安卓10.0藍牙HIDL的直通式初始化流程
本文僅介紹扼要的流程,沒有系統(tǒng)化介紹。
首先從system\bt\hci\src\hci_layer_android.cc文件的函數(shù)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()的實際實現(xiàn)在生成的文件android\hardware\bluetooth\1.0\BluetoothHciAll.cpp中。具體位置根據(jù)不同生成時的配置不用,可以在安卓編譯的out目錄中查找到該文件。該文件是由hidl-gen將hidl描述文件生成的中間編譯c++文件,在編譯時生成該文件。接下來看該函數(shù)的實現(xiàn):
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調(diào)用的明明沒有參數(shù),而這里的具體函數(shù)實現(xiàn)需要2個參數(shù)。這是因為該IBluetoothHci::getService的聲明中提供了2個默認參數(shù),分別是字符串“default”和布爾變量false。可以發(fā)現(xiàn)該實現(xiàn)中,調(diào)用了一個模板函數(shù)。具體模板函數(shù)的實現(xiàn)下面會作介紹。我們先關注BpHwBluetoothHci模板參數(shù),該參數(shù)是哪里來的呢?該模板參數(shù)同樣是由hidl-gen生成的中間c++代碼文件android\hardware\bluetooth\1.0\BpHwBluetoothHci.h中定義的。具體實如下內(nèi)容(需要提醒注意的是,這些代碼是由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;
};
可以看到該實現(xiàn)類似于一個代理,它負責與實際的藍牙芯片交互,并且對藍牙協(xié)議棧提供服務,藍牙協(xié)議棧與藍牙芯片之間的收發(fā)數(shù)據(jù)皆經(jīng)過它。
接下來調(diào)用的函數(shù)::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);
}
由以上的描述,可以看到這里調(diào)用時,第一個參數(shù)instance的值為“default”,第二個參數(shù)retry的值為true,第三個參數(shù)getStub的值為false。
這里需要分析sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);的調(diào)用。該調(diào)用直接決定了HIDL具體的實現(xiàn)的位置。IType::descriptor實際上是等同于IBluetoothHci::descriptor,這點比較明顯,從上述代碼定義就可以看到。具體取值來自
中間文件android\hardware\bluetooth\1.0\BluetoothHciAll.cpp中的const char* IBluetoothHci::descriptor("android.hardware.bluetooth@1.0::IBluetoothHci");
getRawServiceInternal函數(shù)決定了是通過綁定式還是通過直通式與直接的藍牙芯片進行交互。該函數(shù)實現(xiàn)較長,在文件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。經(jīng)過下面的判斷,最終的值可能是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實現(xiàn)接口,需要研究如果通過pm->get拿到的。
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;//返回直通式接口。我的安卓上面配置了直通式接口,因此接下來介紹直通式的流程。其實綁定式和直通式對安卓藍牙協(xié)議棧來講是一樣的,不同之處已經(jīng)由ServiceManagement.cpp幫忙屏蔽并且處理掉了。
}
}
return nullptr;
}
接下來分析sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);pm->get(...)調(diào)用的函數(shù)代碼(文件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所代表的函數(shù)
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());//這里實際調(diào)用到了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;
}
可以看到,該函數(shù)實際上執(zhí)行了一個函數(shù)內(nèi)容:openLibs。執(zhí)行過程中傳入了lambda回調(diào)。先不理會回調(diào)函數(shù),繼續(xù)深入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)) {//查找到之后回調(diào)openLibs傳輸?shù)膌ambda回調(diào)。handle為打開該so的句柄;lib為該so的文件名稱,也就是android.hardware.bluetooth@1.0-impl.so;sym的值見前面的注釋內(nèi)容。
return;
} } } }
至此,分析完成。可以看到,對于直通式藍牙HIDL,最終使用了文件hardware\interfaces\bluetooth\1.0\default\bluetooth_hci.cc中的具體實現(xiàn)內(nèi)容。也就是說,該文件負責實際上地與藍牙芯片之間的收發(fā)數(shù)據(jù),以及初始化藍牙芯片工作等。這里
初始化藍牙芯片指的是廠商在接受協(xié)議棧控制之前需要做的一些初始化工作,比如firmware的下載,藍牙地址的設定等等。
綜合以上判斷,如果在你的項目中不知HIDL具體的實現(xiàn)在哪里的話,可以查找HIDL_FETCH_IBluetoothHci函數(shù)的實現(xiàn)位置,該函數(shù)的實現(xiàn)位置就是實際與藍牙芯片交互的地方喔!

浙公網(wǎng)安備 33010602011771號