Android Q 之MTK代码分析(一)--Camera Hal3 Service

camera hal3 service启动

十分感谢Android 10.0系统启动之init进程-[Android取经之路]https://blog.csdn.net/yiranfeng/article/details/103549394

《Android Q 之MTK代码分析(一)--Camera Hal3 Service》

《Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor》

备忘

文末支持一波,感谢鞠躬

1、Android系统系统简述

1.1 MTK Camera HAL层的框架

大概了解关联部分有camea service、camera provider、camera hal service、 camera device manager、camera device这五部分。

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

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/provider/2.4/CameraProviderImpl.cpp

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/service.cpp

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/CameraDeviceManagerBase.cpp

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3Impl.cpp

1.2 Android框架启动过程 

原文链接:https://blog.csdn.net/yiranfeng/article/details/103549290

Android 系统启动流程:

第一步:手机开机后,引导芯片启动,引导芯片开始从固化在ROM里的预设代码执行,加载引导程序到到RAM,bootloader检查RAM,初始化硬件参数等功能;
第二步:硬件等参数初始化完成后,进入到Kernel层,Kernel层主要加载一些硬件设备驱动,初始化进程管理等操作。在Kernel中首先启动swapper进程(pid=0),用于初始化进程管理、内管管理、加载Driver等操作,再启动kthread进程(pid=2),这些linux系统的内核进程,kthread是所有内核进程的鼻祖;


第三步:Kernel层加载完毕后,硬件设备驱动与HAL层进行交互。初始化进程管理等操作会启动INIT进程 ,这些在Native层中;
第四步:init进程(pid=1,init进程是所有进程的鼻祖,第一个启动)启动后,会启动adbd,logd等用户守护进程,并且会启动servicemanager(binder服务管家)等重要服务,同时孵化出zygote进程,这里属于C++ Framework,代码为C++程序;,CameraHalServer进程就是在这时启动的

各字段的含义

USER 进程当前用户
PID 进程ID
PPID 父进程ID
VSIZE 进程的虚拟内存大小,以KB为单位
RSS 实际占用的内存大小,以KB为单位
WCHAN 进程正在睡眠的内核函数名称;该函数的名称是从/root/system.map文件中获得的。
PC Program Counter
NAME 进程状态及名称

第五步:zygote进程是由init进程解析init.rc文件后fork生成,它会加载虚拟机,启动System Server(zygote孵化的第一个进程);System Server负责启动和管理整个Java Framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务;
第六步:zygote同时会启动相关的APP进程,它启动的第一个APP进程为Launcher,然后启动Email,SMS等进程,所有的APP进程都有zygote fork生成。

1.3 Init进程 启动

start_kernel()->rest_init()-kernel_thread(kernel_init)->kernel_init(),如图所示init进程就这样启动

init.rc有两个,使用场景不一样,分别位于:
./system/core/rootdir/init.rc       //一个是正常启动用到的.
./bootable/recovery/etc/init.rc   //一个是刷机用到的,也就是进入recorvery模式

1.4 rc文件加载

        在SecondStageMain()->LoadBootScripts()

 解析init.rc等文件,建立rc文件的action 、service,启动其他进程
     */
    ActionManager& am = ActionManager::GetInstance();
    ServiceList& sm = ServiceList::GetInstance();
 
    LoadBootScripts(am, sm);

Android7.0后,init.rc进行了拆分,每个服务都有自己的rc文件,他们基本上都被加载到/system/etc/init,/vendor/etc/init, /odm/etc/init等目录,等init.rc解析完成后,会来解析这些目录中的rc文件,用来执行相关的动作

因为camera hal server 是因为用rc文件文件启动,接下来分析什么rc文件?

2、rc文件简介

android rc文件分析

具体分析在上面的链接中,现在简单分析下上图rc提到中的语法

service关键字声明了你要定义一个service,而servicehalserver就是这个service的名字,至于后面的目录则是这个service对应的可执行文件在系统中的位置。注意:这里是说在系统中的位置,也就是在开发板运行你的Android源码编译的系统后的目录,而不是源码的目录。本文位置在vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/下

定义为核心service,当main服务启动时,这个camerahalserver启动。

class 设置class name
user 用户归属
group 组归属
ioprio io调度优先级
capability 能力,也就是系统对进程的一种权限控制。
writepid 当fork一个子进程时,写子进程的pid到一个给定的文件。是给cgroup/cpuset使用

rc文件中使用Init进程启动camerahalserver,意思就是说在init进程中camerahalserver.rc文件如何加载以至于启动hal服务

3、camera hal service启动

下图是mt6873 Camera Server Init时序图(https://www.jianshu.com/p/22714702b7f2),其实和mt6765差不多,这块还是来简单疏通一下

当init进程加载camerahalserver.rc文件之后,

CameraHalService和Camera Hal Server.rc文件:

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/service.cpp

vendor/mediatek/proprietary/hardware/mtkcam/main/hal/service/camerahalserver.rc

这里简单说下 Camera Service 文件和cameraserver.rc文件

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

frameworks/av/camera/cameraserver/cameraserver.rc

在main函数中,先分析signal()的功用,见Signal ()函数用法和总结。从下图可以看到,signal函数在这块没有实际意义。继续溜代码...

1、Camera Hal Service通过registerPassthroughServiceImplementation()函数来向Camera Provider发起调用注册

main()中最后是joinRpcThreadpool(); // joinRpcThreadpool() 其实就是把主线程也放入线程池中等待请求,防止这个进程退出

2、LegacySupport.h

在这里面做两件事:1、获取ICameraProvider接口类对象 2、将CameraProvider注册到ServiceManager

本地代码没有找到CameraProviderAll.cpp这个文件的Interface:: getService(),在这块就不继续贴图片。但是还是要Init过程的逻辑搞清楚。

3、“CameraProviderAll.cpp”这块有Interface:: getService()的实现

4、“mtkcam3.instance.cpp”也找不见。主要做的是创建CameraDeviceManager、Provider

5、“mtkcam3.instance.cpp” 主要做serarch sensor、new IMetadataProvider、createVirtualCameraDevice()、CameraDevice3、 CameraDevice3Session

6、“CameraProviderImpl.cpp”创建CameraProvider实例

7、“CameraProviderAll.cpp”调用LegacySupport.h中的registerAsService(

8、ServiceManagement.cpp

将provider以服务形式注册到HWServiceManager中,之后createCameraDevice3Session可以通过getService来获取该服务。

4、CameraService和CameraHalService之间联系

 

CameraService和Camerahalservice之间还有CameraProviderManagerICameraProvider

我们都知道CameraService服务开始于:

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

CameraService::CameraService(){
    
    
ALOGI("CameraService started (pid=%d)", getpid());
}

-->

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

void CameraService::onFirstRef(){
    
    
ALOGI("CameraService process starting");
res = enumerateProviders();
}

-->

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

status_t CameraService::enumerateProviders() {
    
    
mCameraProviderManager = new CameraProviderManager();
res = mCameraProviderManager->initialize(this);
deviceIds = mCameraProviderManager->getCameraDeviceIds();     //这块回去获取device Id
}

-->

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

status_t CameraProviderManager::ProviderInfo::initialize(
          sp<provider::V2_4::ICameraProvider>& interface,
          hardware::hidl_bitfield<provider::V2_5::DeviceState> currentDeviceState) {

      ALOGI("Connecting to new camera provider: %s, isRemote? %d",
      hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](
      mIsRemote = interface->isRemote();
      // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
      // before setCallback returns. setCallback must be called after addDevice so that
      // the physical camera status callback can look up available regular
      // cameras.
      hardware::Return<Status> st = interface->setCallback(this);//这块就把ICameraProvider接口注册回调

 }

-->

3、hardware/interfaces/camera/provider/2.4/ICameraProvider.hal

interface ICameraProvider {
    setCallback(ICameraProviderCallback callback) generates (Status status);
    getVendorTags() generates (Status status, vec<VendorTagSection> sections);
    getCameraIdList()
    generates (Status status, vec<string> cameraDeviceNames);   
    isSetTorchModeSupported() generates (Status status, bool support);
    getCameraDeviceInterface_V1_x(string cameraDeviceName) generates
            (Status status,
             [email protected]::ICameraDevice device);
    getCameraDeviceInterface_V3_x(string cameraDeviceName) generates
            (Status status,
             [email protected]::ICameraDevice device);

};

Camera Provider提供一个回调接口ICameraProvider,给Hal Provider来通知Framework异步相机事件,到这块Framework“接通”HAL

下面这块是HAL“接通” Framework,

1、定义一个接口ICameraDevice

hardware/interfaces/camera/device/3.2/ICameraDevice.hal

interface ICameraDevice {
    getResourceCost() generates (Status status, CameraResourceCost resourceCost);
    getCameraCharacteristics() generates
    setTorchMode(TorchMode mode) generates (Status status);
    open(ICameraDeviceCallback callback) generates
            (Status status, ICameraDeviceSession session);
    dumpState(handle fd);

};

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

在MTK文档中Framework层在这块是以关联的形式“连接”ICameraDevice

#include <android/hardware/camera/device/3.5/ICameraDevice.h>

3、vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3Impl.cpp

Hal层继承ICameraDevice接口

CameraDevice3Impl::
CameraDevice3Impl(
    ICameraDeviceManager* deviceManager,
    IMetadataProvider* metadataProvider,
    std::map<uint32_t, ::android::sp<IMetadataProvider>>const& physicalMetadataProviders,
    char const* deviceType,
    int32_t instanceId,
    int32_t virtualInstanceId
)
    : ICameraDevice()             //继承ICameraDevice接口
    , mLogLevel(0)
    , mDeviceManager(deviceManager)
    , mStaticDeviceInfo(nullptr)
    , mMetadataProvider(metadataProvider)
    , mPhysicalMetadataProviders(physicalMetadataProviders)
    , mMetadataConverter(IMetadataConverter::createInstance(IDefaultMetadataTagSet::singleton()->getTagSet()))
{
}

举个实现的例子

Return<void>
CameraDevice3Impl::
getCameraCharacteristics(getCameraCharacteristics_cb _hidl_cb)
{
    CameraMetadata cameraCharacteristics;
    {
        camera_metadata const* p_camera_metadata = mMetadataProvider->getStaticCharacteristics();
        size_t size = mMetadataConverter->getCameraMetadataSize(p_camera_metadata);
        cameraCharacteristics.setToExternal((uint8_t *)p_camera_metadata, size, false/*shouldOwn*/);
    }

    _hidl_cb(Status::OK, cameraCharacteristics);
    return Void();
}

后面这些去操作camera

5、log

MTK 平台的log需要打开log开关,这个文档MTK_Camera_Introduction有具体介绍。

cameraServer 和camereahalServer服务在开机的时候已经启动,需要kill掉重启

×××××××/ # ps -d | grep camera
cameraserver   4144      1   88020  34736 binder_ioctl_write_read 0 S cameraserver
cameraserver   4145      1 11483128 151420 binder_ioctl_write_read 0 S camerahalserver
u0_a118        4971    504 14389020 108064 SyS_epoll_wait     0 S com.mediatek.camera

开启log之后,打开MTK 的driveronly版本的DebugLoggerUI 抓取log

  

6、结语

    代码熟练度还不够溜,MTK Code细节不够火候,还需继续深入。我会不定期分享,以便查漏补缺,相互学习。奥里给!!!

7、恰饭

如果您觉得有用,感谢老铁请支持一波

猜你喜欢

转载自blog.csdn.net/weixin_38328785/article/details/106720202