Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3176e6eb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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
parents 8c5d56ec c9ded518
Loading
Loading
Loading
Loading
+271 −6
Original line number Diff line number Diff line
@@ -44,16 +44,33 @@ CameraDeviceSession::CameraDeviceSession(
    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(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;
    }
    mResultBatcher.setNumPartialResults(numPartialResults);

    mInitFail = initialize();
}
@@ -130,6 +147,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<buffer_handle_t*>& allBufPtrs,
@@ -611,14 +699,59 @@ Return<void> CameraDeviceSession::constructDefaultRequestSettings(
            ALOGI("%s: template %d is not supported on this camera device",
                  __FUNCTION__, type);
            status = Status::ILLEGAL_ARGUMENT;
        } else {
            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> 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 (!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 @@ Return<void> 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 +813,9 @@ Return<void> 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<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 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque

    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 @@ 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__);
@@ -881,6 +1047,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;
    }

@@ -908,6 +1077,17 @@ Return<void> 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());
            }
            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 @@ void CameraDeviceSession::sProcessCaptureResult(
    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 @@ void CameraDeviceSession::sNotify(
            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);
}

+29 −0
Original line number Diff line number Diff line
@@ -111,7 +111,18 @@ 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;
    bool mDerivePostRawSensKey;
    uint32_t mNumPartialResults;
    // Stream ID -> Camera3Stream cache
    std::map<int, Camera3Stream> mStreamMap;

@@ -119,6 +130,12 @@ private:
    // (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 @@ private:

    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
+48 −0
Original line number Diff line number Diff line
@@ -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();
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ private:

    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);