<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

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

       

      posted @ 2020-03-21 21:37  WestMountain  Views(3549)  Comments(0)    收藏  舉報
      主站蜘蛛池模板: 宁海县| 亚洲av色香蕉一区二区三| 成人免费乱码大片a毛片| 久久精品囯产精品亚洲| 亚洲码国产精品高潮在线| 国产香蕉久久精品综合网| 亚洲av无码专区在线亚| 2021国产成人精品久久| 性做久久久久久久| 无码专区 人妻系列 在线| 湄潭县| 国产精品免费AⅤ片在线观看| 亚洲一区二区色情苍井空| 亚洲乱色一区二区三区丝袜 | 无码国产69精品久久久久网站| 日韩中文字幕国产精品| 国产SM重味一区二区三区| 欧美不卡无线在线一二三区观| 那坡县| 国产在线观看免费观看不卡| 国产日韩入口一区二区| 阳朔县| 粉嫩国产一区二区三区在线| 亚洲男女羞羞无遮挡久久丫| 国产精品天天狠天天看| 99精品久久免费精品久久| 在线播放深夜精品三级| 日本高清视频在线www色| 偷拍一区二区三区在线视频| 免费观看欧美猛交视频黑人| 欧美午夜精品久久久久久浪潮| 国产在线无遮挡免费观看| 国产香蕉尹人综合在线观看| 文水县| 美女一区二区三区在线观看视频| 成人欧美一区二区三区在线观看 | 色噜噜一区二区三区| 久久精品亚洲国产综合色| 亚洲更新最快无码视频| 九九成人免费视频| 开心久久综合激情五月天|