Camera hal 之 CameraProvider
一、CameraProvider的作用
cameraProvider的主要作用就是向下调用CameraModule,通过CameraModule 来和 Camera driver 交流,向上通过binder会被framework java 层的CameraProviderManager调用,然后CameraProviderManager 最终会被CameraService 使用。
总体来说就是camera hal层的桥梁,承上启下。
二、CameraProvider的启动、初始化
1、启动进程 android.hardware.camera.provider@2.4-service_64
hardware/interfaces/camera/provider/2.4/default/android.hardware.camera.provider@2.4-service_64.rc
service vendor.camera-provider-2-4 /vendor/bin/hw/android.hardware.camera.provider@2.4-service_64
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
bin文件 android.hardware.camera.provider@2.4-service_64 在hardware/interfaces/camera/provider/2.4/default/Android.bp中被编译出来会放在/vendor/bin/hw 目录下面
cc_binary {
name: "android.hardware.camera.provider@2.4-service_64",
defaults: ["hidl_defaults"],
proprietary: true,
relative_install_path: "hw",
srcs: ["service.cpp"],
compile_multilib: "64",
init_rc: ["android.hardware.camera.provider@2.4-service_64.rc"],
shared_libs: [
"libhidlbase",
"libhidltransport",
"libbinder",
"liblog",
"libutils",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.3",
"android.hardware.camera.device@3.4",
"android.hardware.camera.provider@2.4",
"android.hardware.camera.common@1.0",
],
}
通过init进程来执行rc文件,最终会执行bin文件android.hardware.camera.provider@2.4-service_64,
2、注册android.hardware.camera.provider@2.4-service_64到BpHwServiceManager
hardware/interfaces/camera/provider/2.4/default/service.cpp
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);
}
system/libhidl/transport/include/hidl/LegacySupport.h
template<class Interface>
__attribute__((warn_unused_result))
status_t defaultPassthroughServiceImplementation(std::string name,
size_t maxThreads = 1) {
configureRpcThreadpool(maxThreads, true);
/*Interface是 *ICameraProvider , name 是 "legacy/0" */
status_t result = registerPassthroughServiceImplementation<Interface>(name);
if (result != OK) {
return result;
}
joinRpcThreadpool();
return UNKNOWN_ERROR;
}
template<class Interface>
__attribute__((warn_unused_result))
status_t registerPassthroughServiceImplementation(
std::string name = "default") {
/* 这里的Interface 就是ICameraProvider ,所以Interface::getService就是
* 调用 ICameraProvider::getService()
* getStub = ture 时,getservice 以 passthrough 模式打开 HAL 实现
* 因此这个会获得CameraProvider实例化对象(不是binder代理)
*/
sp<Interface> service = Interface::getService(name, true /* getStub */);
if (service == nullptr) {
ALOGE("Could not get passthrough implementation for %s/%s.",
Interface::descriptor, name.c_str());
return EXIT_FAILURE;
}
LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
Interface::descriptor, name.c_str());
status_t status = service->registerAsService(name);
if (status == OK) {
ALOGI("Registration complete for %s/%s.",
Interface::descriptor, name.c_str());
} else {
ALOGE("Could not register service %s/%s (%d).",
Interface::descriptor, name.c_str(), status);
}
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中
// 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中
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 == 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) {
...
/* getStub 为 true,直通模式,将返回CameraProvider实例对象 */
if (getStub || vintfPassthru || vintfLegacy) {
/* 获取ServiceManager代理 */
const sp<IServiceManager> pm = getPassthroughServiceManager();
if (pm != nullptr) {
/* 获取CameraProvider实例对象 */
/* descriptor 是 ,instance 是
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}
return nullptr;
}
struct PassthroughServiceManager : IServiceManager1_1 {
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
/* fqName = android.hardware.camera.provider@2.4::ICameraProvider */
size_t idx = fqName.find("::");
if (idx == std::string::npos ||
idx + strlen("::") + 1 >= fqName.size()) {
LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
return;
}
std::string packageAndVersion = fqName.substr(0, idx);
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};
for (const std::string& path : paths) {
std::vector<std::string> libs = search(path, prefix, ".so");
for (const std::string &lib : libs) {
const std::string fullPath = path + lib;
/* 经过上面的一些添加转换,最终
* fullPath = /vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so
* */
if (path == HAL_LIBRARY_PATH_SYSTEM) {
handle = dlopen(fullPath.c_str(), dlMode);
} else {
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
}
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen " << lib << ": "
<< (error == nullptr ? "unknown error" : error);
continue;
}
/* Lambda表达式代入 */
if (!eachLib(handle, lib, sym)) {
return;
}
}
}
}
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);
/* 返回 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() 函数,该函数返回CameraProvider实例对象保存在ret,
* 所以get()函数将返回 ret
* */
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;
}
}
(*generator)(name.c_str()) 就是 HIDL_FETCH_ICameraProvider(“legacy/0”),
hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp
ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
/* 传递进来的 name 为 legacy/0,而 kLegacyProviderName 定义为 legacy/0 */
if (strcmp(name, kLegacyProviderName) == 0) {
/* 创建CameraProvider对象,构造函数将会调用CameraProvider的initialize() 函数 */
CameraProvider* provider = new CameraProvider();
if (provider == nullptr) {
ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
return nullptr;
}
if (provider->isInitFailed()) {
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;
}
bool CameraProvider::initialize() {
camera_module_t *rawModule;
/* 在通过 hw_get_module() 加载HAL层so:其实是通过获取各种android属性
* (在设备端可以通过 getprop 命令查看当前设备支持的属性),
* 得到HAL so的名称(*variant_keys[]),而后探测、加载该HAL so库,并通
* 过 dlsym() 函数返回标识符为 HAL_MODULE_INFO_SYM_AS_STR 的HMI地址
* (由于各个HAL层代码最终会通过 HAL_MODULE_INFO_SYM 修饰,编译器识别到
* 该符号时将会将标示地址导出为HMI符号,从而在加载HAL so时可以获取)
*/
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 对象 */
/* 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();
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());
...
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);
if (rc != NO_ERROR) {
ALOGE("%s: Camera info query failed!", __func__);
mModule.clear();
return true;
}
...
}
return false; // mInitFailed
}
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
这里的CameraProviderAll.cpp是IcameraProvider.hal经过脚本生成的
::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;
}
/*
* 这里的sm实质是BpHwServiceManager,调用BpHwServiceManager::add来将cameraProvider注册到hwBinder
* 里面
*/
::android::hardware::Return<bool> ret = sm->add(serviceName.c_str(), this);
return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;
}
这里顺便看一下,一个hal文件能生成多少东西
一个ICameraProvider对应的要生成 CameraProviderAll.cpp BpCameraProvider.cpp ICameraProvider.h BnCameraProvider.cpp iHwCameraProvider.h
参考下面的cameraProvider的启动时序图
参考文章:https://blog.csdn.net/weixin_41944449/article/details/99453461