Android Camera Provider启动流程 (androidP) (HIDL流程)
Posted we1less
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Camera Provider启动流程 (androidP) (HIDL流程)相关的知识,希望对你有一定的参考价值。
本章开始分析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的博客-CSDN博客
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
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
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;
openLibs(fqName, /*接下来的参数这样的写法是一个匿名的函数*/[&](void* handle, const std::string &lib, const std::string &sym) {
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;
constexpr int dlMode = RTLD_LAZY;
void* handle = nullptr;
dlerror(); // clear
static std::string halLibPathVndkSp = android::base::StringPrintf(
HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
std::vector<std::string> paths = {HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR,
halLibPathVndkSp, HAL_LIBRARY_PATH_SYSTEM};
...
}
以上是关于Android Camera Provider启动流程 (androidP) (HIDL流程)的主要内容,如果未能解决你的问题,请参考以下文章
Android:权限拒绝:以撤销权限启动 Intent android.permission.CAMERA
Android Camera CameraService启动流程 (androidP)