CameraProvider进程中hidl文件
HIDL文件 | 服务端 | 客户端 | BinderName |
---|---|---|---|
ICameraProvider.hidl | CameraProvider进程(CameraProvider.cpp) | CameraService进程中使用(CameraProviderManager:: ProviderInfo) | legacy/0 |
ICameraDevice.hidl | CameraProvder进程中(CameraDevice.cpp) | CameraService进程中使用 | 匿名Binder |
ICameraDeviceCallback.hal | CameraService进程 | CameraProvider进程中CameraDevice.cpp在open()函数中作为参数传递进来 | 进程间的回调 |
ICameraDeviceSession.hal | CameraProvider进程 CameraDeviceSession.cpp | 在CameraService进程打开摄像头流程中CameraProviderManager::openSession获取 | 匿名Binder |
type.hal | CameraProvider进程 |
CameraProvider进程启动时序图
CameraProvider 进程类图(后续会更新)
CameraProvider进程的启动流程
1、CameraProvider是Camera的Hal层程序(android.hardware.camera.provider@2.4-service )。这是一个独立的进程,它在系统启动的时候就会启动。它通过HIDL机制来和native层的CameraService进程进行通信。
它的启动由rc文件控制
//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
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
1.程序的入口Service.cpp
#define LOG_TAG "android.hardware.camera.provider@2.4-service"
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <hidl/LegacySupport.h>
#include <binder/ProcessState.h>
using android::hardware::camera::provider::V2_4::ICameraProvider;
using android::hardware::defaultPassthroughServiceImplementation;
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");
// 在LegacySupport.h中defaultPassthroughServiceImplementation为模板类函数,将会通过 sp<ICameraProvider> service =
// ICameraProvider::getService(name, true /* getStub */) 获取 CameraProvider 实例化对象,以上操作,将会进入 CameraProviderAll.cpp。
return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0", /*maxThreads*/ 6);
}
这里ICameraProvider.hal 会生成 ICameraProvider.h BpHwCameraProvider.h BnHwCameraProvider.h以及CameraProviderAll.cpp文件。 其中CameraProviderAll.cpp是上面上个头文件的具体内容。
然后这里的defaultPassthroughServiceImplementation()是模板函数,会调用到CameraProviderAll.cpp里面(这里使用的是HIDL直通式,所以会调用到ICameraProvider对应的CameraProviderALL.cpp中的getService()中,这个相当于是一种固定模式)
#CameraProviderAll.cpp:
//这里传递过来的 serviceName--"legacy/0" getStub--true (defaultPassthroughServiceImplementation()过来的流程)
::android::sp<ICameraProvider> ICameraProvider::getService(const std::string &serviceName, const bool getStub) {
return ::android::hardware::details::getServiceInternal<BpHwCameraProvider>(serviceName, true, getStub);
}
-------------------------------------------------------------------------------------------------------------------------------
# system/libhidl/transport/include/hidl/HidlTransportSupport.h
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>>
// instatnce 这里是传递来的 "legacy/0" 或者 "external/0" retry--true getStub--false
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
using ::android::hidl::base::V1_0::IBase;
//IType::descriptor --- ICameraProvider::descriptor("android.hardware.camera.provider@2.4::ICameraProvider")
sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
if (base == nullptr) {
return nullptr;
}
if (base->isRemote()) {
// getRawServiceInternal guarantees we get the proper class
return sp<IType>(new BpType(toBinder<IBase>(base)));
}
return IType::castFrom(base);
}
---------------------------------------------------------------------------------------------------------------------------------------------
# system/libhidl/transport/Servicemanagement.cpp
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();
if (sm == nullptr) {
ALOGE("getService: defaultServiceManager() is null");
return nullptr;
}
Return<Transport> transportRet = sm->getTransport(descriptor, instance);
if (!transportRet.isOk()) {
ALOGE("getService: defaultServiceManager()->getTransport returns %s", transportRet.description().c_str());
return nullptr;
}
Transport transport = transportRet;
const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
、、、、、、
//此处省略的部分代码 主要是 getStub为false的情况 因为CameraProvider的启动流程中的getStub的值为true所以暂不分析
if (getStub || vintfPassthru || vintfLegacy) {
const sp<IServiceManager> pm = getPassthroughServiceManager(); //获取HIDL直通式服务管理对象
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr); //然后调用到了该服务对象中的get函数
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}
return nullptr;
}
--------------------------------------------------------------------------------------------------------------------------------------------
# 上面的pm->get(descriptor, instance)会调用到如下函数
# system/libhidl/transport/Servicemanagement.cpp
//这里的fqName--android.hardware.camera.provider@2.4::ICameraProvider name-- legacy/0
Return<sp<IBase>> get(const hidl_string& fqName,const hidl_string& name) override {
sp<IBase> ret = nullptr;
//此处为Lambda表达式,简单理解为函数指针即可,先执行 openLibs() 其中第一个参数就是fqName,第二个参数是回调函数。
// 回调函数中的 handle--dlopen()的返回值 lib--android.hardware.camera.provider@2.4-impl.so sym--HIDL_FETCH_ICameraProvider
openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
//下面是回调函数的内部逻辑
// 声明一个函数
IBase* (*generator)(const char* name);
//返回 HIDL_FETCH_ICameraProvider() 函数对应的函数地址作为上面声明的函数的具体内容
*(void **)(&generator) = dlsym(handle, sym.c_str());
if(!generator) {
const char* error = dlerror();
LOG(ERROR) << "Passthrough lookup opened " << lib<< " but could not find symbol " << sym << ": "<< (error == nullptr ? "unknown error" : error);
dlclose(handle);
return true;
}
// 执行HIDL_FETCH_ICameraProvider()函数 ret作为返回值 其中ret为ICameraProvider对象
ret = (*generator)(name.c_str());
if (ret == nullptr) {
dlclose(handle);
return true; // this module doesn't provide this instance name
}
// Actual fqname might be a subclass.
// This assumption is tested in vts_treble_vintf_test
using ::android::hardware::details::getDescriptor;
std::string actualFqName = getDescriptor(ret.get());
CHECK(actualFqName.size() > 0);
registerReference(actualFqName, name); //进行服务端的注册,这一块暂时不做深入解析
return false;
});
return ret;
}
2、HIDL直通式后会进入到CameraProvider.cpp里面
上面HIDL相关的代码执行完成后会调用到CameraProvider对象里面的HIDL_FETCH_ICameraProvider()函数。在这个函数里面的参数name 的值就是之前的程序入口处传递来的 "legacy/0" 。接下来我们继续走到了CameraProvider.cpp里面看看。
ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) { //这里name "legacy/0"
if (strcmp(name, kLegacyProviderName) == 0) { //kLegacyProviderName是一个值为 "legacy/0"的常量
//调用待构造函数 创建对象 构造函数里面会调用到内部的initialize()函数来初始化
//并将初始化的结果保存到mInitFailed的全局变量中
CameraProvider* provider = new CameraProvider();
if (provider == nullptr) {
ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
return nullptr;
}
//
if (provider->isInitFailed()) { //这里就是获取的mInitFailed
ALOGE("%s: camera provider init failed!", __FUNCTION__);
delete provider;
return nullptr;
}
return provider;
} else if (strcmp(name, kExternalProviderName) == 0) {
ExternalCameraProvider* provider = new ExternalCameraProvider();
return provider;
}
ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
return nullptr;
}
3、CameraProvider的构造函数和初始化函数--initialize()
然后调用到了CameraProvider的构造函数,在构造函数里面只有一句代码: mInitFailed = initialize() 这样就会调用到内部的initialize()函数,进行初始化,并将初始化结果存储到全局变量mInitFailed(标识是否已经初始化了)。接下来我们看看initialize()函数主要是做什么:
CameraProvider::CameraProvider() :
camera_module_callbacks_t({sCameraDeviceStatusChange,
sTorchModeStatusChange}) {
mInitFailed = initialize();
}
--------------------------------------------------------------------------------------------------------------------------------------------------
bool CameraProvider::initialize() {
camera_module_t *rawModule; //这里的camera_module_t 是一个结构体,它继承了 hw_module_t的结构体。这里就是硬件抽象的基本形式了。
//加载对应的so库(camera.default.so) 给camera_module_t对象赋值
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,(const hw_module_t **)&rawModule);
if (err < 0) {
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
return true;
}
// rawModule 将指向 HAL 中的 camera_module_t 类型结构体
// 此时,CameraProvider 与 camera HAL 绑定成功,可以通过CameraProvider操作camera HAL
// 创建了一个CameraModule.cpp:android/hardware/interfaces/camera/common/1.0/default对象
// 并将该对象赋值给全局变量mModule保存起来(这里provider调用mModule对象然后调用到CameraModule
// 内部的camera_module_t来操作cameraHAL)
mModule = new CameraModule(rawModule);
// init()里面会调用 cameraHAL的init()函数,然后会获取camera number 并存放在CameraModule中的mCameraInfoMap 里面
err = mModule->init();
if (err != OK) {
ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
mModule.clear();
return true;
}
ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
// Setup vendor tags here so HAL can setup vendor keys in camera characteristics
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
if (!setUpVendorTags()) {
ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
}
// 这里是设置camera_module_callbacks_t的回调,会在当前对象接收这些回调传递的数据
err = mModule->setCallbacks(this);
if (err != OK) {
ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
mModule.clear();
return true;
}
// 从系统属性中获取HAL3的 minor的值
mPreferredHal3MinorVersion =property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3);
ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
switch(mPreferredHal3MinorVersion) {
case 2:
case 3:
// OK
break;
default:
ALOGW("Unknown minor camera device HAL version %d in property "
"'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3", mPreferredHal3MinorVersion);
mPreferredHal3MinorVersion = 3;
}
// 获取CameraModule中存放的摄像头数量信息
mNumberOfLegacyCameras = mModule->getNumberOfCameras();
for (int i = 0; i < mNumberOfLegacyCameras; i++) {
struct camera_info info;
auto rc = mModule->getCameraInfo(i, &info);//获取摄像头的基本属性信息
if (rc != NO_ERROR) {
ALOGE("%s: Camera info query failed!", __func__);
mModule.clear();
return true;
}
if (checkCameraVersion(i, info) != OK) {
ALOGE("%s: Camera version check failed!", __func__);
mModule.clear();
return true;
}
char cameraId[kMaxCameraIdLen];
snprintf(cameraId, sizeof(cameraId), "%d", i);
std::string cameraIdStr(cameraId);
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
addDeviceNames(i);
}
return false; // mInitFailed
}
CameraProvider::initialize()中首先就是会调用hw_get_module()(这里会接触到一些Android硬件抽象化的一些基础知识),最终会调用到hardware.c中的load()函数里面主要是加载so库(这个一般是厂家提供的对摄像头具体操作的封装,也就是对camera_module中的一些方法的具体实现)。
通过hw_get_module() 会得到rawModule对象(可以通过这个rawModule对摄像头进行一些操作)。然后将rawModule传递到CameraModule里面保存(CameraModule::mModule)起来,然后会调用到上面的camera_module_t中的init()函数。
mModule->setCallbacks(this)会将camera_module_callbacks_t中的函数回调到当前对象CameraProvider中
下面是涉及到的一些结构体的代码:
typedef struct camera_module_callbacks {
void (*camera_device_status_change)(const struct camera_module_callbacks*,int camera_id, int new_status);
void (*torch_mode_status_change)(const struct camera_module_callbacks*,const char* camera_id,int new_status);
} camera_module_callbacks_t;
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
typedef struct camera_info {
int facing;
int orientation;
uint32_t device_version;
const camera_metadata_t *static_camera_characteristics;
int resource_cost; //当前摄像头使用所消耗的资源
char** conflicting_devices; //标识当前的摄像头和那些摄像头冲突
size_t conflicting_devices_length;
} camera_info_t;
4、mModule->getCameraInfo(i, &info)获取所有摄像头的基本信息并保存在本地
接下来会根据hal层返回的摄像头数量遍历获取每个摄像头的信息,并根据这些信息对每个摄像头进行检查。这个里面会调用到CameraModule::getCameraInfo(int cameraId, struct camera_info *info) ,在CameraModule中主要是通过前面的camera_module_t中的get_camera_info()函数获取摄像头信息最后将摄像头信息保存到 CameraModule::mCameraInfoMap
int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) {
ATRACE_CALL();
Mutex::Autolock lock(mCameraInfoLock);
if (cameraId < 0) {
ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
return -EINVAL;
}
// 获取摄像头信息 如果是API 2.0以前的就不保存
int apiVersion = mModule->common.module_api_version;
if (apiVersion < CAMERA_MODULE_API_VERSION_2_0) {
int ret;
ATRACE_BEGIN("camera_module->get_camera_info");
ret = mModule->get_camera_info(cameraId, info);
// Fill in this so CameraService won't be confused by
// possibly 0 device_version
info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
ATRACE_END();
return ret;
}
//API是2.0以及之后的就需要将摄像头信息保存起来
ssize_t index = mCameraInfoMap.indexOfKey(cameraId);
if (index == NAME_NOT_FOUND) {
// Get camera info from raw module and cache it
camera_info rawInfo, cameraInfo;
ATRACE_BEGIN("camera_module->get_camera_info");
int ret = mModule->get_camera_info(cameraId, &rawInfo);
ATRACE_END();
if (ret != 0) {
return ret;
}
int deviceVersion = rawInfo.device_version;
if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_0) {
// static_camera_characteristics is invalid
*info = rawInfo;
return ret;
}
CameraMetadata m;
m.append(rawInfo.static_camera_characteristics);
deriveCameraCharacteristicsKeys(rawInfo.device_version, m);
cameraInfo = rawInfo;
cameraInfo.static_camera_characteristics = m.release();
index = mCameraInfoMap.add(cameraId, cameraInfo);
}
assert(index != NAME_NOT_FOUND);
// return the cached camera info
*info = mCameraInfoMap[index]; //将摄像头信息返回上个流程的函数进行检查
return OK;
}
5、addDeviceNames(i) 添加摄像头设备到本地
继续CameraProvider::init()函数中的流程的最后一步 addDeviceName(i)。这个会执行到当前对象的
addDeviceNames(int camera_id, CameraDeviceStatus status = CameraDeviceStatus::PRESENT,bool cam_new = false)函数中:
/status的默认值CameraDeviceStatus::PRESENT cam_new的默认值false
void CameraProvider::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new)
{
char cameraId[kMaxCameraIdLen];
snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
std::string cameraIdStr(cameraId);
mCameraIds.add(cameraIdStr); //将camera_id 添加到全局的mCameraIds列表中
//给 mCameraDeviceNames 和 mOpenLegacySupported 这两个集合赋值
mOpenLegacySupported[cameraIdStr] = false;
int deviceVersion = mModule->getDeviceVersion(camera_id);
// pair可以将两个值视为一个单元。容器类别map和multimap就是使用pairs来管理其健值/实值(key/value)的成对元素。可以参考Java中的实体Bean理解
// 无需写出型别, 就可以生成一个pair对象 这里的就是std::pair<std::string, std::string>
auto deviceNamePair = std::make_pair(cameraIdStr, getHidlDeviceName(cameraIdStr, deviceVersion));
mCameraDeviceNames.add(deviceNamePair);
if (cam_new) {
mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
}
if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
mModule->isOpenLegacyDefined()) {
// try open_legacy to see if it actually works
struct hw_device_t* halDev = nullptr;
int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
if (ret == 0) {
mOpenLegacySupported[cameraIdStr] = true;
halDev->close(halDev);
deviceNamePair = std::make_pair(cameraIdStr,
getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
mCameraDeviceNames.add(deviceNamePair);
if (cam_new) {
mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
}
} else if (ret == -EBUSY || ret == -EUSERS) {
// Looks like this provider instance is not initialized during
// system startup and there are other camera users already.
// Not a good sign but not fatal.
ALOGW("%s: open_legacy try failed!", __FUNCTION__);
}
}
}
这个函数主要就是给下面的三个集合赋值
mCameraIds :SortedVector<std::string> 存储的是摄像头的ID 如 : "1" "2"
mCameraDeviceNames :SortedVector<std::pair<std::string, std::string>> 存储的是一个 (cameraId string, hidl device name) pairs 对应ID的摄像头的设备名称
mOpenLegacySupported : std::map<std::string, bool> 存储的是对应ID的摄像头是否支持 HAL1.0(也就是老版本API)
总结:
整体流程就是这样的。
service.cpp ---> ICameraProvider.cpp --> CameraProviderAll.cpp --> HidlTransportSupport.h --> Servicemanagement.cpp --> CameraProvider.cpp --> CameraModule -->CameraHAL.so
发现CameraProvider进程主要有两个作用1、给CameraService进程接口以及主动回调信息给CameraService进程。2、加载厂商提供的CameraHAL的so库,然后获取摄像头信息和操作摄像头。
和CameraService进程通信
所以CameraProvider进程主要是使用了HIDL直通式的当时注册了ICameraProvider.hal中的服务端,这个是用来给CameraService进程来主动调用的。然后这ICameraProvider.hal里面会有setCallback的函数主要是通过回调的形式让CameraService进程接收CameraProvider进程主动发送的消息。
加载CameraHAL的so库
在初始化的时候就通过hw_module_get() 加载对应的so库,获取到camera_module_t对象之后赋值给CameraModule,然后在CameraModule中通过camera_module_t获取摄像头的信息以及后续对摄像头进行操作。