From 7d52a6fd255938f4c7fdf1dab85369b97760df2a Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Fri, 7 Apr 2017 09:53:48 +0100 Subject: [PATCH 1/4] Camera: Map stream dataspaces Older CameraHal versions are still using deprecated dataspace definitions. Mapping between these dataspaces is needed to avoid discrepancies. Bug: 34392075 Test: Manual using camera application Change-Id: I811dec879494445736b4e3731b2d516e396a9058 --- .../3.2/default/CameraDeviceSession.cpp | 38 ++++++++++++++++++- .../device/3.2/default/CameraDeviceSession.h | 4 ++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp index 2499b1abea..e94bc62be4 100644 --- a/camera/device/3.2/default/CameraDeviceSession.cpp +++ b/camera/device/3.2/default/CameraDeviceSession.cpp @@ -44,6 +44,7 @@ CameraDeviceSession::CameraDeviceSession( const sp& callback) : camera3_callback_ops({&sProcessCaptureResult, &sNotify}), mDevice(device), + mDeviceVersion(device->common.version), mResultBatcher(callback) { mDeviceInfo = deviceInfo; @@ -619,6 +620,36 @@ Return CameraDeviceSession::constructDefaultRequestSettings( return Void(); } +/** + * Map Android N dataspace definitions back to Android M definitions, for + * use with HALv3.3 or older. + * + * Only map where correspondences exist, and otherwise preserve the value. + */ +android_dataspace CameraDeviceSession::mapToLegacyDataspace( + android_dataspace dataSpace) const { + if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_3) { + switch (dataSpace) { + case HAL_DATASPACE_V0_SRGB_LINEAR: + return HAL_DATASPACE_SRGB_LINEAR; + case HAL_DATASPACE_V0_SRGB: + return HAL_DATASPACE_SRGB; + case HAL_DATASPACE_V0_JFIF: + return HAL_DATASPACE_JFIF; + case HAL_DATASPACE_V0_BT601_625: + return HAL_DATASPACE_BT601_625; + case HAL_DATASPACE_V0_BT601_525: + return HAL_DATASPACE_BT601_525; + case HAL_DATASPACE_V0_BT709: + return HAL_DATASPACE_BT709; + default: + return dataSpace; + } + } + + return dataSpace; +} + Return CameraDeviceSession::configureStreams( const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) { Status status = initStatus(); @@ -654,6 +685,8 @@ Return CameraDeviceSession::configureStreams( Camera3Stream stream; convertFromHidl(requestedConfiguration.streams[i], &stream); mStreamMap[id] = stream; + mStreamMap[id].data_space = mapToLegacyDataspace( + mStreamMap[id].data_space); mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{}); } else { // width/height/format must not change, but usage/rotation might need to change @@ -662,8 +695,9 @@ Return CameraDeviceSession::configureStreams( mStreamMap[id].width != requestedConfiguration.streams[i].width || mStreamMap[id].height != requestedConfiguration.streams[i].height || mStreamMap[id].format != (int) requestedConfiguration.streams[i].format || - mStreamMap[id].data_space != (android_dataspace_t) - requestedConfiguration.streams[i].dataSpace) { + mStreamMap[id].data_space != + mapToLegacyDataspace( static_cast ( + requestedConfiguration.streams[i].dataSpace))) { ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id); _hidl_cb(Status::INTERNAL_ERROR, outStreams); return Void(); diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h index 7682165c15..51e978ebd6 100644 --- a/camera/device/3.2/default/CameraDeviceSession.h +++ b/camera/device/3.2/default/CameraDeviceSession.h @@ -112,6 +112,7 @@ private: bool mDisconnected = false; camera3_device_t* mDevice; + uint32_t mDeviceVersion; // Stream ID -> Camera3Stream cache std::map mStreamMap; @@ -258,6 +259,9 @@ private: void updateBufferCaches(const hidl_vec& cachesToRemove); + android_dataspace mapToLegacyDataspace( + android_dataspace dataSpace) const; + Status processOneCaptureRequest(const CaptureRequest& request); /** * Static callback forwarding methods from HAL to instance From cf5813702a0c282889cc99ac40a34754f13bcb39 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Fri, 7 Apr 2017 13:53:10 +0100 Subject: [PATCH 2/4] Camera: Override AE pre-capture trigger cancel CameraHal version 3.2 doesn't support cancel AE pre-capture trigger. Camera request metadata that contains this value needs to be overriden respectively. The corresponding results also require the same kind of modification. Bug: 34392075 Test: runtest -x cts/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java -m testAePrecaptureTriggerCancelJpegCapture Change-Id: If8bcf7e97ca8691cf890d5d6306d49dc3ddd087a --- .../3.2/default/CameraDeviceSession.cpp | 154 +++++++++++++++++- .../device/3.2/default/CameraDeviceSession.h | 22 +++ 2 files changed, 173 insertions(+), 3 deletions(-) diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp index e94bc62be4..e9f78ff399 100644 --- a/camera/device/3.2/default/CameraDeviceSession.cpp +++ b/camera/device/3.2/default/CameraDeviceSession.cpp @@ -45,16 +45,24 @@ CameraDeviceSession::CameraDeviceSession( camera3_callback_ops({&sProcessCaptureResult, &sNotify}), mDevice(device), mDeviceVersion(device->common.version), + mIsAELockAvailable(false), + mNumPartialResults(1), mResultBatcher(callback) { mDeviceInfo = deviceInfo; - uint32_t numPartialResults = 1; camera_metadata_entry partialResultsCount = mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT); if (partialResultsCount.count > 0) { - numPartialResults = partialResultsCount.data.i32[0]; + mNumPartialResults = partialResultsCount.data.i32[0]; + } + mResultBatcher.setNumPartialResults(mNumPartialResults); + + camera_metadata_entry aeLockAvailableEntry = mDeviceInfo.find( + ANDROID_CONTROL_AE_LOCK_AVAILABLE); + if (aeLockAvailableEntry.count > 0) { + mIsAELockAvailable = (aeLockAvailableEntry.data.u8[0] == + ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE); } - mResultBatcher.setNumPartialResults(numPartialResults); mInitFail = initialize(); } @@ -131,6 +139,77 @@ void CameraDeviceSession::dumpState(const native_handle_t* fd) { } } +/** + * For devices <= CAMERA_DEVICE_API_VERSION_3_2, AE_PRECAPTURE_TRIGGER_CANCEL is not supported so + * we need to override AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE and AE_LOCK_OFF + * to AE_LOCK_ON to start cancelling AE precapture. If AE lock is not available, it still overrides + * AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE but doesn't add AE_LOCK_ON to the + * request. + */ +bool CameraDeviceSession::handleAePrecaptureCancelRequestLocked( + const camera3_capture_request_t &halRequest, + ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/, + AETriggerCancelOverride *override /*out*/) { + if ((mDeviceVersion > CAMERA_DEVICE_API_VERSION_3_2) || + (nullptr == halRequest.settings) || (nullptr == settings) || + (0 == get_camera_metadata_entry_count(halRequest.settings))) { + return false; + } + + settings->clear(); + settings->append(halRequest.settings); + camera_metadata_entry_t aePrecaptureTrigger = + settings->find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER); + if (aePrecaptureTrigger.count > 0 && + aePrecaptureTrigger.data.u8[0] == + ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) { + // Always override CANCEL to IDLE + uint8_t aePrecaptureTrigger = + ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + settings->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, + &aePrecaptureTrigger, 1); + *override = { false, ANDROID_CONTROL_AE_LOCK_OFF, + true, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL }; + + if (mIsAELockAvailable == true) { + camera_metadata_entry_t aeLock = settings->find( + ANDROID_CONTROL_AE_LOCK); + if (aeLock.count == 0 || aeLock.data.u8[0] == + ANDROID_CONTROL_AE_LOCK_OFF) { + uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_ON; + settings->update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1); + override->applyAeLock = true; + override->aeLock = ANDROID_CONTROL_AE_LOCK_OFF; + } + } + + return true; + } + + return false; +} + +/** + * Override result metadata for cancelling AE precapture trigger applied in + * handleAePrecaptureCancelRequestLocked(). + */ +void CameraDeviceSession::overrideResultForPrecaptureCancelLocked( + const AETriggerCancelOverride &aeTriggerCancelOverride, + ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/) { + if (aeTriggerCancelOverride.applyAeLock) { + // Only devices <= v3.2 should have this override + assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2); + settings->update(ANDROID_CONTROL_AE_LOCK, &aeTriggerCancelOverride.aeLock, 1); + } + + if (aeTriggerCancelOverride.applyAePrecaptureTrigger) { + // Only devices <= v3.2 should have this override + assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2); + settings->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, + &aeTriggerCancelOverride.aePrecaptureTrigger, 1); + } +} + Status CameraDeviceSession::importRequest( const CaptureRequest& request, hidl_vec& allBufPtrs, @@ -665,6 +744,14 @@ Return CameraDeviceSession::configureStreams( return Void(); } + if (!mInflightAETriggerOverrides.empty()) { + ALOGE("%s: trying to configureStreams while there are still %zu inflight" + " trigger overrides!", __FUNCTION__, + mInflightAETriggerOverrides.size()); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + if (status != Status::OK) { _hidl_cb(status, outStreams); return Void(); @@ -871,6 +958,8 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque hidl_vec outHalBufs; outHalBufs.resize(numOutputBufs); + bool aeCancelTriggerNeeded = false; + ::android::hardware::camera::common::V1_0::helper::CameraMetadata settingsOverride; { Mutex::Autolock _l(mInflightLock); if (hasInputBuf) { @@ -896,12 +985,24 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque outHalBufs[i] = bufCache; } halRequest.output_buffers = outHalBufs.data(); + + AETriggerCancelOverride triggerOverride; + aeCancelTriggerNeeded = handleAePrecaptureCancelRequestLocked( + halRequest, &settingsOverride /*out*/, &triggerOverride/*out*/); + if (aeCancelTriggerNeeded) { + mInflightAETriggerOverrides[halRequest.frame_number] = + triggerOverride; + halRequest.settings = settingsOverride.getAndLock(); + } } ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber); ATRACE_BEGIN("camera3->process_capture_request"); status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest); ATRACE_END(); + if (aeCancelTriggerNeeded) { + settingsOverride.unlock(halRequest.settings); + } if (ret != OK) { Mutex::Autolock _l(mInflightLock); ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__); @@ -915,6 +1016,9 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber); mInflightBuffers.erase(key); } + if (aeCancelTriggerNeeded) { + mInflightAETriggerOverrides.erase(request.frameNumber); + } return Status::INTERNAL_ERROR; } @@ -942,6 +1046,12 @@ Return CameraDeviceSession::close() { ALOGE("%s: trying to close while there are still %zu inflight buffers!", __FUNCTION__, mInflightBuffers.size()); } + if (!mInflightAETriggerOverrides.empty()) { + ALOGE("%s: trying to close while there are still %zu inflight " + "trigger overrides!", __FUNCTION__, + mInflightAETriggerOverrides.size()); + } + } ATRACE_BEGIN("camera3->close"); @@ -1005,6 +1115,22 @@ void CameraDeviceSession::sProcessCaptureResult( result.fmqResultSize = 0; result.partialResult = hal_result->partial_result; convertToHidl(hal_result->result, &result.result); + if (nullptr != hal_result->result) { + Mutex::Autolock _l(d->mInflightLock); + auto entry = d->mInflightAETriggerOverrides.find(frameNumber); + if (d->mInflightAETriggerOverrides.end() != entry) { + d->mOverridenResult.clear(); + d->mOverridenResult.append(hal_result->result); + d->overrideResultForPrecaptureCancelLocked(entry->second, + &d->mOverridenResult); + const camera_metadata_t *metaBuffer = d->mOverridenResult.getAndLock(); + convertToHidl(metaBuffer, &result.result); + d->mOverridenResult.unlock(metaBuffer); + if (hal_result->partial_result == d->mNumPartialResults) { + d->mInflightAETriggerOverrides.erase(frameNumber); + } + } + } if (hasInputBuf) { result.inputBuffer.streamId = static_cast(hal_result->input_buffer->stream)->mId; @@ -1080,6 +1206,28 @@ void CameraDeviceSession::sNotify( return; } } + + if (static_cast(hidlMsg.type) == CAMERA3_MSG_ERROR) { + switch (hidlMsg.msg.error.errorCode) { + case ErrorCode::ERROR_DEVICE: + case ErrorCode::ERROR_REQUEST: + case ErrorCode::ERROR_RESULT: { + Mutex::Autolock _l(d->mInflightLock); + auto entry = d->mInflightAETriggerOverrides.find( + hidlMsg.msg.error.frameNumber); + if (d->mInflightAETriggerOverrides.end() != entry) { + d->mInflightAETriggerOverrides.erase( + hidlMsg.msg.error.frameNumber); + } + } + break; + case ErrorCode::ERROR_BUFFER: + default: + break; + } + + } + d->mResultBatcher.notify(hidlMsg); } diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h index 51e978ebd6..c08ed90011 100644 --- a/camera/device/3.2/default/CameraDeviceSession.h +++ b/camera/device/3.2/default/CameraDeviceSession.h @@ -111,8 +111,17 @@ private: // Set by CameraDevice (when external camera is disconnected) bool mDisconnected = false; + struct AETriggerCancelOverride { + bool applyAeLock; + uint8_t aeLock; + bool applyAePrecaptureTrigger; + uint8_t aePrecaptureTrigger; + }; + camera3_device_t* mDevice; uint32_t mDeviceVersion; + bool mIsAELockAvailable; + uint32_t mNumPartialResults; // Stream ID -> Camera3Stream cache std::map mStreamMap; @@ -120,6 +129,10 @@ private: // (streamID, frameNumber) -> inflight buffer cache std::map, camera3_stream_buffer_t> mInflightBuffers; + // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides + std::map mInflightAETriggerOverrides; + ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult; + // buffers currently ciculating between HAL and camera service // key: bufferId sent via HIDL interface // value: imported buffer_handle_t @@ -262,6 +275,15 @@ private: android_dataspace mapToLegacyDataspace( android_dataspace dataSpace) const; + bool handleAePrecaptureCancelRequestLocked( + const camera3_capture_request_t &halRequest, + android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/, + AETriggerCancelOverride *override /*out*/); + + void overrideResultForPrecaptureCancelLocked( + const AETriggerCancelOverride &aeTriggerCancelOverride, + ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/); + Status processOneCaptureRequest(const CaptureRequest& request); /** * Static callback forwarding methods from HAL to instance From a13ac99f3472e015c24b5a2999a9b7fda1f56a45 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 10 Apr 2017 12:02:17 +0100 Subject: [PATCH 3/4] Camera: Insert default RAW boost if needed RAW boost key inside result and request metadata could be absent depending on CameraHal. In case RAW boost range is supported, the RAW boost value must always be present. Bug: 34392075 Test: runtest -x cts/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java Change-Id: I4c27b3fe5228ff604e3f2796abc670be5c17da67 --- .../3.2/default/CameraDeviceSession.cpp | 95 +++++++++++++++++-- .../device/3.2/default/CameraDeviceSession.h | 3 + 2 files changed, 92 insertions(+), 6 deletions(-) diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp index e9f78ff399..b7187232f8 100644 --- a/camera/device/3.2/default/CameraDeviceSession.cpp +++ b/camera/device/3.2/default/CameraDeviceSession.cpp @@ -46,6 +46,7 @@ CameraDeviceSession::CameraDeviceSession( mDevice(device), mDeviceVersion(device->common.version), mIsAELockAvailable(false), + mDerivePostRawSensKey(false), mNumPartialResults(1), mResultBatcher(callback) { @@ -64,6 +65,13 @@ CameraDeviceSession::CameraDeviceSession( ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE); } + // Determine whether we need to derive sensitivity boost values for older devices. + // If post-RAW sensitivity boost range is listed, so should post-raw sensitivity control + // be listed (as the default value 100) + if (mDeviceInfo.exists(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE)) { + mDerivePostRawSensKey = true; + } + mInitFail = initialize(); } @@ -692,7 +700,22 @@ Return CameraDeviceSession::constructDefaultRequestSettings( __FUNCTION__, type); status = Status::ILLEGAL_ARGUMENT; } else { - convertToHidl(rawRequest, &outMetadata); + mOverridenRequest.clear(); + mOverridenRequest.append(rawRequest); + // Derive some new keys for backward compatibility + if (mDerivePostRawSensKey && !mOverridenRequest.exists( + ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) { + int32_t defaultBoost[1] = {100}; + mOverridenRequest.update( + ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, + defaultBoost, 1); + const camera_metadata_t *metaBuffer = + mOverridenRequest.getAndLock(); + convertToHidl(metaBuffer, &outMetadata); + mOverridenRequest.unlock(metaBuffer); + } else { + convertToHidl(rawRequest, &outMetadata); + } } } _hidl_cb(status, outMetadata); @@ -752,6 +775,14 @@ Return CameraDeviceSession::configureStreams( return Void(); } + if (!mInflightRawBoostPresent.empty()) { + ALOGE("%s: trying to configureStreams while there are still %zu inflight" + " boost overrides!", __FUNCTION__, + mInflightRawBoostPresent.size()); + _hidl_cb(Status::INTERNAL_ERROR, outStreams); + return Void(); + } + if (status != Status::OK) { _hidl_cb(status, outStreams); return Void(); @@ -1051,6 +1082,11 @@ Return CameraDeviceSession::close() { "trigger overrides!", __FUNCTION__, mInflightAETriggerOverrides.size()); } + if (!mInflightRawBoostPresent.empty()) { + ALOGE("%s: trying to close while there are still %zu inflight " + " RAW boost overrides!", __FUNCTION__, + mInflightRawBoostPresent.size()); + } } @@ -1116,20 +1152,59 @@ void CameraDeviceSession::sProcessCaptureResult( result.partialResult = hal_result->partial_result; convertToHidl(hal_result->result, &result.result); if (nullptr != hal_result->result) { + bool resultOverriden = false; Mutex::Autolock _l(d->mInflightLock); + + // Derive some new keys for backward compatibility + if (d->mDerivePostRawSensKey) { + camera_metadata_ro_entry entry; + if (find_camera_metadata_ro_entry(hal_result->result, + ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &entry) == 0) { + d->mInflightRawBoostPresent[frameNumber] = true; + } else { + auto entry = d->mInflightRawBoostPresent.find(frameNumber); + if (d->mInflightRawBoostPresent.end() == entry) { + d->mInflightRawBoostPresent[frameNumber] = false; + } + } + + if ((hal_result->partial_result == d->mNumPartialResults)) { + if (!d->mInflightRawBoostPresent[frameNumber]) { + if (!resultOverriden) { + d->mOverridenResult.clear(); + d->mOverridenResult.append(hal_result->result); + resultOverriden = true; + } + int32_t defaultBoost[1] = {100}; + d->mOverridenResult.update( + ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, + defaultBoost, 1); + } + + d->mInflightRawBoostPresent.erase(frameNumber); + } + } + auto entry = d->mInflightAETriggerOverrides.find(frameNumber); if (d->mInflightAETriggerOverrides.end() != entry) { - d->mOverridenResult.clear(); - d->mOverridenResult.append(hal_result->result); + if (!resultOverriden) { + d->mOverridenResult.clear(); + d->mOverridenResult.append(hal_result->result); + resultOverriden = true; + } d->overrideResultForPrecaptureCancelLocked(entry->second, &d->mOverridenResult); - const camera_metadata_t *metaBuffer = d->mOverridenResult.getAndLock(); - convertToHidl(metaBuffer, &result.result); - d->mOverridenResult.unlock(metaBuffer); if (hal_result->partial_result == d->mNumPartialResults) { d->mInflightAETriggerOverrides.erase(frameNumber); } } + + if (resultOverriden) { + const camera_metadata_t *metaBuffer = + d->mOverridenResult.getAndLock(); + convertToHidl(metaBuffer, &result.result); + d->mOverridenResult.unlock(metaBuffer); + } } if (hasInputBuf) { result.inputBuffer.streamId = @@ -1219,6 +1294,14 @@ void CameraDeviceSession::sNotify( d->mInflightAETriggerOverrides.erase( hidlMsg.msg.error.frameNumber); } + + auto boostEntry = d->mInflightRawBoostPresent.find( + hidlMsg.msg.error.frameNumber); + if (d->mInflightRawBoostPresent.end() != boostEntry) { + d->mInflightRawBoostPresent.erase( + hidlMsg.msg.error.frameNumber); + } + } break; case ErrorCode::ERROR_BUFFER: diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h index c08ed90011..bbf39e60e5 100644 --- a/camera/device/3.2/default/CameraDeviceSession.h +++ b/camera/device/3.2/default/CameraDeviceSession.h @@ -121,6 +121,7 @@ private: camera3_device_t* mDevice; uint32_t mDeviceVersion; bool mIsAELockAvailable; + bool mDerivePostRawSensKey; uint32_t mNumPartialResults; // Stream ID -> Camera3Stream cache std::map mStreamMap; @@ -132,6 +133,8 @@ private: // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides std::map mInflightAETriggerOverrides; ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult; + std::map mInflightRawBoostPresent; + ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest; // buffers currently ciculating between HAL and camera service // key: bufferId sent via HIDL interface From c9ded518486e02ced10ebdf2491d11fc3680433d Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 10 Apr 2017 16:12:55 +0100 Subject: [PATCH 4/4] CameraProvider: Check camera device version Make sure we are working with supported devices. Bug: 34392075 Test: Manual using application Change-Id: I834612303f3e02e79924efbdcc25cff890defefb --- .../provider/2.4/default/CameraProvider.cpp | 48 +++++++++++++++++++ camera/provider/2.4/default/CameraProvider.h | 1 + 2 files changed, 49 insertions(+) diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp index 9f4d18838c..791b93c759 100644 --- a/camera/provider/2.4/default/CameraProvider.cpp +++ b/camera/provider/2.4/default/CameraProvider.cpp @@ -207,6 +207,20 @@ bool CameraProvider::initialize() { mNumberOfLegacyCameras = mModule->getNumberOfCameras(); for (int i = 0; i < mNumberOfLegacyCameras; i++) { + struct camera_info info; + auto rc = mModule->getCameraInfo(i, &info); + if (rc != NO_ERROR) { + ALOGE("%s: Camera info query failed!", __func__); + mModule.clear(); + return true; + } + + if (checkCameraVersion(i, info) != OK) { + ALOGE("%s: Camera version check failed!", __func__); + mModule.clear(); + return true; + } + char cameraId[kMaxCameraIdLen]; snprintf(cameraId, sizeof(cameraId), "%d", i); std::string cameraIdStr(cameraId); @@ -242,6 +256,40 @@ bool CameraProvider::initialize() { return false; // mInitFailed } +/** + * Check that the device HAL version is still in supported. + */ +int CameraProvider::checkCameraVersion(int id, camera_info info) { + if (mModule == nullptr) { + return NO_INIT; + } + + // device_version undefined in CAMERA_MODULE_API_VERSION_1_0, + // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible + if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) { + // Verify the device version is in the supported range + switch (info.device_version) { + case CAMERA_DEVICE_API_VERSION_1_0: + case CAMERA_DEVICE_API_VERSION_3_2: + case CAMERA_DEVICE_API_VERSION_3_3: + case CAMERA_DEVICE_API_VERSION_3_4: + // in support + break; + case CAMERA_DEVICE_API_VERSION_2_0: + case CAMERA_DEVICE_API_VERSION_2_1: + case CAMERA_DEVICE_API_VERSION_3_0: + case CAMERA_DEVICE_API_VERSION_3_1: + // no longer supported + default: + ALOGE("%s: Device %d has HAL version %x, which is not supported", + __FUNCTION__, id, info.device_version); + return NO_INIT; + } + } + + return OK; +} + bool CameraProvider::setUpVendorTags() { ATRACE_CALL(); vendor_tag_ops_t vOps = vendor_tag_ops_t(); diff --git a/camera/provider/2.4/default/CameraProvider.h b/camera/provider/2.4/default/CameraProvider.h index d7b0ea6dd9..75971fa3a0 100644 --- a/camera/provider/2.4/default/CameraProvider.h +++ b/camera/provider/2.4/default/CameraProvider.h @@ -89,6 +89,7 @@ private: hidl_vec mVendorTagSections; bool setUpVendorTags(); + int checkCameraVersion(int id, camera_info info); // extract legacy camera ID/device version from a HIDL device name static std::string getLegacyCameraId(const hidl_string& deviceName);