欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Treble 框架下的 Android Camera HAL3 一

程序员文章站 2022-06-08 20:42:12
...

frameworks/av/services/camera/libcameraservice/CameraService.cpp

frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp

frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp

frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp

frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp

frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.h

 

源码: Android 8

Android 8 和之前版本最大的变化是使用 Treble 架构分离了 framework 和 HAL

Treble 架构详见:AndroidO Treble架构下的变化(转载)

准备工作

 在之前的 cameraservice 源码分析中在如下代码中得知 camera hal的版本如下

CAMERA_DEVICE_API_VERSION_1_0

CAMERA_DEVICE_API_VERSION_3_0:
CAMERA_DEVICE_API_VERSION_3_1:
CAMERA_DEVICE_API_VERSION_3_2:
CAMERA_DEVICE_API_VERSION_3_3:
CAMERA_DEVICE_API_VERSION_3_4:

本文主要分析 camera HAL3,如想了解camera 流程参考 : CameraService 和 Client 链接到 HAL

在 cameraservice 服务中实例化 CameraDeviceClient  

CameraDeviceClient 调用模板 template <typename TClientBase>  实例化 Camera3Device

Treble 框架下的 Android Camera HAL3 一

 

 

camera HAL3

Android7  和 Android8 的区别

Treble 框架下的 Android Camera HAL3 一

如上图所示, Android 8 采用 HIDL 分离了 framework 和 HAL .

 

接下来分析 : sp<CameraProviderManager> manager

camera HAL1 和 HAL3 都使用了 Treble 架构

Treble 框架下的 Android Camera HAL3 一

 

在  CameraProviderManager.cpp 中的 deviceInfo3->mInterface->open(...)

关键字 auto 修饰成员变量 deviceInfo3 ,自动推导关键字 auto 增加阅读代码的难度。 

    auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);   // 类型转换

status_t CameraProviderManager::openSession(const std::string &id,
        const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
        /*out*/
        sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {

    std::lock_guard<std::mutex> lock(mInterfaceMutex);

    auto deviceInfo = findDeviceInfoLocked(id,
            /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
    if (deviceInfo == nullptr) return NAME_NOT_FOUND;

    auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);

    Status status;
    hardware::Return<void> ret;
    // 调用了 open 函数
    ret = deviceInfo3->mInterface->open(callback, [&status, &session]
            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
                status = s;
                if (status == Status::OK) {
                    *session = cameraSession;
                }
            });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
                __FUNCTION__, id.c_str(), ret.description().c_str());
        return DEAD_OBJECT;
    }
    return mapToStatusT(status);
}

在 CameraProviderManager.h 中找到 DeviceInfo3

          struct DeviceInfo3 : public DeviceInfo{...};  // cpp 中 struct 对 C 中 struct 进行了扩充。

DeviceInfo 中定义的成员函数是虚函数,需要子类实现, cpp 中虚函数的用法不做介绍。

重点:   typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;

hardware::camera::device::V3_2::ICameraDevice 中定义了 open 函数,和链接底层驱动。

因为 Android 8(O) 采用了 Treble 架构分离了 framework 和 HAL,并引入了后缀是 .hal 的文件(HAL 接口定义语言)。

// frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.h
        // HALv3-specific camera fields, including the actual device interface
        struct DeviceInfo3 : public DeviceInfo {
            typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;  // 重点
            const sp<InterfaceT> mInterface;

            virtual status_t setTorchMode(bool enabled) override;
            virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
            virtual bool isAPI1Compatible() const override;
            virtual status_t getCameraCharacteristics(
                    CameraMetadata *characteristics) const override;

            DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
                    const std::string &id, uint16_t minorVersion,
                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
                    sp<InterfaceT> interface);
            virtual ~DeviceInfo3();
        private:
            CameraMetadata mCameraCharacteristics;
        };

 

hardware::camera::device::V3_2::ICameraDevice

通过搜索和 ICameraDevice 关联的源码文件:

  • vendor/mediatek/proprietary/hardware/mtkcam/main/hal/device/3.x/include/ICameraDevice3Session.h
  • hardware/interfaces/camera/device/3.2/ICameraDevice.hal

两个文件中均声明了open:

// ICameraDevice.hal
open(ICameraDeviceCallback callback) generates
            (Status status, ICameraDeviceSession session);


// ICameraDevice3Session.h
virtual auto    open(
                     const ::android::sp<ICameraDeviceCallback>& callback
                     ) -> ::android::status_t                            = 0;

 

在编译系统的时候 ICameraDevice.hal 会编译成  ICameraDevice.h

使用 find 命令查找 :find ./out  -name ICameraDevice.h

打开 ICameraDevice.h 

//  ICameraDevice.h
using open_cb = std::function<void(::android::hardware::camera::common::V1_0::Status status, const ::android::sp<ICameraDeviceSession>& session)>;

virtual ::android::hardware::Return<void> open(const ::android::sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb) = 0;

查找 ::android::hardware::Return<void> open(...) 实现的位置:

hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp

打开模块的代码: 接下来定位追踪 mModule->open(...)

        ATRACE_BEGIN("camera3->open");
        res = mModule->open(mCameraId.c_str(),
                reinterpret_cast<hw_device_t**>(&device));
        ATRACE_END();
// hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb)  {
    Status status = initStatus();
    sp<CameraDeviceSession> session = nullptr;

    if (callback == nullptr) {
        ALOGE("%s: cannot open camera %s. callback is null!",
                __FUNCTION__, mCameraId.c_str());
        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
        return Void();
    }

    if (status != Status::OK) {
        // Provider will never pass initFailed device to client, so
        // this must be a disconnected camera
        ALOGE("%s: cannot open camera %s. camera is disconnected!",
                __FUNCTION__, mCameraId.c_str());
        _hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
        return Void();
    } else {
        mLock.lock();

        ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
        session = mSession.promote();
        if (session != nullptr && !session->isClosed()) {
            ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
            mLock.unlock();
            _hidl_cb(Status::CAMERA_IN_USE, nullptr);
            return Void();
        }

        /** Open HAL device */
        status_t res;
        camera3_device_t *device;

        ATRACE_BEGIN("camera3->open");
        res = mModule->open(mCameraId.c_str(),
                reinterpret_cast<hw_device_t**>(&device));
        ATRACE_END();

        if (res != OK) {
            ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str());
            mLock.unlock();
            _hidl_cb(getHidlStatus(res), nullptr);
            return Void();
        }

        /** Cross-check device version */
        if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
            ALOGE("%s: Could not open camera: "
                    "Camera device should be at least %x, reports %x instead",
                    __FUNCTION__,
                    CAMERA_DEVICE_API_VERSION_3_2,
                    device->common.version);
            device->common.close(&device->common);
            mLock.unlock();
            _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
            return Void();
        }

        struct camera_info info;
        res = mModule->getCameraInfo(mCameraIdInt, &info);
        if (res != OK) {
            ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
            device->common.close(&device->common);
            mLock.unlock();
            _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
            return Void();
        }

        session = createSession(
                device, info.static_camera_characteristics, callback);
        if (session == nullptr) {
            ALOGE("%s: camera device session allocation failed", __FUNCTION__);
            mLock.unlock();
            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
            return Void();
        }
        if (session->isInitFailed()) {
            ALOGE("%s: camera device session init failed", __FUNCTION__);
            session = nullptr;
            mLock.unlock();
            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
            return Void();
        }
        mSession = session;

        IF_ALOGV() {
            session->getInterface()->interfaceChain([](
                ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
                    ALOGV("Session interface chain:");
                    for (auto iface : interfaceChain) {
                        ALOGV("  %s", iface.c_str());
                    }
                });
        }
        mLock.unlock();
    }
    _hidl_cb(status, session->getInterface());
    return Void();
}

 

mModule->open(...)

根据源码: const sp<CameraModule> mModule; 接下来分析类 CameraModule 。

hardware/interfaces/camera/common/1.0/default/CameraModule.cpp

// hardware/interfaces/camera/common/1.0/default/CameraModule.cpp
// 结合分析 Android 7 camera 的经验,推测 nModule->methods->open() 和 cameraHAL 息息相关
int CameraModule::open(const char* id, struct hw_device_t** device) {
    int res;
    ATRACE_BEGIN("camera_module->open");
    res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
    ATRACE_END();
    return res;
}

Android 8 (O) 中使用 Treble 架构分离了 framework 和 HAL : 下节分析 Android 8(O)  camera HAL3 的注册。

// hardware/libhardware/include/hardware/camera_common.h
typedef struct camera_module
{
	...
	hw_module_t common;
	...
}

// hardware/libhardware/include/hardware/hardware.h
typedef struct hw_module_methods_t
{
    /** Open a specific device */
    int (*open)(const struct hw_module_t* module, const char* id,
            struct hw_device_t** device);

} hw_module_methods_t;

 

相关标签: camera HAL3