安卓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函數的實現位置,該函數的實現位置就是實際與藍牙芯片交互的地方喔!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM