Android Camera Provider启动流程 (androidP)(HIDL)
Posted we1less
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Camera Provider启动流程 (androidP)(HIDL)相关的知识,希望对你有一定的参考价值。
本篇文章是继续上一篇分析的Android Camera(一) Provider启动流程 (androidP)(HIDL)_we1less的博客-CSDN博客
总结一下:所以在这个流程中
这个路径下的 hardware/interfaces/camera/provider/2.4/default/service.cpp
CameraProviderService的return defaultPassthroughServiceImplementation就是以直通式向ServiceManager中注册一个服务,这个服务是由
/vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so
这个动态库的HIDL_FETCH_ICameraProvider()函数提供的new CameraProvider()
这个CameraProvider在initialize()函数中以同样的方式load进一个动态库,这个动态库的路径为
/vendor/lib/hw/camera.xxxx.so,同时保存在new CameraModule(rawModule);中这样就能利用这个指针访问so中的方法了。
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
路径 system/libhidl/transport/ServiceManagement.cpp
上一篇说到get函数同时上一篇文章中也总结了
fullPath = /vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so
lib = android.hardware.camera.provider@2.4-impl.so
sym = HIDL_FETCH_ICameraProvider
handle = dlopen(fullPath.c_str(), dlMode);
关于dlopen和dlsym函数已经在这里介绍dlopen / dlsym函数(动态链接库)_we1less的博客-CSDN博客
fullPath = /vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so
那么generator就变成了fullPath路径下的so文件中的HIDL_FETCH_ICameraProvider函数得到CameraProvider的实例对象并保存在ret, 所以get()函数将返回 ret
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;
}
HIDL_FETCH_ICameraProvider
路径 hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp
传递进来的 name 为 legacy/0,而 kLegacyProviderName 定义为 legacy/0
创建CameraProvider对象,构造函数将会调用initialize() 函数
关于hw_get_module如何运作的这里给出这几篇篇作为参考【HAL】hw_get_module分析:加载HAL层库,获取camx模块接口_mrhjlong-CSDN博客
Android--hw_get_module解析_Tinghua_M的博客-CSDN博客_hw_get_module
用法可以参考我这篇Android 从上到下写一个例子 本地服务(二)_we1less的博客-CSDN博客
至此,已获得CameraProvider实例对象,最终返回赋值给 registerPassthroughServiceImplementation() 函数中的 service
ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
if (strcmp(name, kLegacyProviderName) == 0) {
CameraProvider* provider = new CameraProvider();
...
return provider;
} else if (strcmp(name, kExternalProviderName) == 0) {
ExternalCameraProvider* provider = new ExternalCameraProvider();
return provider;
}
ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
return nullptr;
}
bool CameraProvider::initialize() {
camera_module_t *rawModule;
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&rawModule);
...
/* rawModule 将指向 HAL 中的 camera_module_t 类型结构体,
* 此时,CameraProvider 与 camera HAL 绑定成功,可以通过
* CameraProvider操作camera HAL
*/
/* 创建 CameraModule 对象 */
/* CameraModule.cpp:android/hardware/interfaces/camera/common/1.0/default */
mModule = new CameraModule(rawModule);
/* mModule->init()主要完成以下操作:
* 1. 当camera HAL的 module_api_version >= CAMERA_MODULE_API_VERSION_2_4,将调用HAL->init()
* 2. 通过 HAL getNumberOfCameras() 获取设置camera数量,并将该参数设置为 mCameraInfoMap 容器的大小
* */
err = mModule->init();
...
err = mModule->setCallbacks(this);
...
mNumberOfLegacyCameras = mModule->getNumberOfCameras();
for (int i = 0; i < mNumberOfLegacyCameras; i++) {
struct camera_info info;
/* 将获取camera信息并保存,其中将有HAL version信息,应用
* 层将会检查HAL层版本信息从而确认调用不同的API实现相机应用
*/
auto rc = mModule->getCameraInfo(i, &info);
...
char cameraId[kMaxCameraIdLen];
snprintf(cameraId, sizeof(cameraId), "%d", i);
std::string cameraIdStr(cameraId);
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
addDeviceNames(i);
}
return false; // mInitFailed
}
CameraModule中的相关函数
路径 hardware/interfaces/camera/common/1.0/default/CameraModule.cpp
mModule->init(); 这个mModule就是camera_module_t结构体对象
camera_module_t 定义在 hardware/libhardware/include/hardware/camera_common.h
CameraModule::CameraModule(camera_module_t *module) {
...
mModule = module;
}
int CameraModule::init() {
ATRACE_CALL();
int res = OK;
if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 &&
mModule->init != NULL) {
ATRACE_BEGIN("camera_module->init");
res = mModule->init();
ATRACE_END();
}
mCameraInfoMap.setCapacity(getNumberOfCameras());
return res;
}
//hardware/libhardware/include/hardware/camera_common.h
#define CAMERA_HARDWARE_MODULE_ID "camera"
typedef struct camera_module {
hw_module_t common;
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id, struct camera_info *info);
int (*set_callbacks)(const camera_module_callbacks_t *callbacks);
void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops);
int (*open_legacy)(const struct hw_module_t* module, const char* id,
uint32_t halVersion, struct hw_device_t** device);
int (*set_torch_mode)(const char* camera_id, bool enabled);
int (*init)();
void* reserved[5];
} camera_module_t;
status_t status = service->registerAsService(name);
路径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
最后将这个service add进去这部分的可以参考这篇Android P HIDL 之 CameraProvider_a185531353的博客-CSDN博客
::android::status_t ICameraProvider::registerAsService(const std::string &serviceName) {
::android::hardware::details::onRegistration("android.hardware.camera.provider@2.4", "ICameraProvider", serviceName);
const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm
= ::android::hardware::defaultServiceManager();
if (sm == nullptr) {
return ::android::INVALID_OPERATION;
}
::android::hardware::Return<bool> ret = sm->add(serviceName.c_str(), this);
return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;
}
以上是关于Android Camera Provider启动流程 (androidP)(HIDL)的主要内容,如果未能解决你的问题,请参考以下文章
Android:权限拒绝:以撤销权限启动 Intent android.permission.CAMERA
Android Camera CameraService启动流程 (androidP)