Merge changes from topic 'device_version_cleanup' into oc-dev

* changes:
  CameraProvider: Check camera device version
  Camera: Insert default RAW boost if needed
  Camera: Override AE pre-capture trigger cancel
  Camera: Map stream dataspaces
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 2499b1a..b718723 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -44,16 +44,33 @@
     const sp<ICameraDeviceCallback>& callback) :
         camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
         mDevice(device),
+        mDeviceVersion(device->common.version),
+        mIsAELockAvailable(false),
+        mDerivePostRawSensKey(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(numPartialResults);
+    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);
+    }
+
+    // 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();
 }
@@ -130,6 +147,77 @@
     }
 }
 
+/**
+ * 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<buffer_handle_t*>& allBufPtrs,
@@ -612,13 +700,58 @@
                   __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);
     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<void> CameraDeviceSession::configureStreams(
         const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb)  {
     Status status = initStatus();
@@ -634,6 +767,22 @@
         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 (!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();
@@ -654,6 +803,8 @@
             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 +813,9 @@
                     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<android_dataspace_t> (
+                                    requestedConfiguration.streams[i].dataSpace))) {
                 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
                 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
                 return Void();
@@ -837,6 +989,8 @@
 
     hidl_vec<camera3_stream_buffer_t> outHalBufs;
     outHalBufs.resize(numOutputBufs);
+    bool aeCancelTriggerNeeded = false;
+    ::android::hardware::camera::common::V1_0::helper::CameraMetadata settingsOverride;
     {
         Mutex::Autolock _l(mInflightLock);
         if (hasInputBuf) {
@@ -862,12 +1016,24 @@
             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__);
@@ -881,6 +1047,9 @@
             auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
             mInflightBuffers.erase(key);
         }
+        if (aeCancelTriggerNeeded) {
+            mInflightAETriggerOverrides.erase(request.frameNumber);
+        }
         return Status::INTERNAL_ERROR;
     }
 
@@ -908,6 +1077,17 @@
                 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());
+            }
+            if (!mInflightRawBoostPresent.empty()) {
+                ALOGE("%s: trying to close while there are still %zu inflight "
+                        " RAW boost overrides!", __FUNCTION__,
+                        mInflightRawBoostPresent.size());
+            }
+
         }
 
         ATRACE_BEGIN("camera3->close");
@@ -971,6 +1151,61 @@
     result.fmqResultSize = 0;
     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) {
+            if (!resultOverriden) {
+                d->mOverridenResult.clear();
+                d->mOverridenResult.append(hal_result->result);
+                resultOverriden = true;
+            }
+            d->overrideResultForPrecaptureCancelLocked(entry->second,
+                    &d->mOverridenResult);
+            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 =
                 static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
@@ -1046,6 +1281,36 @@
             return;
         }
     }
+
+    if (static_cast<camera3_msg_type_t>(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);
+                }
+
+                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:
+            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 7682165..bbf39e6 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -111,7 +111,18 @@
     // 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;
+    bool mDerivePostRawSensKey;
+    uint32_t mNumPartialResults;
     // Stream ID -> Camera3Stream cache
     std::map<int, Camera3Stream> mStreamMap;
 
@@ -119,6 +130,12 @@
     // (streamID, frameNumber) -> inflight buffer cache
     std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t>  mInflightBuffers;
 
+    // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
+    std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
+    ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult;
+    std::map<uint32_t, bool> mInflightRawBoostPresent;
+    ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
+
     // buffers currently ciculating between HAL and camera service
     // key: bufferId sent via HIDL interface
     // value: imported buffer_handle_t
@@ -258,6 +275,18 @@
 
     void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
 
+    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
diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp
index 9f4d188..791b93c 100644
--- a/camera/provider/2.4/default/CameraProvider.cpp
+++ b/camera/provider/2.4/default/CameraProvider.cpp
@@ -207,6 +207,20 @@
 
     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 @@
     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 d7b0ea6..75971fa 100644
--- a/camera/provider/2.4/default/CameraProvider.h
+++ b/camera/provider/2.4/default/CameraProvider.h
@@ -89,6 +89,7 @@
 
     hidl_vec<VendorTagSection> 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);