Treble 框架下的 Android Camera HAL3 一

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

camera HAL3
Android7  和 Android8 的区别

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

接下来分析 : sp<CameraProviderManager> manager
camera HAL1 和 HAL3 都使用了 Treble 架构

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值