安卓10.0蓝牙HIDL的直通式初始化流程
本文仅介绍扼要的流程,没有系统化介绍。
首先从system\bt\hci\src\hci_layer_android.cc文件的函数void hci_initialize() 开始初始化:
void hci_initialize() { LOG_INFO(LOG_TAG, "%s", __func__); btHci = IBluetoothHci::getService(); // If android.hardware.bluetooth* is not found, Bluetooth can not continue. CHECK(btHci != nullptr); auto death_link = btHci->linkToDeath(bluetoothHciDeathRecipient, 0); if (!death_link.isOk()) { LOG_ERROR(LOG_TAG, "%s: Unable to set the death recipient for the Bluetooth HAL", __func__); abort(); } LOG_INFO(LOG_TAG, "%s: IBluetoothHci::getService() returned %p (%s)", __func__, btHci.get(), (btHci->isRemote() ? "remote" : "local")); // Block allows allocation of a variable that might be bypassed by goto. { android::sp<IBluetoothHciCallbacks> callbacks = new BluetoothHciCallbacks(); btHci->initialize(callbacks); } }
从第4行的btHci = IBluetoothHci::getService();可以看到,先从HIDL层获取BluetoothHci的实际服务的接口。IBluetoothHci::getService()的实际实现在生成的文件android\hardware\bluetooth\1.0\BluetoothHciAll.cpp中。具体位置根据不同生成时的配置不用,可以在安卓编译的out目录中查找到该文件。该文件是由hidl-gen将hidl描述文件生成的中间编译c++文件,在编译时生成该文件。接下来看该函数的实现:
1 // static 2 ::android::sp<IBluetoothHci> IBluetoothHci::getService(const std::string &serviceName, const bool getStub) { 3 return ::android::hardware::details::getServiceInternal<BpHwBluetoothHci>(serviceName, true, getStub); 4 }
细心的朋友可能会问,前面hci_layer_android.cc中hci_initialize调用的明明没有参数,而这里的具体函数实现需要2个参数。这是因为该IBluetoothHci::getService的声明中提供了2个默认参数,分别是字符串“default”和布尔变量false。可以发现该实现中,调用了一个模板函数。具体模板函数的实现下面会作介绍。我们先关注BpHwBluetoothHci模板参数,该参数是哪里来的呢?该模板参数同样是由hidl-gen生成的中间c++代码文件android\hardware\bluetooth\1.0\BpHwBluetoothHci.h中定义的。具体实如下内容(需要提醒注意的是,这些代码是由hidl-gen工具生成的):
struct BpHwBluetoothHci : public ::android::hardware::BpInterface<IBluetoothHci>, public ::android::hardware::details::HidlInstrumentor {
explicit BpHwBluetoothHci(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);
typedef IBluetoothHci Pure;
typedef android::hardware::details::bphw_tag _hidl_tag;
virtual bool isRemote() const override { return true; }
// Methods from ::android::hardware::bluetooth::V1_0::IBluetoothHci follow.
static ::android::hardware::Return<void> _hidl_initialize(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::sp<::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks>& callback);
static ::android::hardware::Return<void> _hidl_sendHciCommand(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_vec<uint8_t>& command);
static ::android::hardware::Return<void> _hidl_sendAclData(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_vec<uint8_t>& data);
static ::android::hardware::Return<void> _hidl_sendScoData(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_vec<uint8_t>& data);
static ::android::hardware::Return<void> _hidl_close(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor);
// Methods from ::android::hardware::bluetooth::V1_0::IBluetoothHci follow.
::android::hardware::Return<void> initialize(const ::android::sp<::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks>& callback) override;
::android::hardware::Return<void> sendHciCommand(const ::android::hardware::hidl_vec<uint8_t>& command) override;
::android::hardware::Return<void> sendAclData(const ::android::hardware::hidl_vec<uint8_t>& data) override;
::android::hardware::Return<void> sendScoData(const ::android::hardware::hidl_vec<uint8_t>& data) override;
::android::hardware::Return<void> close() override;
// Methods from ::android::hidl::base::V1_0::IBase follow.
::android::hardware::Return<void> interfaceChain(interfaceChain_cb _hidl_cb) override;
::android::hardware::Return<void> debug(const ::android::hardware::hidl_handle& fd, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& options) override;
::android::hardware::Return<void> interfaceDescriptor(interfaceDescriptor_cb _hidl_cb) override;
::android::hardware::Return<void> getHashChain(getHashChain_cb _hidl_cb) override;
::android::hardware::Return<void> setHALInstrumentation() override;
::android::hardware::Return<bool> linkToDeath(const ::android::sp<::android::hardware::hidl_death_recipient>& recipient, uint64_t cookie) override;
::android::hardware::Return<void> ping() override;
::android::hardware::Return<void> getDebugInfo(getDebugInfo_cb _hidl_cb) override;
::android::hardware::Return<void> notifySyspropsChanged() override;
::android::hardware::Return<bool> unlinkToDeath(const ::android::sp<::android::hardware::hidl_death_recipient>& recipient) override;
private:
std::mutex _hidl_mMutex;
std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>> _hidl_mDeathRecipients;
};
可以看到该实现类似于一个代理,它负责与实际的蓝牙芯片交互,并且对蓝牙协议栈提供服务,蓝牙协议栈与蓝牙芯片之间的收发数据皆经过它。
接下来调用的函数::android::hardware::details::getServiceInternal<BpHwBluetoothHci>(serviceName, true, getStub)其实就在安卓源代码中的lib hidl部分了,在文件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(getOrCreateCachedBinder(base.get()))); } return IType::castFrom(base); }
由以上的描述,可以看到这里调用时,第一个参数instance的值为“default”,第二个参数retry的值为true,第三个参数getStub的值为false。
这里需要分析sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);的调用。该调用直接决定了HIDL具体的实现的位置。IType::descriptor实际上是等同于IBluetoothHci::descriptor,这点比较明显,从上述代码定义就可以看到。具体取值来自
中间文件android\hardware\bluetooth\1.0\BluetoothHciAll.cpp中的const char* IBluetoothHci::descriptor("android.hardware.bluetooth@1.0::IBluetoothHci");
getRawServiceInternal函数决定了是通过绑定式还是通过直通式与直接的蓝牙芯片进行交互。该函数实现较长,在文件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::manager::V1_0::IServiceManager; sp<Waiter> waiter; sp<IServiceManager1_1> sm; Transport transport = Transport::EMPTY; //表示最终使用绑定式还是直通式HIDL。经过下面的判断,最终的值可能是HWBINDER,也可能是PASSTHROUGH。 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); #ifdef ENFORCE_VINTF_MANIFEST #ifdef LIBHIDL_TARGET_DEBUGGABLE const char* env = std::getenv("TREBLE_TESTING_OVERRIDE"); const bool trebleTestingOverride = env && !strcmp(env, "true"); const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride; #else // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE const bool trebleTestingOverride = false; const bool vintfLegacy = false; #endif // LIBHIDL_TARGET_DEBUGGABLE #else // not ENFORCE_VINTF_MANIFEST const char* env = std::getenv("TREBLE_TESTING_OVERRIDE"); const bool trebleTestingOverride = env && !strcmp(env, "true"); const bool vintfLegacy = (transport == Transport::EMPTY); #endif // ENFORCE_VINTF_MANIFEST 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<IServiceManager> pm = getPassthroughServiceManager();//该行仅拿到了一个ServiceManager的接口,不太重要。 if (pm != nullptr) { sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);//这里需要注意了因为sp<IBase>是实际的蓝牙HIDL实现接口,需要研究如果通过pm->get拿到的。 if (!getStub || trebleTestingOverride) { base = wrapPassthrough(base); } return base;//返回直通式接口。我的安卓上面配置了直通式接口,因此接下来介绍直通式的流程。其实绑定式和直通式对安卓蓝牙协议栈来讲是一样的,不同之处已经由ServiceManagement.cpp帮忙屏蔽并且处理掉了。 } } return nullptr; }
接下来分析sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);pm->get(...)调用的函数代码(文件system\libhidl\transport\ServiceManagement.cpp)为:
Return<sp<IBase>> get(const hidl_string& fqName,//该值为“android.hardware.bluetooth@1.0::IBluetoothHci” 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());//查找该so中的sym所代表的函数 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());//这里实际调用到了hardware\interfaces\bluetooth\1.0\default\bluetooth_hci.cc的HIDL_FETCH_IBluetoothHci_impl 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。执行过程中传入了lambda回调。先不理会回调函数,继续深入openLibs:
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 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;//sym值为“HIDL_FETCH_IBluetoothHci” 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; } const char* vtsRootPath = std::getenv("VTS_ROOT_PATH"); if (vtsRootPath && strlen(vtsRootPath) > 0) { const std::string halLibraryPathVtsOverride = std::string(vtsRootPath) + HAL_LIBRARY_PATH_SYSTEM; paths.insert(paths.begin(), halLibraryPathVtsOverride); } } #endif //在paths列表所表示的文件夹中查找对于的so文件。paths列表的值分别是:/odm/lib/hw/;/vendor/lib/hw/;/system/lib/vndk-sp/hw/;/system/lib/hw/
//在上述文件夹中查找文件android.hardware.bluetooth@1.0-impl.so。按照先后顺序查找,如果第一个文件夹查找到了后,那么就不会查找第二个文件夹了。
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__) 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)) {//查找到之后回调openLibs传输的lambda回调。handle为打开该so的句柄;lib为该so的文件名称,也就是android.hardware.bluetooth@1.0-impl.so;sym的值见前面的注释内容。
return;
} } } }
至此,分析完成。可以看到,对于直通式蓝牙HIDL,最终使用了文件hardware\interfaces\bluetooth\1.0\default\bluetooth_hci.cc中的具体实现内容。也就是说,该文件负责实际上地与蓝牙芯片之间的收发数据,以及初始化蓝牙芯片工作等。这里
初始化蓝牙芯片指的是厂商在接受协议栈控制之前需要做的一些初始化工作,比如firmware的下载,蓝牙地址的设定等等。
综合以上判断,如果在你的项目中不知HIDL具体的实现在哪里的话,可以查找HIDL_FETCH_IBluetoothHci函数的实现位置,该函数的实现位置就是实际与蓝牙芯片交互的地方喔!