Android Camera(一) Provider启动流程 (androidP)(HIDL)

本文详细解析了Android系统中CameraProvider服务的启动流程,包括通过rc文件启动、binder线程池配置、HIDL接口调用和服务注册过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章开始分析camera框架 主要是自己用来加深理解的 内含HIDL的调用流程

camera provider 启动


android.hardware.camera.provider@2.4-service.rc

路径  hardware/interfaces/camera/provider/2.4/default/android.hardware.camera.provider@2.4-service.rc

跟普通服务类似就是以一个rc文件启动的,在之前的文章中我们分析过rc文件是如何启动服务的

android8.1系统启动过程(四) 解析init.rc_we1less的博客-优快云博客

service camera-provider-2-4 /vendor/bin/hw/android.hardware.camera.provider@2.4-service
    class hal
    user cameraserver
    group audio camera input drmrpc
    ioprio rt 4
    capabilities SYS_NICE
    writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks

在android启动的过程中,init进程调用该脚本启动 camera provider 服务。根据该目录下的 Android.bp 可以知道,其实就是运行该目录下 service.cpp 编译的可执行文件 


main

路径  hardware/interfaces/camera/provider/2.4/default/service.cpp

        驱动可通过vndbinder与其他HAL模块通信,默认创建直通式的camera provider 服务,在Treble架构下,存在了3个binder设备,分别是/dev/binder、/dev/vndbinder、/dev/hwbinder,上层需要通过binder库来访问这些binder设备,而/dev/binder和/dev/vndbinder都是由libbinder来访问,因此需要指定打开的binder设备。

int main()
{
    ALOGI("Camera provider Service is starting.");
    // The camera HAL may communicate to other vendor components via
    // /dev/vndbinder
    android::ProcessState::initWithDriver("/dev/vndbinder");
    return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0", /*maxThreads*/ 6);
}

defaultPassthroughServiceImplementation

路径  system/libhidl/transport/include/hidl/LegacySupport.h

        配置binder线程个数,然后调用registerPassthroughServiceImplementation

        joinRpcThreadpool参考这篇Android Binder 服务端分析_we1less的博客-优快云博客

template<class Interface>
__attribute__((warn_unused_result))
status_t defaultPassthroughServiceImplementation(std::string name,
                                            size_t maxThreads = 1) {
    configureRpcThreadpool(maxThreads, true); //配置binder线程个数
    status_t result = registerPassthroughServiceImplementation<Interface>(name);
    ...
    //
    joinRpcThreadpool();
    return 0;
}

registerPassthroughServiceImplementation

路径  system/libhidl/transport/include/hidl/LegacySupport.h

        调用 HIDL 生成的接口 ICameraProvider::getService,得到BpHwCameraProvider,name = "legacy/0" , getStub = true, 为直通模式

        注册 cameraprovider, name = "legacy/0" // 后面其他服务通过HwServiceManager get service是就是是此名称

template<class Interface>
__attribute__((warn_unused_result))
status_t registerPassthroughServiceImplementation(
        std::string name = "default") {
    sp<Interface> service = Interface::getService(name, true /* getStub */);
    //调用ICameraProvider接口类的getService
    ...
    //注册 cameraprovider, name = "legacy/0"
	// 后面其他服务通过HwServiceManager get service是就是是此名称
    status_t status = service->registerAsService(name);
    ...
    return status;
}

ICameraProvider::getService

路径  

out/soong/.intermediates/hardware/interfaces/camera/provider/2.4/android.hardware.camera.provider@2.4_genc++/gen/android/hardware/camera/provider/2.4/CameraProviderAll.cpp

        这地方就是调用链了              

#include <hidl/HidlTransportSupport.h>
...
const char* ICameraProvider::descriptor("android.hardware.camera.provider@2.4::ICameraProvider");
...
// static
::android::sp<ICameraProvider> ICameraProvider::getService(const std::string &serviceName, const bool getStub) {
    return ::android::hardware::details::getServiceInternal<BpHwCameraProvider>(serviceName, true, getStub);
}

getServiceInternal

路径  system/libhidl/transport/include/hidl/HidlTransportSupport.h

        因为BpType = BpHwCameraProvider,所以IType = typename BpType::Pure

        因为在out/soong/.intermediates/hardware/interfaces/camera/provider/2.4/android.hardware.camera.provider@2.4_genc++_headers/gen/android/hardware/camera/provider/2.4/BpHwCameraProvider.h

这个文件中有定义    typedef ICameraProvider Pure;

        所以 IType::descriptor == ICameraProvider::descriptor  参见CameraProviderAll的代码可知:

        IType::descriptor = android.hardware.camera.provider@2.4::ICameraProvider

        instance = "legacy/0"

template <typename BpType, typename IType = typename BpType::Pure,
          typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
          typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
    using ::android::hidl::base::V1_0::IBase;

    sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
    ...
    if (base->isRemote()) {
        // getRawServiceInternal guarantees we get the proper class
        return sp<IType>(new BpType(toBinder<IBase>(base)));
    }

    return IType::castFrom(base);
}

getRawServiceInternal

路径  system/libhidl/transport/ServiceManagement.cpp

        获取 hwservicemanager 服务, 用于获取Service的client端即BpXXX代理类

        descriptor = android.hardware.camera.provider@2.4::ICameraProvider

        getStub = false 时,一般用于其他服务获取cameraprovider服务

        getStub = true 用于服务启动过程 我们从服务启动的角度继续分析

sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
                                                             const std::string& instance,
                                                             bool retry, bool getStub) {
    using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
    using ::android::hidl::base::V1_0::IBase;
    using ::android::hidl::manager::V1_0::IServiceManager;
    sp<Waiter> waiter;
    // 获取 hwservicemanager 服务, 用于获取Service的client端即BpXXX代理类
    const sp<IServiceManager1_1> sm = defaultServiceManager1_1();
    ...
    // getStub = false 时,走此流程,拿到 cameraprovider 
	// 一般用于其他服务获取cameraprovider服务
	// 比如cameraservice 获取 cameraprovider时,拿到<sp<IBase>>,之后会New BpHwCameraProvider
	// 通过 BpHwCameraProvider类调用HIDL通信
    for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
        ...
        Return<sp<IBase>> ret = sm->get(descriptor, instance);
        ...
    }
    ...
    //getStub = true 是走此流程,用于服务启动过程
    if (getStub || vintfPassthru || vintfLegacy) {
        const sp<IServiceManager> pm = getPassthroughServiceManager();
        if (pm != nullptr) {
            // 返回CameraProvider实例,CameraProvider是ICameraProvider的子类
        	// ICameraProvider是IBase的子类
            sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
            ...
            return base;
        }
    }

    return nullptr;
}

getPassthroughServiceManager

路径  system/libhidl/transport/ServiceManagement.cpp

        PassthroughServiceManager 是 IServiceManager1_1 的子类,重写了get等方法后面就是调用此get方法,而get方法中则调用了openLibs方法其中传递进去一个匿名函数

        在openLibs方法中

        fqName = descriptor = android.hardware.camera.provider@2.4::ICameraProvider

        packageAndVersion = android.hardware.camera.provider@2.4

        fullPath = /vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so

        lib = android.hardware.camera.provider@2.4-impl.so

sp<IServiceManager1_0> getPassthroughServiceManager() {
    return getPassthroughServiceManager1_1();
}

sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
    // PassthroughServiceManager 是 IServiceManager1_1 的子类,重写了get等方法
	// 后面就是调用此get方法
    static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
    return manager;
}

//  sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);

Return<sp<IBase>> get(const hidl_string& fqName,
                      const hidl_string& name) override {
    sp<IBase> ret = nullptr;
    /* [&] 此处为Lambda表达式,简单理解为函数指针即可,先执行 openLibs() */
    openLibs(fqName, /*接下来的参数这样的写法是一个匿名的函数*/[&](void* handle, const std::string &lib, const std::string &sym) {
        /* handle :dlopen() 的返回值
         * lib :android.hardware.camera.provider@2.4-impl.so
         * sym :HIDL_FETCH_ICameraProvider
         */

        IBase* (*generator)(const char* name);
        *(void **)(&generator) = dlsym(handle, sym.c_str());
        ...
        ret = (*generator)(name.c_str());
        ...
    });

    return ret;
}


static void openLibs(
    const std::string& fqName,
    const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
                                             const std::string& /* sym */)>& eachLib) {
    //fqName looks like android.hardware.foo@1.0::IFoo
    //获取 :: 位置
    size_t idx = fqName.find("::");
    ...
    // packageAndVersion = android.hardware.camera.provider@2.4
    std::string packageAndVersion = fqName.substr(0, idx);
    //ifaceName = ICameraProvider
    std::string ifaceName = fqName.substr(idx + strlen("::"));
    //得到库名 prefix = android.hardware.camera.provider@2.4-impl
    const std::string prefix = packageAndVersion + "-impl";
    //函数名 sym = HIDL_FETCH_ICameraProvider
    const std::string sym = "HIDL_FETCH_" + ifaceName;
    //这个里面装着路径
    std::vector<std::string> paths = {HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR,
                                          halLibPathVndkSp, HAL_LIBRARY_PATH_SYSTEM};
    ...
    for (const std::string& path : paths) {
            std::vector<std::string> libs = search(path, prefix, ".so");

            for (const std::string &lib : libs) {
                const std::string fullPath = path + lib;
                /* 经过上面的一些添加转换,最终
                 * fullPath = /vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so
                   lib = android.hardware.camera.provider@2.4-impl.so
                 * */
                if (path == HAL_LIBRARY_PATH_SYSTEM) {
                    handle = dlopen(fullPath.c_str(), dlMode);
                } else {
                    handle = android_load_sphal_library(fullPath.c_str(), dlMode);
                }
                ...
                /* 调用Lambda表达式 */
                if (!eachLib(handle, lib, sym)) {
                    return;
                }
            }
        }
}

open camera流程 CameraManager.java 在apk中使用camera需要创建CameraManager实例,再通过CameraManager::openCamera()打开设备, OpenCamera() openCameraForUid openCameraDeviceUserAsync() ①getCameraCharacteristics():获取指定 cameraId 对应的相机特性信息,返回值 CameraCharacteristics包含相机的各种属性,比如支持的分辨率、硬件、功能等。 ②new android.hardware.camera2.impl.CameraDeviceImpl 实例化CameraDeviceImpl对象 ③CameraManagerGlobal.get().getCameraService(); 通过binder获取CameraService接口 ④通过cameraService.connectDevice连接cameraDevice ⑤setRemoteDevice方法主要是将获取到的远端设备保存起来 CameraService.cpp connectDevice()CameraManager.java通过connectDevice进入到CameraService.cpp中 ②调用connectHelper模板函数来创建CameraDeviceClient实例,并于HAL层建立连接 connectHelper() ①makeClient生成CameraDeviceClient实例 makeclient会根据API的版本和HAL版本选择生成具体Client的实例 对应关系: API1+HAL3->CameraClient API1+HAL3->Camera2Client API2+HAL3->CameraDeviceClient ②初始化CLIENT实例 ③Client->initialize()等同于HidlCamera3Device::initialize() / AidlCamera3Device::initialize() CameraDeviceClient.cpp CameraDeviceClient.h中可以看到CameraDeviceClient继承于 Camera2ClientBase Camera2ClientBase.cpp 后面以Hidl为例 HidlCamera3Device.h HidlCamera3Device继承于Camera3Device HidlCamera3Device.cpp manager-openHidlSession()打开指定相机ID的会话,获取HAL接口 manager->getCameracharacteristics获取相机特性元数据(分辨率、能力...) CameraProviderManager.cpp HidlProviderInfo.cpp auto interface = HidlDeviceInfo3->startDeviceInterface() ---> device = parentProvider->startDeviceInterface(mName); ---> ret = interface->getCameraDeviceInterface_V3_x 调用ICameraProvider接口的getCameraDeviceInterface_V3_x来获取获取ICameraDevice的实例。 AidlProviderInfo.cpp aidl最后调用的是getCameraDeviceInterface();通用相机设备接口(通常为最新版) Camera3DeviceImpl.cpp 在MTK CameraHIDL框架中,从HidlProviderInfo.cpp到Camera3DeviceImpl.cpp的调用链路主要涉及HIDL接口实例化与设备实现类绑定,具体路径如下: 关键调用流程 1. HidlProviderInfo获取设备接口 在HidlProviderInfo.cpp中,startDeviceInterface方法通过调用ICameraProvider::getCameraDeviceInterface_V3_x(HIDL接口方法),向HAL层请求获取指定相机设备的ICameraDevice接口实例(HIDL接口)。该方法的实现由HAL层的相机Provider完成,最终返回的ICameraDevice接口实例由CameraDevice3Impl类具体实现即CameraDevice3Impl是ICameraDevice的HIDL服务端实现类)。 2. Camera3DeviceImpl实例化 HAL层在接收到getCameraDeviceInterface_V3_x请求后,会根据设备ID(如"0")实例化对应的Camera3DeviceImpl对象。该类是HAL层设备操作的核心实现类,负责处理设备打开、配置、数据流等核心功能。 ICameraDevice.h Camera3DeviceImpl.h Camera3DeviceImpl.cpp 3. 接口绑定与方法调用 HidlProviderInfo获取到ICameraDevice接口(即CameraDevice3Impl实例)后,通过该接口调用设备方法(如open)。例如,当上层(如CameraService)需要打开设备时,会通过ICameraDevice::open方法触发Camera3DeviceImpl::open的执行,从而进入CameraDevice3Impl.cpp的逻辑。 CameraDevice3SessionImpl.cpp 在open函数中调用onOpenLocked(callback) PipelineModelImpl.cpp 调用mHalDeviceAdapter的open函数用于初始化DeviceAdapter HalDeviceAdapter.cpp powerOn函数中调用HalSensor::powerOn( ) sensor上完电后对3A进行PowerOn动作 HalSensor.cpp HalSensor::powerOn( ) 拿到开机时search到的sensor后,开始初始化pSeninfDrv,setSensorMclk后,然后通过pSensorDrv->open( )调用到imgsensor_drv.cpp里面的open。 imgsensor_drv.cpp 在pSensorDrv->open( )里会通过featureControl向kernel传递SENSOR_FEATURE_OPEN这个featureid imgsensor.c 拿到imgsensor_drv.cpp传过来的SENSOR_FEATURE_SET_DRIVER 这个featureid 调用到imgsensor_sensor_open()去给对应sensor做上电的动作 imgsensor_sensor_open()>>imgsensor_set_driver()>>imgsensor_check_is_alive() >>imgsensor_hw_power XXXmipiraw_Sensor.c open函数ret = psensor_func->SensorOpen();调用到kd_imgsensor_define.h中的MUINT32(* SensorOpen) (void); 最后会调用到驱动里面的open( )函数来做具体的实操。 弄个讲解这段内容的稿子,并优化细节
最新发布
07-24
<think>好的,我现在需要帮用户整理个关于Android Camera打开流程的讲解稿,并且优化细节。首先,我需要理解用户提供的整个流程,从上层的CameraManager到HAL层,再到驱动层的调用链路。用户已经给出了各个关键类和步骤,我需要将这些步骤串联起来,用更易懂的语言解释,同时补充些关键细节,比如各层的作用、关键接口的功能等。 首先,用户提到的流程从APK层的CameraManager开始,调用openCamera方法,然后进入CameraManager的内部实现,通过Binder与CameraService通信。接下来是CameraService的connectDevice方法,创建CameraDeviceClient实例,并与HAL层建立连接。然后是HAL层的HIDL接口调用,获取ICameraDevice实例,最终到驱动层的传感器上电操作。 我需要分层次讲解,从应用层到框架层(CameraManager、CameraService)、HAL层(HIDL/AIDL接口、Camera3DeviceImpl),最后到驱动层(imgsensor驱动)。每个层次需要说明关键步骤和作用,比如CameraManager如何与CameraService交互,CameraService如何通过Client与HAL通信,HAL如何实例化设备接口,驱动层如何具体操作传感器上电。 需要注意优化细节,比如:CameraManager获取相机特性的作用(如分辨率、硬件能力),CameraDeviceClient的不同类型(根据API和HAL版本),HIDL接口的作用(跨进程通信),Camera3DeviceImpl作为HAL层核心实现类的功能,以及驱动层中featureControl的具体作用(传递控制指令)等。 另外,用户可能希望讲解稿结构清晰,逻辑连贯,所以需要按照调用顺序逐步展开,从上层到下层,每步说明目的和关键操作。同时,需要解释些专业术语,比如Binder、HIDL、HAL等,让听众更容易理解。 现在开始组织内容: 1. 开头引入:Android相机打开流程的重要性,涉及多模块协作。 2. 应用层(APK):使用CameraManager实例调用openCamera,触发后续流程。 3. 框架层(CameraManager.java):获取相机特性,通过Binder与CameraService通信,调用connectDevice。 4. CameraService.cpp:处理连接请求,通过connectHelper创建CameraDeviceClient实例(根据API和HAL版本选择类型),初始化并连接HAL。 5. HAL层(HIDL/AIDL):通过Provider获取ICameraDevice接口实例(Camera3DeviceImpl),处理设备打开、配置等核心操作。 6. 驱动层:从Camera3DeviceImpl到HalDeviceAdapter,再到HalSensor,最终通过imgsensor驱动完成传感器上电。 7. 关键细节补充:各层的作用,关键接口的功能,传感器上电的具体步骤(如设置MCLK、检查传感器是否存活)。 需要确保每个步骤衔接自然,解释清楚每个环节的作用,避免过于技术化的术语,同时保持专业性。最后,检查是否有遗漏的关键步骤,比如CameraDeviceImpl的初始化、Session的创建等,确保流程完整。 现在,根据这些思路整理成讲解稿,并优化细节。 </think>### Android Camera打开流程全解析:从应用层到驱动层的完整链路 在Android系统中,相机的打开是个涉及多模块协作的复杂过程,需要应用层、框架层、HAL层(硬件抽象层)及底层驱动的紧密配合。下面我们将从上层应用调用开始,逐步拆解整个流程的关键步骤与核心逻辑。 #### **、应用层触发:CameraManager启动打开流程** 当APK需要使用相机时,首先会通过`CameraManager`类发起操作。开发者通常的代码逻辑是: ```java // 获取CameraManager实例(通过Context获取) CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); // 调用openCamera打开指定相机(cameraId通常为"0"代表后摄,"1"代表前摄) cameraManager.openCamera(cameraId, cameraStateCallback, backgroundHandler); ``` `openCamera`方法是流程的起点,它会触发框架层系列关键操作: - **步骤1:获取相机特性** 首先调用`getCameraCharacteristics(cameraId)`,获取该相机的核心参数(如支持的分辨率、对焦模式、硬件能力等级等)。这些信息由HAL层提供,是后续配置相机的基础。 - **步骤2:创建CameraDevice实例** 框架层会实例化`CameraDeviceImpl`对象(Android内部实现类),该对象负责与底层相机服务通信。 - **步骤3:通过Binder连接CameraService** 通过`CameraManagerGlobal.get().getCameraService()`获取系统级的`CameraService`接口(跨进程通信通过Binder实现),并调用其`connectDevice`方法,正式进入系统服务层的处理逻辑。 #### **二、框架层核心:CameraService的连接与Client创建** `CameraService`是Android系统管理相机的核心服务,运行在系统进程(通常为`system_server`)。当`connectDevice`被调用后,CameraService会执行以下关键操作: - **步骤1:通过connectHelper创建Client实例** `connectHelper`是个模板函数,负责根据API版本(如API1/API2)和HAL版本(如HAL3)生成具体的Client类。例如: - API1+HAL3 → `CameraClient`(兼容旧版API) - API2+HAL3 → `CameraDeviceClient`(支持Camera2 API的核心Client) 不同Client类的选择决定了后续与HAL层交互的接口规范。 - **步骤2:初始化Client并连接HAL层** Client实例创建后,会调用`initialize()`方法,该方法最终会路由到HAL层的具体实现(如`HidlCamera3Device::initialize()`或`AidlCamera3Device::initialize()`),从而建立框架层与HAL层的通信链路。 #### **三、HAL层:设备接口的获取与核心能力初始化** HAL层是连接框架层与硬件驱动的桥梁,负责将上层指令转换为硬件可识别的操作。以HIDL(硬件接口定义语言)框架为例,关键流程如下: - **步骤1:通过Provider获取设备接口** HAL层的`HidlProviderInfo`类会调用`startDeviceInterface`方法,通过`ICameraProvider`接口的`getCameraDeviceInterface_V3_x`方法,向底层请求获取指定相机的`ICameraDevice`接口实例。该实例由HAL层的`Camera3DeviceImpl`类具体实现(即`Camera3DeviceImpl`是HIDL服务端的核心类)。 - **步骤2:实例化Camera3DeviceImpl** 当HAL层接收到`getCameraDeviceInterface_V3_x`请求时,会根据相机ID(如"0")实例化对应的`Camera3DeviceImpl`对象。该类是HAL层操作相机的核心,负责处理设备打开、配置数据流、控制曝光/对焦等核心功能。 #### **四、驱动层:传感器上电与硬件初始化** HAL层的`Camera3DeviceImpl`完成初始化后,会通过`open`方法触发驱动层的硬件操作,最终目标是让相机传感器(Sensor)上电并准备就绪: - **步骤1:Session创建与Pipeline初始化** `Camera3DeviceImpl`的`open`方法会调用`onOpenLocked`,触发`PipelineModelImpl`的初始化。`PipelineModelImpl`是相机数据流的管理核心,负责协调各处理阶段(如预览、拍照)的数据流。 - **步骤2:HalDeviceAdapter与传感器上电** 通过`mHalDeviceAdapter`的`open`方法,调用`powerOn`函数,依次执行: - **传感器时钟初始化**:通过`HalSensor::powerOn`设置传感器主时钟(MCLK),这是传感器工作的基础。 - **传感器驱动打开**:调用`pSensorDrv->open()`,通过`featureControl`向内核传递`SENSOR_FEATURE_OPEN`指令,触发底层驱动的具体操作。 - **步骤3:内核驱动与传感器硬件交互** 内核层的`imgsensor.c`接收到指令后,调用`imgsensor_sensor_open`函数,完成: - 传感器上电(如给Sensor的VDD、AVDD等电源引脚供电)。 - 传感器存活检查(`imgsensor_check_is_alive`):通过I2C读取传感器寄存器,确认硬件连接正常。 - 最终调用具体传感器驱动(如`XXXmipiraw_Sensor.c`中的`SensorOpen`函数),完成传感器的初始化(如加载校准参数、配置分辨率等)。 #### **总结** 整个相机打开流程从应用层触发,经过框架层的服务协调、HAL层的接口转换,最终落地到驱动层的硬件操作,每步都需要精确协作。理解这流程有助于开发者定位相机异常(如无法打开、花屏),并优化相机启动速度与稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值