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

Commit ee23840b authored by Yin-Chia Yeh's avatar Yin-Chia Yeh
Browse files

Camera: add external camera@3.5

External camera@3.5 supports the new buffer management
API that allows HAL to request buffer when needed to
optimize the memory usage.

Test: smoke test TestingCamera
Bug: 109829698
Change-Id: Icfbb75a26d8e92e4eb82a680e94e183041a5174d
parent ccc05ec9
Loading
Loading
Loading
Loading
+35 −59
Original line number Diff line number Diff line
@@ -50,22 +50,29 @@ constexpr int OPEN_RETRY_SLEEP_US = 100000; // 100ms * MAX_RETRY = 0.5 seconds
ExternalCameraDevice::ExternalCameraDevice(
        const std::string& cameraId, const ExternalCameraConfig& cfg) :
        mCameraId(cameraId),
        mCfg(cfg) {
        mCfg(cfg) {}

ExternalCameraDevice::~ExternalCameraDevice() {}

bool ExternalCameraDevice::isInitFailed() {
    Mutex::Autolock _l(mLock);
    return isInitFailedLocked();
}

bool ExternalCameraDevice::isInitFailedLocked() {
    if (!mInitialized) {
        status_t ret = initCameraCharacteristics();
        if (ret != OK) {
            ALOGE("%s: init camera characteristics failed: errorno %d", __FUNCTION__, ret);
            mInitFailed = true;
        }
        mInitialized = true;
    }

ExternalCameraDevice::~ExternalCameraDevice() {}

bool ExternalCameraDevice::isInitFailed() {
    return mInitFailed;
}

Return<void> ExternalCameraDevice::getResourceCost(getResourceCost_cb _hidl_cb) {
Return<void> ExternalCameraDevice::getResourceCost(
        ICameraDevice::getResourceCost_cb _hidl_cb) {
    CameraResourceCost resCost;
    resCost.resourceCost = 100;
    _hidl_cb(Status::OK, resCost);
@@ -73,11 +80,11 @@ Return<void> ExternalCameraDevice::getResourceCost(getResourceCost_cb _hidl_cb)
}

Return<void> ExternalCameraDevice::getCameraCharacteristics(
        getCameraCharacteristics_cb _hidl_cb) {
        ICameraDevice::getCameraCharacteristics_cb _hidl_cb) {
    Mutex::Autolock _l(mLock);
    V3_2::CameraMetadata hidlChars;

    if (isInitFailed()) {
    if (isInitFailedLocked()) {
        _hidl_cb(Status::INTERNAL_ERROR, hidlChars);
        return Void();
    }
@@ -94,7 +101,7 @@ Return<Status> ExternalCameraDevice::setTorchMode(TorchMode) {
}

Return<void> ExternalCameraDevice::open(
        const sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb) {
        const sp<ICameraDeviceCallback>& callback, ICameraDevice::open_cb _hidl_cb) {
    Status status = Status::OK;
    sp<ExternalCameraDeviceSession> session = nullptr;

@@ -143,7 +150,7 @@ Return<void> ExternalCameraDevice::open(
        }
    }

    session = new ExternalCameraDeviceSession(
    session = createSession(
            callback, mCfg, mSupportedFormats, mCroppingType,
            mCameraCharacteristics, mCameraId, std::move(fd));
    if (session == nullptr) {
@@ -479,52 +486,9 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(
    UPDATE(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, availableResultKeys,
           ARRAY_SIZE(availableResultKeys));

    const int32_t availableCharacteristicsKeys[] = {
        ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
        ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
        ANDROID_CONTROL_AE_AVAILABLE_MODES,
        ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
        ANDROID_CONTROL_AE_COMPENSATION_RANGE,
        ANDROID_CONTROL_AE_COMPENSATION_STEP,
        ANDROID_CONTROL_AE_LOCK_AVAILABLE,
        ANDROID_CONTROL_AF_AVAILABLE_MODES,
        ANDROID_CONTROL_AVAILABLE_EFFECTS,
        ANDROID_CONTROL_AVAILABLE_MODES,
        ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
        ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
        ANDROID_CONTROL_AWB_AVAILABLE_MODES,
        ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
        ANDROID_CONTROL_MAX_REGIONS,
        ANDROID_FLASH_INFO_AVAILABLE,
        ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
        ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
        ANDROID_LENS_FACING,
        ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
        ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
        ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
        ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
        ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
        ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
        ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
        ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
        ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
        ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
        ANDROID_SCALER_CROPPING_TYPE,
        ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
        ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
        ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
        ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
        ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
        ANDROID_SENSOR_ORIENTATION,
        ANDROID_SHADING_AVAILABLE_MODES,
        ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
        ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
        ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
        ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
        ANDROID_SYNC_MAX_LATENCY};
    UPDATE(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
           availableCharacteristicsKeys,
           ARRAY_SIZE(availableCharacteristicsKeys));
           AVAILABLE_CHARACTERISTICS_KEYS_3_4.data(),
           AVAILABLE_CHARACTERISTICS_KEYS_3_4.size());

    return OK;
}
@@ -931,6 +895,18 @@ void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
    }
}

sp<ExternalCameraDeviceSession> ExternalCameraDevice::createSession(
        const sp<ICameraDeviceCallback>& cb,
        const ExternalCameraConfig& cfg,
        const std::vector<SupportedV4L2Format>& sortedFormats,
        const CroppingType& croppingType,
        const common::V1_0::helper::CameraMetadata& chars,
        const std::string& cameraId,
        unique_fd v4l2Fd) {
    return new ExternalCameraDeviceSession(
            cb, cfg, sortedFormats, croppingType, chars, cameraId, std::move(v4l2Fd));
}

}  // namespace implementation
}  // namespace V3_4
}  // namespace device
+161 −59
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@ bool tryLock(std::mutex& mutex)
    return locked;
}

buffer_handle_t sEmptyBuffer = nullptr;

} // Anonymous namespace

// Static instances
@@ -103,11 +105,8 @@ ExternalCameraDeviceSession::ExternalCameraDeviceSession(
        mCroppingType(croppingType),
        mCameraId(cameraId),
        mV4l2Fd(std::move(v4l2Fd)),
        mOutputThread(new OutputThread(this, mCroppingType)),
        mMaxThumbResolution(getMaxThumbResolution()),
        mMaxJpegResolution(getMaxJpegResolution()) {
    mInitFail = initialize();
}
        mMaxJpegResolution(getMaxJpegResolution()) {}

bool ExternalCameraDeviceSession::initialize() {
    if (mV4l2Fd.get() < 0) {
@@ -142,6 +141,12 @@ bool ExternalCameraDeviceSession::initialize() {
            model = card;
        }
    }

    initOutputThread();
    if (mOutputThread == nullptr) {
        ALOGE("%s: init OutputThread failed!", __FUNCTION__);
        return true;
    }
    mOutputThread->setExifMakeModel(make, model);

    status_t status = initDefaultRequests();
@@ -168,6 +173,32 @@ bool ExternalCameraDeviceSession::initialize() {
    return false;
}

bool ExternalCameraDeviceSession::isInitFailed() {
    Mutex::Autolock _l(mLock);
    if (!mInitialized) {
        mInitFail = initialize();
        mInitialized = true;
    }
    return mInitFail;
}

void ExternalCameraDeviceSession::initOutputThread() {
    mOutputThread = new OutputThread(this, mCroppingType);
}

void ExternalCameraDeviceSession::closeOutputThread() {
    closeOutputThreadImpl();
}

void ExternalCameraDeviceSession::closeOutputThreadImpl() {
    if (mOutputThread) {
        mOutputThread->flush();
        mOutputThread->requestExit();
        mOutputThread->join();
        mOutputThread.clear();
    }
}

Status ExternalCameraDeviceSession::initStatus() const {
    Mutex::Autolock _l(mLock);
    Status status = Status::OK;
@@ -181,7 +212,7 @@ Status ExternalCameraDeviceSession::initStatus() const {
ExternalCameraDeviceSession::~ExternalCameraDeviceSession() {
    if (!isClosed()) {
        ALOGE("ExternalCameraDeviceSession deleted before close!");
        close();
        close(/*callerIsDtor*/true);
    }
}

@@ -442,19 +473,24 @@ Return<Status> ExternalCameraDeviceSession::flush() {
    return Status::OK;
}

Return<void> ExternalCameraDeviceSession::close() {
Return<void> ExternalCameraDeviceSession::close(bool callerIsDtor) {
    Mutex::Autolock _il(mInterfaceLock);
    bool closed = isClosed();
    if (!closed) {
        mOutputThread->flush();
        mOutputThread->requestExit();
        mOutputThread->join();
        if (callerIsDtor) {
            closeOutputThreadImpl();
        } else {
            closeOutputThread();
        }

        Mutex::Autolock _l(mLock);
        // free all buffers
        {
            Mutex::Autolock _l(mCbsLock);
            for(auto pair : mStreamMap) {
                cleanupBuffersLocked(/*Stream ID*/pair.first);
            }
        }
        v4l2StreamOffLocked();
        ALOGV("%s: closing V4L2 camera FD %d", __FUNCTION__, mV4l2Fd.get());
        mV4l2Fd.reset();
@@ -463,10 +499,61 @@ Return<void> ExternalCameraDeviceSession::close() {
    return Void();
}

Status ExternalCameraDeviceSession::importRequest(
Status ExternalCameraDeviceSession::importRequestLocked(
    const CaptureRequest& request,
    hidl_vec<buffer_handle_t*>& allBufPtrs,
    hidl_vec<int>& allFences) {
    return importRequestLockedImpl(request, allBufPtrs, allFences);
}

Status ExternalCameraDeviceSession::importBuffer(int32_t streamId,
        uint64_t bufId, buffer_handle_t buf,
        /*out*/buffer_handle_t** outBufPtr,
        bool allowEmptyBuf) {
    Mutex::Autolock _l(mCbsLock);
    return importBufferLocked(streamId, bufId, buf, outBufPtr, allowEmptyBuf);
}

Status ExternalCameraDeviceSession::importBufferLocked(int32_t streamId,
        uint64_t bufId, buffer_handle_t buf,
        /*out*/buffer_handle_t** outBufPtr,
        bool allowEmptyBuf) {

    if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) {
        if (allowEmptyBuf) {
            *outBufPtr = &sEmptyBuffer;
            return Status::OK;
        } else {
            ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
            return Status::ILLEGAL_ARGUMENT;
        }
    }

    CirculatingBuffers& cbs = mCirculatingBuffers[streamId];
    if (cbs.count(bufId) == 0) {
        if (buf == nullptr) {
            ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
            return Status::ILLEGAL_ARGUMENT;
        }
        // Register a newly seen buffer
        buffer_handle_t importedBuf = buf;
        sHandleImporter.importBuffer(importedBuf);
        if (importedBuf == nullptr) {
            ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId);
            return Status::INTERNAL_ERROR;
        } else {
            cbs[bufId] = importedBuf;
        }
    }
    *outBufPtr = &cbs[bufId];
    return Status::OK;
}

Status ExternalCameraDeviceSession::importRequestLockedImpl(
        const CaptureRequest& request,
        hidl_vec<buffer_handle_t*>& allBufPtrs,
        hidl_vec<int>& allFences,
        bool allowEmptyBuf) {
    size_t numOutputBufs = request.outputBuffers.size();
    size_t numBufs = numOutputBufs;
    // Validate all I/O buffers
@@ -485,26 +572,17 @@ Status ExternalCameraDeviceSession::importRequest(
        streamIds[i] = request.outputBuffers[i].streamId;
    }

    {
        Mutex::Autolock _l(mCbsLock);
        for (size_t i = 0; i < numBufs; i++) {
        buffer_handle_t buf = allBufs[i];
        uint64_t bufId = allBufIds[i];
        CirculatingBuffers& cbs = mCirculatingBuffers[streamIds[i]];
        if (cbs.count(bufId) == 0) {
            if (buf == nullptr) {
                ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
                return Status::ILLEGAL_ARGUMENT;
            }
            // Register a newly seen buffer
            buffer_handle_t importedBuf = buf;
            sHandleImporter.importBuffer(importedBuf);
            if (importedBuf == nullptr) {
                ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i);
                return Status::INTERNAL_ERROR;
            } else {
                cbs[bufId] = importedBuf;
            Status st = importBufferLocked(
                    streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i],
                    allowEmptyBuf);
            if (st != Status::OK) {
                // Detailed error logs printed in importBuffer
                return st;
            }
        }
        allBufPtrs[i] = &cbs[bufId];
    }

    // All buffers are imported. Now validate output buffer acquire fences
@@ -652,7 +730,7 @@ Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureReques
        }
    }

    status = importRequest(request, allBufPtrs, allFences);
    status = importRequestLocked(request, allBufPtrs, allFences);
    if (status != Status::OK) {
        return status;
    }
@@ -775,9 +853,11 @@ Status ExternalCameraDeviceSession::processCaptureResult(std::shared_ptr<HalRequ
        result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
        if (req->buffers[i].fenceTimeout) {
            result.outputBuffers[i].status = BufferStatus::ERROR;
            if (req->buffers[i].acquireFence > 0) {
                native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
                handle->data[0] = req->buffers[i].acquireFence;
                result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
            }
            notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
        } else {
            result.outputBuffers[i].status = BufferStatus::OK;
@@ -1747,6 +1827,12 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
                (req->frameIn->mFourcc >> 24) & 0xFF);
    }

    int res = requestBufferStart(req->buffers);
    if (res != 0) {
        ALOGE("%s: send BufferRequest failed! res %d", __FUNCTION__, res);
        return onDeviceError("%s: failed to send buffer request!", __FUNCTION__);
    }

    std::unique_lock<std::mutex> lk(mBufferLock);
    // Convert input V4L2 frame to YU12 of the same size
    // TODO: see if we can save some computation by converting to YV12 here
@@ -1755,7 +1841,7 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
    req->frameIn->map(&inData, &inDataSize);
    // TODO: in some special case maybe we can decode jpg directly to gralloc output?
    ATRACE_BEGIN("MJPGtoI420");
    int res = libyuv::MJPGToI420(
    res = libyuv::MJPGToI420(
            inData, inDataSize,
            static_cast<uint8_t*>(mYu12FrameLayout.y),
            mYu12FrameLayout.yStride,
@@ -1779,10 +1865,23 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
        return true;
    }

    ATRACE_BEGIN("Wait for BufferRequest done");
    res = waitForBufferRequestDone(&req->buffers);
    ATRACE_END();

    if (res != 0) {
        ALOGE("%s: wait for BufferRequest done failed! res %d", __FUNCTION__, res);
        lk.unlock();
        return onDeviceError("%s: failed to process buffer request error!", __FUNCTION__);
    }

    ALOGV("%s processing new request", __FUNCTION__);
    const int kSyncWaitTimeoutMs = 500;
    for (auto& halBuf : req->buffers) {
        if (halBuf.acquireFence != -1) {
        if (*(halBuf.bufPtr) == nullptr) {
            ALOGW("%s: buffer for stream %d missing", __FUNCTION__, halBuf.streamId);
            halBuf.fenceTimeout = true;
        } else if (halBuf.acquireFence != -1) {
            int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs);
            if (ret) {
                halBuf.fenceTimeout = true;
@@ -2041,7 +2140,7 @@ void ExternalCameraDeviceSession::cleanupBuffersLocked(int id) {
}

void ExternalCameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove) {
    Mutex::Autolock _l(mLock);
    Mutex::Autolock _l(mCbsLock);
    for (auto& cache : cachesToRemove) {
        auto cbsIt = mCirculatingBuffers.find(cache.streamId);
        if (cbsIt == mCirculatingBuffers.end()) {
@@ -2494,6 +2593,8 @@ Status ExternalCameraDeviceSession::configureStreams(
    }

    Mutex::Autolock _l(mLock);
    {
        Mutex::Autolock _l(mCbsLock);
        // Add new streams
        for (const auto& stream : config.streams) {
            if (mStreamMap.count(stream.id) == 0) {
@@ -2520,6 +2621,7 @@ Status ExternalCameraDeviceSession::configureStreams(
                ++it;
            }
        }
    }

    // Now select a V4L2 format to produce all output streams
    float desiredAr = (mCroppingType == VERTICAL) ? kMaxAspectRatio : kMinAspectRatio;
+40 −5
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ struct ExternalCameraDeviceSession : public virtual RefBase {
    // Call by CameraDevice to dump active device states
    void dumpState(const native_handle_t*);
    // Caller must use this method to check if CameraDeviceSession ctor failed
    bool isInitFailed() { return mInitFail; }
    bool isInitFailed();
    bool isClosed();

    // Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
@@ -134,7 +134,7 @@ protected:
            ICameraDeviceSession::processCaptureRequest_cb);

    Return<Status> flush();
    Return<void> close();
    Return<void> close(bool callerIsDtor = false);

    Return<void> configureStreams_3_3(
            const V3_2::StreamConfiguration&,
@@ -170,10 +170,17 @@ protected:
        std::vector<HalStreamBuffer> buffers;
    };

    static const uint64_t BUFFER_ID_NO_BUFFER = 0;

    Status constructDefaultRequestSettingsRaw(RequestTemplate type,
            V3_2::CameraMetadata *outMetadata);

    bool initialize();
    // To init/close different version of output thread
    virtual void initOutputThread();
    virtual void closeOutputThread();
    void closeOutputThreadImpl();

    Status initStatus() const;
    status_t initDefaultRequests();
    status_t fillCaptureResult(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp);
@@ -195,10 +202,28 @@ protected:
    bool isSupported(const Stream&);

    // Validate and import request's output buffers and acquire fence
    Status importRequest(
    virtual Status importRequestLocked(
            const CaptureRequest& request,
            hidl_vec<buffer_handle_t*>& allBufPtrs,
            hidl_vec<int>& allFences);

    Status importRequestLockedImpl(
            const CaptureRequest& request,
            hidl_vec<buffer_handle_t*>& allBufPtrs,
            hidl_vec<int>& allFences,
            // Optional argument for ICameraDeviceSession@3.5 impl
            bool allowEmptyBuf = false);

    Status importBuffer(int32_t streamId,
            uint64_t bufId, buffer_handle_t buf,
            /*out*/buffer_handle_t** outBufPtr,
            bool allowEmptyBuf);

    Status importBufferLocked(int32_t streamId,
            uint64_t bufId, buffer_handle_t buf,
            /*out*/buffer_handle_t** outBufPtr,
            bool allowEmptyBuf);

    static void cleanupInflightFences(
            hidl_vec<int>& allFences, size_t numFences);
    void cleanupBuffersLocked(int id);
@@ -224,7 +249,7 @@ protected:
    class OutputThread : public android::Thread {
    public:
        OutputThread(wp<ExternalCameraDeviceSession> parent, CroppingType);
        ~OutputThread();
        virtual ~OutputThread();

        Status allocateIntermediateBuffers(
                const Size& v4lSize, const Size& thumbSize,
@@ -236,7 +261,14 @@ protected:
        virtual bool threadLoop() override;

        void setExifMakeModel(const std::string& make, const std::string& model);
    private:

    protected:
        // Methods to request output buffer in parallel
        // No-op for device@3.4. Implemented in device@3.5
        virtual int requestBufferStart(const std::vector<HalStreamBuffer>&) { return 0; }
        virtual int waitForBufferRequestDone(
                /*out*/std::vector<HalStreamBuffer>*) { return 0; }

        static const uint32_t FLEX_YUV_GENERIC = static_cast<uint32_t>('F') |
                static_cast<uint32_t>('L') << 8 | static_cast<uint32_t>('E') << 16 |
                static_cast<uint32_t>('X') << 24;
@@ -319,6 +351,7 @@ protected:
    //    - init failed
    //    - camera disconnected
    bool mClosed = false;
    bool mInitialized = false;
    bool mInitFail = false;
    bool mFirstRequest = false;
    common::V1_0::helper::CameraMetadata mLatestReqSetting;
@@ -351,6 +384,8 @@ protected:
    typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
    // Stream ID -> circulating buffers map
    std::map<int, CirculatingBuffers> mCirculatingBuffers;
    // Protect mCirculatingBuffers, must not lock mLock after acquiring this lock
    mutable Mutex mCbsLock;

    std::mutex mAfTriggerLock; // protect mAfTrigger
    bool mAfTrigger = false;
+110 −8

File changed.

Preview size limit exceeded, changes collapsed.

+48 −0
Original line number Diff line number Diff line
@@ -20,6 +20,12 @@ cc_library_headers {
    export_include_dirs: ["include/device_v3_5_impl"]
}

cc_library_headers {
    name: "camera.device@3.5-external-impl_headers",
    vendor: true,
    export_include_dirs: ["include/ext_device_v3_5_impl"]
}

cc_library_shared {
    name: "camera.device@3.5-impl",
    defaults: ["hidl_defaults"],
@@ -52,3 +58,45 @@ cc_library_shared {
    ],
    local_include_dirs: ["include/device_v3_5_impl"],
}

cc_library_shared {
    name: "camera.device@3.5-external-impl",
    defaults: ["hidl_defaults"],
    proprietary: true,
    vendor: true,
    srcs: [
        "ExternalCameraDevice.cpp",
        "ExternalCameraDeviceSession.cpp",
    ],
    shared_libs: [
        "libhidlbase",
        "libhidltransport",
        "libutils",
        "libcutils",
        "camera.device@3.2-impl",
        "camera.device@3.3-impl",
        "camera.device@3.4-external-impl",
        "android.hardware.camera.device@3.2",
        "android.hardware.camera.device@3.3",
        "android.hardware.camera.device@3.4",
        "android.hardware.camera.device@3.5",
        "android.hardware.camera.provider@2.4",
        "android.hardware.graphics.mapper@2.0",
        "liblog",
        "libhardware",
        "libcamera_metadata",
        "libfmq",
        "libsync",
        "libyuv",
        "libjpeg",
        "libexif",
        "libtinyxml2"
    ],
    static_libs: [
        "android.hardware.camera.common@1.0-helper",
    ],
    local_include_dirs: ["include/ext_device_v3_5_impl"],
    export_shared_lib_headers: [
        "libfmq",
    ],
}
Loading