前言
去年正式进入框架组的时候,啥也不会,瞎jb分析了一通 Android N 上面的 Camera 相关流程。其实基本上都是跟着别人的分析日志看代码,然后按照自己的理解记了些笔记而已。
不过当时感觉受益匪浅,并且后来在项目开发、维护的时候,很多相关的内容都派上了用场。
从正式进入项目到现在大概有 10 个月了吧,其中大概有一半时间在 Android N 上填坑,另一半就是填 Android O 上的坑了(虽然这些坑基本上都是自己人挖的)。现在终于感觉自己对 Android Camera 这块的架构也有一定的认识了。
然而,公司业务要往 HAL3 上迁移了,又要重新开始学习 Camera 流程了……
不过现在的我已经有一定的能力,可以自己跟踪流程去分析了。趁此机会,我就从比较简单的 Camera 服务启动流程开始,锻炼锻炼分析代码、抽象出主干思想的功力吧。
Camera 服务启动流程概览
在 Android O 中,系统启动时,就会启动 CameraProvider 服务。它将 Camera HAL 从 cameraserver
进程中分离出来,作为一个独立进程 android.hardware.camera.provider@2.4-service
来控制 HAL。
这两个进程之间通过 HIDL 机制进行通信。
这样的改动源自于 Android O 版本加入的 Treble 机制,它的主要功能(如下图所示)是将 service 与 HAL 隔离,以方便 HAL 部分进行独立升级。这其实和 APP 与 Framework 之间的 Binder 机制类似,通过引入一个进程间通信机制而针对不同层级进行解耦(从 Local call 变成了 Remote call)。
(这个图是部门里的大佬给的…)
如此一来 Camera 服务的启动流程就变得有些复杂了,但是最核心的部分其实没变,最终都要从动态库中获取连接 HAL 的结构,并保存下来以备未来对 Camera 设备进行操作。
这几天跟了一下代码流程,大概总结了一下 cameraserver 与 provider 这两个进程启动、初始化的调用逻辑,如下图。
总体逻辑顺序:
- provider 进程启动,注册;
- cameraserver 进程启动,注册,初始化;
- cameraserver 获取远端 provider(此时实例化 CameraProvider 并初始化)。
上图中,实线箭头是调用关系。左边是 cameraserver 进程中的动作,右边则是 provider 进程中的动作,它们之间通过 ICameraProvider
联系在了一起,而这个东西与 HIDL 相关,我们可以不用关心它的实现方式。
由图可见:
- cameraserver 一侧,
Cameraservice
类依旧是主体。它通过CameraProviderManager
来管理对CameraProvider
的操作。此处初始化的最终目的是连接上 CameraProvider。 - provider 一侧,最终主体是
CameraProvider
。初始化最终目的是得到一个mModule
,通过它可以直接与 HAL 接口定义层进行交互。
至此,我们就能对 Android O 上的 Camera 服务启动流程有一个大致的了解。但由于我个人功力尚浅,目前只能理解到这个地步,还无法轻易抽象出更容易理解的框架,所以图片中的流程还是比较凌乱的,可能需要对照相应代码才能理解。
下面是我分析代码时的一些笔记,有需要可以对照上图中的流程看看。
CameraProvider 的启动与注册
这个服务进程的启动很简单,主要动作是注册该 CameraProvider,以便 CameraServer 启动时能找到它。需要注意的是,此时 CameraProvider 还未实例化与初始化。
Service.cpp
文件位置:hardware\interfaces\camera\provider\2.4\default
看代码:
- 第 6 行:与
/dev/vndbinder
进行某种关联,注释表明 Camera HAL 可能会通过它与其它 vendor 组件进行通信。 - 第 7 行:创建默认为直通模式(passthrough)的 CameraProvider 服务实现。
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);
}
LegacySupport.h
文件路径:system\libhidl\transport\include\hid