Android R camera Hal启动(上)


前言

之前准备按照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初始化结束为止。


版权声明:本文为weixin_53065050原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。