在 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的整体架构符合标准的Android架构,即App->FWK->HAL->Kernel,只不过在Android8.0之前HAL的so库是被System分区的服务动态加载的,对于camera hal来说就是被cameraserver进程动态加载,hal和cameraserver进程属于同一个进程。在Android8.0之后,Google加入了Treble机制,将HAL放到了独立的进程当中并且位于vendor分区,System服务通过binder访问vendor分区的HAL进程。对于camera来说就是cameraserver进程通过binder访问Camera HAL进程,后者在开机时通过init启动。这样就可以将厂商的私有实现与Google发布的aosp进行隔离,在系统升级时如果厂商的vendor分区没有修改的话,就可以不升级vendor分区,但是厂商必须按照Google定义的标准接口来实现HAL。
这么一来,看似调用变复杂了,但其实是殊途同归,hal层代码和之前基本上没有变化。具体到camera而言,就是在frameworks层和hal层中间,增加了一个cameraProvider来做为两方联系的桥梁,Camera HAL运行在CameraProvider进程当中。现在的调用流程,再借网上一张图一用:
上面这张图来大致的说一下调用流程:
1.) 开机注册cameraProvider(cameraProvider里会和具体的camera hal层对应起来)
2.) 开机实例化cameraService
3.) 查找并列出所有的cameraProvider(这一步会通过hw_get_module来将camera的hal层代码load出来)
这基本上就是camera开机后从frameworks加载到hal层的路线了。下面再具体一步步来分析。
开机注册cameraProvider
在我们的hardware\interfaces\camera\provider\2.4\default目录下,有一个android.hardware.camera.provider@2.4-service.rc文件
service vendor.camera-provider-2-4 /vendor/bin/hw/android.hardware.camera.provider@2.4-service
interface android.hardware.camera.provider@2.4::ICameraProvider legacy/0
class hal
user cameraserver
group audio camera input drmrpc
ioprio rt 4
capabilities SYS_NICE
task_profiles CameraServiceCapacity MaxPerformance
socket camera_tool stream 0666 cameraserver camera
当开机时,会自动调用这个文件去启动服务camera-provider-2-4,然后它会调用到/vendor/bin/hw/android.hardware.camera.provider@2.4-service这个文件。然后会调到hardware\interfaces\camera\provider\2.4\default\service.cpp
int main()
{
ALOGI("CameraProvider@2.4 legacy service is starting.");
// The camera HAL may communicate to other vendor components via
// /dev/vndbinder
android::ProcessState::initWithDriver("/dev/vndbinder");
// b/166675194
if (property_get_bool("ro.vendor.camera.provider24.disable_mem_init", false)) {
if (mallopt(M_BIONIC_ZERO_INIT, 0) == 0) {
// Note - heap initialization is only present on devices with Scudo.
// Devices with jemalloc don't have heap-init, and thus the mallopt
// will fail. On these devices, you probably just want to remove the
// property.
ALOGE("Disabling heap initialization failed.");
}
}
status_t status;
if (kLazyService) {
status = defaultLazyPassthroughServiceImplementation<ICameraProvider>("legacy/0",
/*maxThreads*/ 6);
} else {
status = defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0",
/*maxThreads*/ 6);
}
return status;
}
然后这里会用hidl的标准接口去将我们的"legacy/0"注册到服务上去。
system\libhidl\transport\include\hidl\LegacySupport.h
/**
* Creates default passthrough service implementation that exits when there are 0 clients. This
* method never returns.
*
* Return value is exit status. 创建默认的直通服务实现,该实现在存在0个客户端时退出。这
方法永远不会返回。
*/
template <class Interface, class ExpectInterface = Interface>
__attribute__((warn_unused_result)) status_t defaultLazyPassthroughServiceImplementation(
const std::string& name, size_t maxThreads = 1) {
configureRpcThreadpool(maxThreads, true);
status_t result =
registerLazyPassthroughServiceImplementation<Interface, ExpectInterface>(name);
if (result != OK) {
return result;
}
joinRpcThreadpool();
return UNKNOWN_ERROR;
}
template <class Interface, class ExpectInterface = Interface>
__attribute__((warn_unused_result)) status_t defaultLazyPassthroughServiceImplementation(
size_t maxThreads = 1) {
return defaultLazyPassthroughServiceImplementation<Interface, ExpectInterface>("default",
maxThreads);
}
/**
* Creates default passthrough service implementation. This method never returns.
*
* Return value is exit status.创建默认的直通服务实现。此方法永远不会返回。
返回值为退出状态。
*/
template <class Interface, class ExpectInterface = Interface>
__attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(
const std::string& name, size_t maxThreads = 1) {
configureRpcThreadpool(maxThreads, true);
status_t result = registerPassthroughServiceImplementation<Interface, ExpectInterface>(name);
if (result != OK) {
return result;
}
joinRpcThreadpool();
return UNKNOWN_ERROR;
}
template <class Interface, class ExpectInterface = Interface>
__attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation