blob: 854c34282901f34ce49fa1ff744c106b217a3313 [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#define LOG_TAG "CameraServiceFuzzer"
//#define LOG_NDEBUG 0
#include <CameraService.h>
#include <device3/Camera3StreamInterface.h>
#include <android/hardware/BnCameraServiceListener.h>
#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
#include <android/hardware/ICameraServiceListener.h>
#include <android/hardware/camera2/ICameraDeviceUser.h>
#include <camera/camera2/OutputConfiguration.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <private/android_filesystem_config.h>
#include "fuzzer/FuzzedDataProvider.h"
using namespace android;
using namespace hardware;
using namespace std;
const int32_t kPreviewThreshold = 8;
const int32_t kNumRequestsTested = 8;
const nsecs_t kPreviewTimeout = 5000000000; // .5 [s.]
const nsecs_t kEventTimeout = 10000000000; // 1 [s.]
const size_t kMaxNumLines = USHRT_MAX;
const size_t kMinArgs = 1;
const size_t kMaxArgs = 5;
const int32_t kCamType[] = {hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE,
hardware::ICameraService::CAMERA_TYPE_ALL};
const int kCameraApiVersion[] = {android::CameraService::API_VERSION_1,
android::CameraService::API_VERSION_2};
const uint8_t kSensorPixelModes[] = {ANDROID_SENSOR_PIXEL_MODE_DEFAULT,
ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION};
const int32_t kRequestTemplates[] = {
hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW,
hardware::camera2::ICameraDeviceUser::TEMPLATE_STILL_CAPTURE,
hardware::camera2::ICameraDeviceUser::TEMPLATE_RECORD,
hardware::camera2::ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT,
hardware::camera2::ICameraDeviceUser::TEMPLATE_MANUAL,
hardware::camera2::ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG
};
const int32_t kRotations[] = {
camera3::CAMERA_STREAM_ROTATION_0,
camera3::CAMERA_STREAM_ROTATION_90,
camera3::CAMERA_STREAM_ROTATION_270
};
const int kLayerMetadata[] = {
0x00100000 /*GRALLOC_USAGE_RENDERSCRIPT*/, 0x00000003 /*GRALLOC_USAGE_SW_READ_OFTEN*/,
0x00000100 /*GRALLOC_USAGE_HW_TEXTURE*/, 0x00000800 /*GRALLOC_USAGE_HW_COMPOSER*/,
0x00000200 /*GRALLOC_USAGE_HW_RENDER*/, 0x00010000 /*GRALLOC_USAGE_HW_VIDEO_ENCODER*/};
const int kCameraMsg[] = {0x001 /*CAMERA_MSG_ERROR*/,
0x002 /*CAMERA_MSG_SHUTTER*/,
0x004 /*CAMERA_MSG_FOCUS*/,
0x008 /*CAMERA_MSG_ZOOM*/,
0x010 /*CAMERA_MSG_PREVIEW_FRAME*/,
0x020 /*CAMERA_MSG_VIDEO_FRAME */,
0x040 /*CAMERA_MSG_POSTVIEW_FRAME*/,
0x080 /*CAMERA_MSG_RAW_IMAGE */,
0x100 /*CAMERA_MSG_COMPRESSED_IMAGE*/,
0x200 /*CAMERA_MSG_RAW_IMAGE_NOTIFY*/,
0x400 /*CAMERA_MSG_PREVIEW_METADATA*/,
0x800 /*CAMERA_MSG_FOCUS_MOVE*/};
const int32_t kEventId[] = {ICameraService::EVENT_USER_SWITCHED, ICameraService::EVENT_NONE};
const android::CameraService::sound_kind kSoundKind[] = {
android::CameraService::SOUND_SHUTTER, android::CameraService::SOUND_RECORDING_START,
android::CameraService::SOUND_RECORDING_STOP};
const String16 kShellCmd[] = {String16("set-uid-state"), String16("reset-uid-state"),
String16("get-uid-state"), String16("set-rotate-and-crop"),
String16("get-rotate-and-crop"), String16("help")};
const size_t kNumLayerMetaData = size(kLayerMetadata);
const size_t kNumCameraMsg = size(kCameraMsg);
const size_t kNumSoundKind = size(kSoundKind);
const size_t kNumShellCmd = size(kShellCmd);
class CameraFuzzer : public ::android::hardware::BnCameraClient {
public:
CameraFuzzer(sp<CameraService> cs, std::shared_ptr<FuzzedDataProvider> fp) :
mCameraService(cs), mFuzzedDataProvider(fp) {};
~CameraFuzzer() { deInit(); }
void process();
void deInit();
private:
sp<CameraService> mCameraService = nullptr;
std::shared_ptr<FuzzedDataProvider> mFuzzedDataProvider = nullptr;
sp<SurfaceComposerClient> mComposerClient = nullptr;
int32_t mNumCameras = 0;
size_t mPreviewBufferCount = 0;
bool mAutoFocusMessage = false;
bool mSnapshotNotification = false;
bool mRecordingNotification = false;
mutable Mutex mPreviewLock;
mutable Condition mPreviewCondition;
mutable Mutex mAutoFocusLock;
mutable Condition mAutoFocusCondition;
mutable Mutex mSnapshotLock;
mutable Condition mSnapshotCondition;
mutable Mutex mRecordingLock;
mutable Condition mRecordingCondition;
void getNumCameras();
void getCameraInformation(int32_t cameraId);
void invokeCameraAPIs();
void invokeCameraSound();
void invokeDump();
void invokeShellCommand();
void invokeNotifyCalls();
void invokeTorchAPIs(int32_t cameraId);
// CameraClient interface
void notifyCallback(int32_t msgType, int32_t, int32_t) override;
void dataCallback(int32_t msgType, const sp<IMemory> &, camera_frame_metadata_t *) override;
void dataCallbackTimestamp(nsecs_t, int32_t, const sp<IMemory> &) override{};
void recordingFrameHandleCallbackTimestamp(nsecs_t, native_handle_t *) override{};
void recordingFrameHandleCallbackTimestampBatch(
const std::vector<nsecs_t> &, const std::vector<native_handle_t *> &) override{};
status_t waitForPreviewStart();
status_t waitForEvent(Mutex &mutex, Condition &condition, bool &flag);
};
void CameraFuzzer::notifyCallback(int32_t msgType, int32_t, int32_t) {
if (CAMERA_MSG_FOCUS == msgType) {
Mutex::Autolock l(mAutoFocusLock);
mAutoFocusMessage = true;
mAutoFocusCondition.broadcast();
}
};
void CameraFuzzer::dataCallback(int32_t msgType, const sp<IMemory> & /*data*/,
camera_frame_metadata_t *) {
switch (msgType) {
case CAMERA_MSG_PREVIEW_FRAME: {
Mutex::Autolock l(mPreviewLock);
++mPreviewBufferCount;
mPreviewCondition.broadcast();
mRecordingNotification = true;
mRecordingCondition.broadcast();
break;
}
case CAMERA_MSG_COMPRESSED_IMAGE: {
Mutex::Autolock l(mSnapshotLock);
mSnapshotNotification = true;
mSnapshotCondition.broadcast();
break;
}
default:
break;
}
};
status_t CameraFuzzer::waitForPreviewStart() {
status_t rc = NO_ERROR;
Mutex::Autolock l(mPreviewLock);
mPreviewBufferCount = 0;
while (mPreviewBufferCount < kPreviewThreshold) {
rc = mPreviewCondition.waitRelative(mPreviewLock, kPreviewTimeout);
if (NO_ERROR != rc) {
break;
}
}
return rc;
}
status_t CameraFuzzer::waitForEvent(Mutex &mutex, Condition &condition, bool &flag) {
status_t rc = NO_ERROR;
Mutex::Autolock l(mutex);
flag = false;
while (!flag) {
rc = condition.waitRelative(mutex, kEventTimeout);
if (NO_ERROR != rc) {
break;
}
}
return rc;
}
void CameraFuzzer::deInit() {
if (mComposerClient) {
mComposerClient->dispose();
}
}
void CameraFuzzer::getNumCameras() {
bool shouldPassInvalidCamType = mFuzzedDataProvider->ConsumeBool();
int32_t camType;
if (shouldPassInvalidCamType) {
camType = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
} else {
camType = kCamType[mFuzzedDataProvider->ConsumeBool()];
}
mCameraService->getNumberOfCameras(camType, &mNumCameras);
}
void CameraFuzzer::getCameraInformation(int32_t cameraId) {
std::string cameraIdStr = std::to_string(cameraId);
bool isSupported = false;
mCameraService->supportsCameraApi(
cameraIdStr, kCameraApiVersion[mFuzzedDataProvider->ConsumeBool()], &isSupported);
mCameraService->isHiddenPhysicalCamera(cameraIdStr, &isSupported);
std::string parameters;
mCameraService->getLegacyParameters(cameraId, &parameters);
std::vector<hardware::camera2::utils::ConcurrentCameraIdCombination> concurrentCameraIds;
mCameraService->getConcurrentCameraIds(&concurrentCameraIds);
hardware::camera2::params::VendorTagDescriptorCache cache;
mCameraService->getCameraVendorTagCache(&cache);
CameraInfo cameraInfo;
mCameraService->getCameraInfo(cameraId, /*overrideToPortrait*/false, &cameraInfo);
CameraMetadata metadata;
mCameraService->getCameraCharacteristics(cameraIdStr,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &metadata);
}
void CameraFuzzer::invokeCameraSound() {
mCameraService->increaseSoundRef();
mCameraService->decreaseSoundRef();
bool shouldPassInvalidPlaySound = mFuzzedDataProvider->ConsumeBool();
bool shouldPassInvalidLockSound = mFuzzedDataProvider->ConsumeBool();
android::CameraService::sound_kind playSound, lockSound;
if (shouldPassInvalidPlaySound) {
playSound = static_cast<android::CameraService::sound_kind>(
mFuzzedDataProvider->ConsumeIntegral<size_t>());
} else {
playSound =
kSoundKind[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumSoundKind - 1)];
}
if (shouldPassInvalidLockSound) {
lockSound = static_cast<android::CameraService::sound_kind>(
mFuzzedDataProvider->ConsumeIntegral<size_t>());
} else {
lockSound =
kSoundKind[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumSoundKind - 1)];
}
mCameraService->playSound(playSound);
mCameraService->loadSoundLocked(lockSound);
}
void CameraFuzzer::invokeDump() {
Vector<String16> args;
size_t numberOfLines = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kMaxNumLines);
for (size_t lineIdx = 0; lineIdx < numberOfLines; ++lineIdx) {
args.add(static_cast<String16>(mFuzzedDataProvider->ConsumeRandomLengthString().c_str()));
}
const char *fileName = "logDumpFile";
int fd = memfd_create(fileName, MFD_ALLOW_SEALING);
mCameraService->dump(fd, args);
close(fd);
}
void CameraFuzzer::invokeShellCommand() {
int in = mFuzzedDataProvider->ConsumeIntegral<int>();
int out = mFuzzedDataProvider->ConsumeIntegral<int>();
int err = mFuzzedDataProvider->ConsumeIntegral<int>();
Vector<String16> args;
size_t numArgs = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinArgs, kMaxArgs);
for (size_t argsIdx = 0; argsIdx < numArgs; ++argsIdx) {
bool shouldPassInvalidCommand = mFuzzedDataProvider->ConsumeBool();
if (shouldPassInvalidCommand) {
args.add(
static_cast<String16>(mFuzzedDataProvider->ConsumeRandomLengthString().c_str()));
} else {
args.add(kShellCmd[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
0, kNumShellCmd - 1)]);
}
}
mCameraService->shellCommand(in, out, err, args);
}
void CameraFuzzer::invokeNotifyCalls() {
mCameraService->notifyMonitoredUids();
int64_t newState = mFuzzedDataProvider->ConsumeIntegral<int64_t>();
mCameraService->notifyDeviceStateChange(newState);
std::vector<int32_t> args;
size_t numArgs = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinArgs, kMaxArgs);
for (size_t argsIdx = 0; argsIdx < numArgs; ++argsIdx) {
args.push_back(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
}
bool shouldPassInvalidEvent = mFuzzedDataProvider->ConsumeBool();
int32_t eventId;
if (shouldPassInvalidEvent) {
eventId = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
} else {
eventId = kEventId[mFuzzedDataProvider->ConsumeBool()];
}
mCameraService->notifySystemEvent(eventId, args);
}
void CameraFuzzer::invokeTorchAPIs(int32_t cameraId) {
std::string cameraIdStr = std::to_string(cameraId);
sp<IBinder> binder = new BBinder;
mCameraService->setTorchMode(cameraIdStr, true, binder);
ALOGV("Turned torch on.");
int32_t torchStrength = rand() % 5 + 1;
ALOGV("Changing torch strength level to %d", torchStrength);
mCameraService->turnOnTorchWithStrengthLevel(cameraIdStr, torchStrength, binder);
mCameraService->setTorchMode(cameraIdStr, false, binder);
ALOGV("Turned torch off.");
}
void CameraFuzzer::invokeCameraAPIs() {
/** In order to avoid the timeout issue caused due to multiple iteration of loops, the 'for'
* loops are removed and the 'cameraId', 'pictureSize' and 'videoSize' are derived using the
* FuzzedDataProvider from the available cameras and vectors of 'pictureSizes' and 'videoSizes'
*/
int32_t cameraId = mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(0, mNumCameras - 1);
getCameraInformation(cameraId);
invokeTorchAPIs(cameraId);
::android::binder::Status rc;
sp<ICamera> cameraDevice;
rc = mCameraService->connect(this, cameraId, std::string(),
android::CameraService::USE_CALLING_UID,
android::CameraService::USE_CALLING_PID,
/*targetSdkVersion*/ __ANDROID_API_FUTURE__,
/*overrideToPortrait*/true, /*forceSlowJpegMode*/false,
&cameraDevice);
if (!rc.isOk()) {
// camera not connected
return;
}
if (cameraDevice) {
sp<Surface> previewSurface;
sp<SurfaceControl> surfaceControl;
CameraParameters params(cameraDevice->getParameters());
String8 focusModes(params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
bool isAFSupported = false;
const char* focusMode = nullptr;
if (focusModes.contains(CameraParameters::FOCUS_MODE_AUTO)) {
isAFSupported = true;
} else if (focusModes.contains(CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)) {
isAFSupported = true;
focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
} else if (focusModes.contains(CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO)) {
isAFSupported = true;
focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
} else if (focusModes.contains(CameraParameters::FOCUS_MODE_MACRO)) {
isAFSupported = true;
focusMode = CameraParameters::FOCUS_MODE_MACRO;
}
if (nullptr != focusMode) {
params.set(CameraParameters::KEY_FOCUS_MODE, focusMode);
cameraDevice->setParameters(params.flatten());
}
int previewWidth, previewHeight;
params.getPreviewSize(&previewWidth, &previewHeight);
mComposerClient = new SurfaceComposerClient;
mComposerClient->initCheck();
bool shouldPassInvalidLayerMetaData = mFuzzedDataProvider->ConsumeBool();
int layerMetaData;
if (shouldPassInvalidLayerMetaData) {
layerMetaData = mFuzzedDataProvider->ConsumeIntegral<int>();
} else {
layerMetaData = kLayerMetadata[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
0, kNumLayerMetaData - 1)];
}
surfaceControl = mComposerClient->createSurface(
String8("Test Surface"), previewWidth, previewHeight,
CameraParameters::previewFormatToEnum(params.getPreviewFormat()), layerMetaData);
if (surfaceControl.get()) {
SurfaceComposerClient::Transaction{}
.setLayer(surfaceControl, 0x7fffffff)
.show(surfaceControl)
.apply();
previewSurface = surfaceControl->getSurface();
if (previewSurface.get()) {
cameraDevice->setPreviewTarget(previewSurface->getIGraphicBufferProducer());
}
}
cameraDevice->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER);
Vector<Size> pictureSizes;
params.getSupportedPictureSizes(pictureSizes);
if (pictureSizes.size()) {
Size pictureSize = pictureSizes[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
0, pictureSizes.size() - 1)];
params.setPictureSize(pictureSize.width, pictureSize.height);
cameraDevice->setParameters(params.flatten());
cameraDevice->startPreview();
waitForPreviewStart();
cameraDevice->autoFocus();
waitForEvent(mAutoFocusLock, mAutoFocusCondition, mAutoFocusMessage);
bool shouldPassInvalidCameraMsg = mFuzzedDataProvider->ConsumeBool();
int msgType;
if (shouldPassInvalidCameraMsg) {
msgType = mFuzzedDataProvider->ConsumeIntegral<int>();
} else {
msgType = kCameraMsg[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
0, kNumCameraMsg - 1)];
}
cameraDevice->takePicture(msgType);
waitForEvent(mSnapshotLock, mSnapshotCondition, mSnapshotNotification);
cameraDevice->stopPreview();
}
Vector<Size> videoSizes;
params.getSupportedVideoSizes(videoSizes);
if (videoSizes.size()) {
Size videoSize = videoSizes[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
0, videoSizes.size() - 1)];
params.setVideoSize(videoSize.width, videoSize.height);
cameraDevice->setParameters(params.flatten());
cameraDevice->startPreview();
waitForPreviewStart();
cameraDevice->setVideoBufferMode(
android::hardware::BnCamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE);
sp<SurfaceControl> surfaceControlVideo = mComposerClient->createSurface(
String8("Test Surface Video"), previewWidth, previewHeight,
CameraParameters::previewFormatToEnum(params.getPreviewFormat()),
layerMetaData);
if (surfaceControlVideo.get()) {
SurfaceComposerClient::Transaction{}
.setLayer(surfaceControlVideo, 0x7fffffff)
.show(surfaceControlVideo)
.apply();
sp<Surface> previewSurfaceVideo = surfaceControlVideo->getSurface();
if (previewSurfaceVideo.get()) {
cameraDevice->setVideoTarget(previewSurfaceVideo->getIGraphicBufferProducer());
}
}
cameraDevice->stopPreview();
cameraDevice->startRecording();
waitForEvent(mRecordingLock, mRecordingCondition, mRecordingNotification);
cameraDevice->stopRecording();
}
cameraDevice->disconnect();
}
}
void CameraFuzzer::process() {
getNumCameras();
invokeCameraSound();
if (mNumCameras > 0) {
invokeCameraAPIs();
}
invokeDump();
invokeShellCommand();
invokeNotifyCalls();
}
class TestCameraServiceListener : public hardware::BnCameraServiceListener {
public:
virtual ~TestCameraServiceListener() {};
virtual binder::Status onStatusChanged(int32_t, const std::string&) {
return binder::Status::ok();
};
virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/) {
// No op
return binder::Status::ok();
};
virtual binder::Status onTorchStatusChanged(int32_t /*status*/,
const std::string& /*cameraId*/) {
return binder::Status::ok();
};
virtual binder::Status onCameraAccessPrioritiesChanged() {
// No op
return binder::Status::ok();
}
virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
const std::string& /*clientPackageName*/) {
// No op
return binder::Status::ok();
}
virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) {
// No op
return binder::Status::ok();
}
virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
int32_t /*torchStrength*/) {
// No op
return binder::Status::ok();
}
};
class TestCameraDeviceCallbacks : public hardware::camera2::BnCameraDeviceCallbacks {
public:
TestCameraDeviceCallbacks() {}
virtual ~TestCameraDeviceCallbacks() {}
virtual binder::Status onDeviceError(int /*errorCode*/,
const CaptureResultExtras& /*resultExtras*/) {
return binder::Status::ok();
}
virtual binder::Status onDeviceIdle() {
return binder::Status::ok();
}
virtual binder::Status onCaptureStarted(const CaptureResultExtras& /*resultExtras*/,
int64_t /*timestamp*/) {
return binder::Status::ok();
}
virtual binder::Status onResultReceived(const CameraMetadata& /*metadata*/,
const CaptureResultExtras& /*resultExtras*/,
const std::vector<PhysicalCaptureResultInfo>& /*physicalResultInfos*/) {
return binder::Status::ok();
}
virtual binder::Status onPrepared(int /*streamId*/) {
return binder::Status::ok();
}
virtual binder::Status onRepeatingRequestError(
int64_t /*lastFrameNumber*/, int32_t /*stoppedSequenceId*/) {
return binder::Status::ok();
}
virtual binder::Status onRequestQueueEmpty() {
return binder::Status::ok();
}
};
class Camera2Fuzzer {
public:
Camera2Fuzzer(sp<CameraService> cs, std::shared_ptr<FuzzedDataProvider> fp) :
mCameraService(cs), mFuzzedDataProvider(fp) { };
~Camera2Fuzzer() {}
void process();
private:
sp<CameraService> mCameraService = nullptr;
std::shared_ptr<FuzzedDataProvider> mFuzzedDataProvider = nullptr;
};
void Camera2Fuzzer::process() {
sp<TestCameraServiceListener> listener = new TestCameraServiceListener();
std::vector<hardware::CameraStatus> statuses;
mCameraService->addListenerTest(listener, &statuses);
for (auto s : statuses) {
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
mCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/true,
&device);
if (device == nullptr) {
continue;
}
device->beginConfigure();
sp<IGraphicBufferProducer> gbProducer;
sp<IGraphicBufferConsumer> gbConsumer;
BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
sp<BufferItemConsumer> opaqueConsumer = new BufferItemConsumer(gbConsumer,
GRALLOC_USAGE_SW_READ_NEVER, /*maxImages*/8, /*controlledByApp*/true);
opaqueConsumer->setName(String8("Roger"));
// Set to VGA dimension for default, as that is guaranteed to be present
gbConsumer->setDefaultBufferSize(640, 480);
gbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
std::string noPhysicalId;
size_t rotations = sizeof(kRotations) / sizeof(int32_t) - 1;
OutputConfiguration output(gbProducer,
kRotations[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, rotations)],
noPhysicalId);
int streamId;
device->createStream(output, &streamId);
CameraMetadata sessionParams;
std::vector<int> offlineStreamIds;
device->endConfigure(/*isConstrainedHighSpeed*/ mFuzzedDataProvider->ConsumeBool(),
sessionParams, ns2ms(systemTime()), &offlineStreamIds);
CameraMetadata requestTemplate;
size_t requestTemplatesSize = sizeof(kRequestTemplates) /sizeof(int32_t) - 1;
device->createDefaultRequest(kRequestTemplates[
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, requestTemplatesSize)],
/*out*/&requestTemplate);
hardware::camera2::CaptureRequest request;
request.mSurfaceList.add(surface);
request.mIsReprocess = false;
hardware::camera2::utils::SubmitInfo info;
for (int i = 0; i < kNumRequestsTested; i++) {
uint8_t sensorPixelMode =
kSensorPixelModes[mFuzzedDataProvider->ConsumeBool() ? 1 : 0];
requestTemplate.update(ANDROID_SENSOR_PIXEL_MODE, &sensorPixelMode, 1);
request.mPhysicalCameraSettings.clear();
request.mPhysicalCameraSettings.push_back({s.cameraId, requestTemplate});
device->submitRequest(request, /*streaming*/false, /*out*/&info);
ALOGV("%s : camera id %s submit request id %d",__FUNCTION__, s.cameraId.c_str(),
info.mRequestId);
}
device->disconnect();
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 1) {
return 0;
}
setuid(AID_CAMERASERVER);
std::shared_ptr<FuzzedDataProvider> fp = std::make_shared<FuzzedDataProvider>(data, size);
sp<CameraService> cs = new CameraService();
cs->clearCachedVariables();
sp<CameraFuzzer> camerafuzzer = new CameraFuzzer(cs, fp);
if (!camerafuzzer) {
return 0;
}
camerafuzzer->process();
Camera2Fuzzer camera2fuzzer(cs, fp);
camera2fuzzer.process();
return 0;
}