前言
之前准备按照camera APP调用API1/2的接口一点点的写代码流程。本地写了几篇之后发现不把camera server和hal的初始化写完,直接开始写API调用流程的话不太好写。还是从服务的初始化开始写吧。代码流程分析
我就按照自己习惯的学习一个新的模块的思路来写。
先通过ps命令看一下当前camera hal运行的进程叫什么。
cameraserver 946 1 0 S android.hardware.camera.provider@2.4-service_64
从手机运行的进程看,当前运行的camera Hal是android.hardware.camera.provider@2.4-service_64
根据这个名称再到代码里面搜一下,定义在hardware/interfaces/camera/provider/2.4/default/Android.bp中。
cc_binary {
name: "android.hardware.camera.provider@2.4-service_64",
defaults: ["camera_service_defaults"],
compile_multilib: "64",
init_rc: ["android.hardware.camera.provider@2.4-service_64.rc"],
}
使用了android.hardware.camera.provider@2.4-service_64.rc,rc文件没啥好分析的,就是告诉init进程该去哪里以什么方式启动什么进程。
看下rc的内容:
service vendor.camera-provider-2-4 /vendor/bin/hw/android.hardware.camera.provider@2.4-service_64
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 HighPerformance
defaults: [“camera_service_defaults”]编译相关
cc_defaults {
name: "camera_service_defaults",
defaults: ["hidl_defaults"],
proprietary: true,
relative_install_path: "hw",
srcs: ["service.cpp"],
...
从srcs: [“service.cpp”]可以看出,android.hardware.camera.provider@2.4-service_64主要就是用这个cpp编译生成的。再来看看service.cpp。
#ifdef LAZY_SERVICE
const bool kLazyService = true;
#else
const bool kLazyService = false;
#endif
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");
status_t status;
if (kLazyService) {
status = defaultLazyPassthroughServiceImplementation<ICameraProvider>("legacy/0",
/*maxThreads*/ 6);
} else {
status = defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0",
/*maxThreads*/ 6);
}
return status;
}
LAZY_SERVICE的宏不确定是不是被定义了,再回去看看android.bp
cc_binary {
name: "android.hardware.camera.provider@2.4-service-lazy",
overrides: ["android.hardware.camera.provider@2.4-service"],
defaults: ["camera_service_defaults"],
compile_multilib: "32",
init_rc: ["android.hardware.camera.provider@2.4-service-lazy.rc"],
cflags: ["-DLAZY_SERVICE"],
}
cc_binary {
name: "android.hardware.camera.provider@2.4-service-lazy_64",
overrides: ["android.hardware.camera.provider@2.4-service_64"],
defaults: ["camera_service_defaults"],
compile_multilib: "64",
init_rc: ["android.hardware.camera.provider@2.4-service-lazy_64.rc"],
cflags: ["-DLAZY_SERVICE"],
}
只找到了上面两处定义LAZY_SERVICE的地方,所以这里kLazyService 肯定是false了。最终会调用defaultPassthroughServiceImplementation
这就是注册hidl服务,调用到system/libhidl/transport/include/hidl/LegacySupport.h中。
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;
}
调用registerPassthroughServiceImplementation
template <class Interface, class ExpectInterface = Interface>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& name = "default") {
return registerPassthroughServiceImplementation(Interface::descriptor,
ExpectInterface::descriptor, name);
}
调用registerPassthroughServiceImplementation
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& interfaceName, const std::string& expectInterfaceName,
const std::string& serviceName) {
return details::registerPassthroughServiceImplementation(
interfaceName, expectInterfaceName,
[](const sp<IBase>& service, const std::string& name) {
return details::registerAsServiceInternal(service, name);
},
serviceName);
}
调用registerPassthroughServiceImplementation
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& interfaceName, const std::string& expectInterfaceName,
RegisterServiceCb registerServiceCb, const std::string& serviceName) {
sp<IBase> service =
getRawServiceInternal(interfaceName, serviceName, true /*retry*/, true /*getStub*/);
if (service == nullptr) {
ALOGE("Could not get passthrough implementation for %s/%s.", interfaceName.c_str(),
serviceName.c_str());
return EXIT_FAILURE;
}
if (service->isRemote()) {
ALOGE("Implementation of %s/%s is remote!", interfaceName.c_str(), serviceName.c_str());
return EXIT_FAILURE;
}
std::string actualName;
Return<void> result = service->interfaceDescriptor(
[&actualName](const hidl_string& descriptor) { actualName = descriptor; });
if (!result.isOk()) {
ALOGE("Error retrieving interface name from %s/%s: %s", interfaceName.c_str(),
serviceName.c_str(), result.description().c_str());
return EXIT_FAILURE;
}
if (actualName != expectInterfaceName) {
ALOGE("Implementation of %s/%s is actually %s, not a %s!", interfaceName.c_str(),
serviceName.c_str(), actualName.c_str(), expectInterfaceName.c_str());
return EXIT_FAILURE;
}
status_t status = registerServiceCb(service, serviceName);
if (status == OK) {
ALOGI("Registration complete for %s/%s.", interfaceName.c_str(), serviceName.c_str());
} else {
ALOGE("Could not register service %s/%s (%d).", interfaceName.c_str(), serviceName.c_str(),
status);
}
return status;
}
调用getRawServiceInternal
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance,
bool retry, bool getStub) {
using Transport = IServiceManager1_0::Transport;
sp<Waiter> waiter;
sp<IServiceManager1_1> sm;
Transport transport = Transport::EMPTY;
if (kIsRecovery) {
transport = Transport::PASSTHROUGH;
} else {
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 = transportRet;
}
const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
const bool trebleTestingOverride = isTrebleTestingOverride();
const bool allowLegacy = !kEnforceVintfManifest || (trebleTestingOverride && kDebuggable);
const bool vintfLegacy = (transport == Transport::EMPTY) && allowLegacy;
if (!kEnforceVintfManifest) {
ALOGE("getService: Potential race detected. The VINTF manifest is not being enforced. If "
"a HAL server has a delay in starting and it is not in the manifest, it will not be "
"retrieved. Please make sure all HALs on this device are in the VINTF manifest and "
"enable PRODUCT_ENFORCE_VINTF_MANIFEST on this device (this is also enabled by "
"PRODUCT_FULL_TREBLE). PRODUCT_ENFORCE_VINTF_MANIFEST will ensure that no race "
"condition is possible here.");
sleep(1);
}
for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
if (waiter == nullptr && tries > 0) {
waiter = new Waiter(descriptor, instance, sm);
}
if (waiter != nullptr) {
waiter->reset(); // don't reorder this -- see comments on reset()
}
Return<sp<IBase>> ret = sm->get(descriptor, instance);
if (!ret.isOk()) {
ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
ret.description().c_str(), descriptor.c_str(), instance.c_str());
break;
}
sp<IBase> base = ret;
if (base != nullptr) {
Return<bool> canCastRet =
details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
if (canCastRet.isOk() && canCastRet) {
if (waiter != nullptr) {
waiter->done();
}
return base; // still needs to be wrapped by Bp class.
}
if (!handleCastError(canCastRet, descriptor, instance)) break;
}
// In case of legacy or we were not asked to retry, don't.
if (vintfLegacy || !retry) break;
if (waiter != nullptr) {
ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
waiter->wait(true /* timeout */);
}
}
if (waiter != nullptr) {
waiter->done();
}
if (getStub || vintfPassthru || vintfLegacy) {
const sp<IServiceManager1_0> pm = getPassthroughServiceManager();
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}
return nullptr;
}
因为getStub是true,所以会调用IServiceManager1_0的get
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());
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;
}
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;
}
openLibs的实现:
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("::");
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("::"));
const std::string prefix = packageAndVersion + "-impl";
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,
#ifndef __ANDROID_VNDK__
HAL_LIBRARY_PATH_SYSTEM,
#endif
};
#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
if (trebleTestingOverride) {
// Load HAL implementations that are statically linked
handle = dlopen(nullptr, dlMode);
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen self: "
<< (error == nullptr ? "unknown error" : error);
} else if (!eachLib(handle, "SELF", sym)) {
return;
}
}
#endif
for (const std::string& path : paths) {
std::vector<std::string> libs = findFiles(path, prefix, ".so");
for (const std::string &lib : libs) {
const std::string fullPath = path + lib;
if (kIsRecovery || path == HAL_LIBRARY_PATH_SYSTEM) {
handle = dlopen(fullPath.c_str(), dlMode);
} else {
#if !defined(__ANDROID_RECOVERY__) && defined(__ANDROID__)
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
#endif
}
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen " << lib << ": "
<< (error == nullptr ? "unknown error" : error);
continue;
}
if (!eachLib(handle, lib, sym)) {
return;
}
}
}
}
openLibs作用就是在这些目录下查找带-impl的so,查找的路径如下:
#define HAL_LIBRARY_PATH_SYSTEM_64BIT "/system/lib64/hw/"
#define HAL_LIBRARY_PATH_VNDK_SP_64BIT_FOR_VERSION "/apex/com.android.vndk.v%s/lib64/hw/"
#define HAL_LIBRARY_PATH_VENDOR_64BIT "/vendor/lib64/hw/"
#define HAL_LIBRARY_PATH_ODM_64BIT "/odm/lib64/hw/"
#define HAL_LIBRARY_PATH_SYSTEM_32BIT "/system/lib/hw/"
#define HAL_LIBRARY_PATH_VNDK_SP_32BIT_FOR_VERSION "/apex/com.android.vndk.v%s/lib/hw/"
#define HAL_LIBRARY_PATH_VENDOR_32BIT "/vendor/lib/hw/"
#define HAL_LIBRARY_PATH_ODM_32BIT "/odm/lib/hw/"
#if defined(__LP64__)
#define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_64BIT
#define HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION HAL_LIBRARY_PATH_VNDK_SP_64BIT_FOR_VERSION
#define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_64BIT
#define HAL_LIBRARY_PATH_ODM HAL_LIBRARY_PATH_ODM_64BIT
#else
#define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_32BIT
#define HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION HAL_LIBRARY_PATH_VNDK_SP_32BIT_FOR_VERSION
#define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_32BIT
#define HAL_LIBRARY_PATH_ODM HAL_LIBRARY_PATH_ODM_32BIT
#endif
最终在/vendor/lib64/hw目录下找到android.hardware.camera.provider@2.4-impl.so,然后通过dlopen打开他,通过dlsym打开HIDL_FETCH_ICameraProvider。
看一下android.hardware.camera.provider@2.4-impl.so的bp文件:
cc_library_shared {
name: "android.hardware.camera.provider@2.4-impl",
defaults: ["hidl_defaults"],
proprietary: true,
relative_install_path: "hw",
srcs: ["CameraProvider_2_4.cpp"],
...
relative_install_path: "hw"决定了android.hardware.camera.provider@2.4-impl.so存放的路径,编译so主要用了CameraProvider_2_4.cpp,在这个文件里面就看到了上面的HIDL_FETCH_ICameraProvider函数。
ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
using namespace android::hardware::camera::provider::V2_4::implementation;
ICameraProvider* provider = nullptr;
if (strcmp(name, kLegacyProviderName) == 0) {
provider = getProviderImpl<LegacyCameraProviderImpl_2_4>();
} else if (strcmp(name, kExternalProviderName) == 0) {
provider = getProviderImpl<ExternalCameraProviderImpl_2_4>();
} else {
ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
}
return provider;
}
因为const char *kLegacyProviderName = “legacy/0”;所以会走provider = getProviderImpl<LegacyCameraProviderImpl_2_4>();这个分支,再看getProviderImpl的实现:
template<typename IMPL>
CameraProvider<IMPL>* getProviderImpl() {
CameraProvider<IMPL> *provider = new CameraProvider<IMPL>();
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;
}
所以最终返回的是一个CameraProvider对象。到这一步先不要继续往下看了,先回头看一下最开始注册hidl服务的地方。registerPassthroughServiceImplementation函数获取到了CameraProvider对象。
在registerPassthroughServiceImplementation中,拿到CameraProvider之后,根据hidl编译生成的文件,调用interfaceDescriptor获取descriptor。
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
const char* ICameraProvider::descriptor("android.hardware.camera.provider@2.4::ICameraProvider");
::android::hardware::Return<void> ICameraProvider::interfaceDescriptor(interfaceDescriptor_cb _hidl_cb){
_hidl_cb(::android::hardware::camera::provider::V2_4::ICameraProvider::descriptor);
return ::android::hardware::Void();
}
然后用descriptor和defaultPassthroughServiceImplementation的ICameraProvider::descriptor去对比,这只是一个校验。然后再去调用registerServiceCb,而registerServiceCb其实是registerPassthroughServiceImplementation中的lambda表达式:
[](const sp<IBase>& service, const std::string& name) {
return details::registerAsServiceInternal(service, name);
},
所以还是要看registerAsServiceInternal的实现:
status_t registerAsServiceInternal(const sp<IBase>& service, const std::string& name) {
if (service == nullptr) {
return UNEXPECTED_NULL;
}
sp<IServiceManager1_2> sm = defaultServiceManager1_2();
if (sm == nullptr) {
return INVALID_OPERATION;
}
const std::string descriptor = getDescriptor(service.get());
if (kEnforceVintfManifest && !isTrebleTestingOverride()) {
using Transport = IServiceManager1_0::Transport;
Transport transport = sm->getTransport(descriptor, name);
if (transport != Transport::HWBINDER) {
LOG(ERROR) << "Service " << descriptor << "/" << name
<< " must be in VINTF manifest in order to register/get.";
return UNKNOWN_ERROR;
}
}
bool registered = false;
Return<void> ret = service->interfaceChain([&](const auto& chain) {
registered = sm->addWithChain(name.c_str(), service, chain).withDefault(false);
});
if (!ret.isOk()) {
LOG(ERROR) << "Could not retrieve interface chain: " << ret.description();
}
if (registered) {
onRegistrationImpl(descriptor, name);
}
return registered ? OK : UNKNOWN_ERROR;
}
其实到这里已经没啥好说的了,剩下的就是完成注册,和camera本身没啥关系了。
总结
这一篇其实只是说了camera provider的main函数而已,本来准备一篇写完,但是越写越长。。。所以还是分开来写吧,最终准备写到高通平台的camera Hal初始化结束为止。