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

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

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

      Android Hal 啟動過程--以 broadcastradio hal2.0 為例

      Android Hal 啟動過程--以 broadcastradio hal2.0 為例

      概述

      1. broadcastradio hal2 的 Android 源碼位于 hardware/interfaces/broadcastradio 目錄下
      2. hal 進程作為服務端,調用 open/mmap/ioctol 系統接口使用 Binder IPC ,向 HIDL Service Manager 注冊服務,frameworks 會在應用軟件調用相關接口時去 HIDL 的 ServiceManager 找 hal 層的服務,如果找到,則順利調用到 hal 層,否則,報錯。
      3. hal 層進程注冊到 hwbinder 過程很復雜,這里只去除了如何向 Hwbinder 注冊,以及 Binder IPC 通信過程,只專注于 hal 層和 frameworks 之間接口調用,后續會繼續追蹤 hal 層的服務句柄到底是怎么傳遞到 HIDL 服務手里的。

      一、拉起 hal 進程

      1. init 進程負責拉起 hal 進程
      // system/core/init/init.cpp
      static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
          Parser parser = CreateParser(action_manager, service_list);
      
          std::string bootscript = GetProperty("ro.boot.init_rc", "");
          if (bootscript.empty()) {
              parser.ParseConfig("/init.rc");
              if (!parser.ParseConfig("/system/etc/init")) {
                  late_import_paths.emplace_back("/system/etc/init");
              }
              ...
      
              // 會將 /vendor/etc/init 文件夾所有 rc 文件都拉來
              if (!parser.ParseConfig("/vendor/etc/init")) {
                  late_import_paths.emplace_back("/vendor/etc/init");
              }
          } else {
              parser.ParseConfig(bootscript);
          }
      }
      
      1. broadcastradiohal 的 rc 文件
      // hardware/interfaces/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
      // 該文件會在編譯后拷貝到 /vendor/etc/init/ 目錄下
      service broadcastradio-hal2 /vendor/bin/hw/android.hardware.broadcastradio@2.0-service
          class hal
          user audioserver
          group audio
      

      二、hal 進程啟動

      1. hal 注冊服務
      // hardware/interfaces/broadcastradio/2.0/default/service.cpp
      int main(int /* argc */, char** /* argv */) {
      
          BroadcastRadio broadcastRadio(gAmFmRadio);
      
          // 向 HidlService 注冊 broadcastRadio 的服務
          auto status = broadcastRadio.registerAsService();
          CHECK_EQ(status, android::OK) << "Failed to register Broadcast Radio HAL implementation";
      
          return 1;  // joinRpcThreadpool shouldn't exit
      }
      
      1. 注冊接口的配置文件
      // manifest.xml 注冊配置文件
      <hal format="hidl">
          <name>android.hardware.broadcastradio</name>
          <transport>hwbinder</transport>
          <version>2.0</version>
          <interface>
              <name>IBroadcastRadio</name>
              <instance>default</instance>
          </interface>
      </hal>
      
      
      • 該文件可以在 device 目錄下和其他 hal 層接口一起設置,也可以在 hal 源碼目錄下單獨設置,如果是后者,則需要在 Android.bp 文件中指明注冊的配置文件。
      • 注冊的服務名為 android.hardware.broadcastradio@2.0::IBroadcastRadio
      1. hal 層服務器創建
        在 Android hal 中,hardware/interfaces/broadcastradio/2.0/default/ 目錄下都是接口,雖然說具體開發確實也是實現這個文件夾下的文件,但是實際上,會被 Android 使用 hidl-gen 工具生成最終的 hal 層服務器和客戶端,比如在 auto status = broadcastRadio.registerAsService(); 注冊服務代碼就在生成的 HIDL 服務器代碼中
      // out/soong/.intermediates/hardware/interfaces/broadcastradio/2.0/android.hardware.broadcastradio@2.0_genc++/gen/android/hardware/broadcastradio/2.0/BroadcastRadioAll.cpp
      ::android::status_t IBroadcastRadio::registerAsService(const std::string &serviceName) {
          ::android::hardware::details::onRegistration("android.hardware.broadcastradio@2.0", "IBroadcastRadio", serviceName);
      
          const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm
                  = ::android::hardware::defaultServiceManager();
          if (sm == nullptr) {
              return ::android::INVALID_OPERATION;
          }
          ::android::hardware::Return<bool> ret = sm->add(serviceName.c_str(), this);
          return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;
      }
      
      
      1. HIDL broadcastradio 服務進程向 HIDL ServiceManager 注冊服務
      // 該 broadcastradio 的引用和唯一標識名保存位置
      // system/hwservicemanager/ServiceManager.h
      struct ServiceManager : public IServiceManager, hidl_death_recipient {
          ...
          Return<bool> add(const hidl_string& name,
                           const sp<IBase>& service) override;
          std::map<
              std::string, // package::interface e.x. "android.hidl.manager@1.0::IServiceManager"
              PackageInterfaceMap
          > mServiceMap; 
      }
      // ServiceManager.cpp
      Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
          ...
          const HidlService *hidlService = ifaceMap.lookup(name);
          if (hidlService == nullptr) {
              ifaceMap.insertService(
                  std::make_unique<HidlService>(fqName, name, service, callingContext.pid));
          } else {
              hidlService->setService(service, callingContext.pid);
          }
      }
      

      三、frameworks 層調用 hal 層服務

      1. 查看 HIDL 服務器是否有 hal 層進程接口
      // frameworks/base/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
          private static @NonNull List<String> listByInterface(@NonNull String fqName) {
              try {
                  IServiceManager manager = IServiceManager.getService();
                  ..
                  List<String> list = manager.listByInterface(fqName);
                  return list;
              } catch (RemoteException ex) {
                  ...
              }
          }
      
      1. RadioModule 模塊加載 hal 層服務接口,即獲取 hal 進程對應的 broadcastradio hal 服務的引用
      private RadioModule(@NonNull IBroadcastRadio service,
              @NonNull RadioManager.ModuleProperties properties) {
          mProperties = Objects.requireNonNull(properties);
          mService = Objects.requireNonNull(service);
      }
      public static @Nullable RadioModule tryLoadingModule(int idx, @NonNull String fqName) {
          ...
          return new RadioModule(service, prop);
      }
      
      1. frameworks 打開與 hal 層的會話
      public @NonNull TunerSession openSession(@NonNull android.hardware.radio.ITunerCallback userCb) throws RemoteException {
          ...
          synchronized (mService) {
              mService.openSession(cb, (result, session) -> {
                  hwSession.value = session;
                  halResult.value = result;
              });
          }
          ...
      }
      

      自此,radio 的 frameworks 和 hal 進程通信通道構建完成

      posted @ 2024-04-03 15:47  王清河  閱讀(991)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 18禁国产一区二区三区| 灵川县| 国产99视频精品免费专区| 亚洲精品国产第一区二区| 熟女蜜臀av麻豆一区二区| 另类 专区 欧美 制服| 扒开双腿疯狂进出爽爽爽| 年轻女教师hd中字3| 三级国产在线观看| 久久天天躁狠狠躁夜夜2020老熟妇| 日韩一欧美内射在线观看| 日韩av日韩av在线| 亚洲国产制服丝袜高清在线| 国产福利在线观看免费第一福利| 狠狠躁夜夜躁无码中文字幕 | 强开少妇嫩苞又嫩又紧九色| 无码人妻斩一区二区三区 | 日韩有码中文字幕国产| 亚洲熟妇一区二区三个区| 视频一区二区不中文字幕| 日韩大片高清播放器| 成人亚洲精品一区二区三区| 免费人成在线观看网站| 69精品丰满人妻无码视频a片| 国产精品乱码一区二区三| 久操资源站| 欧美国产精品啪啪| 中文字幕理伦午夜福利片| 久久精品国产亚洲欧美| 亚洲中文字幕一区二区| 国产精品人成在线观看免费| 国产精品成人久久电影| 日韩女同一区二区三区久久| 亚洲欧美中文日韩V日本| 久久综合97丁香色香蕉| 亚洲国产精品色一区二区| 91精品乱码一区二区三区| 成年午夜无码av片在线观看| 亚洲国产成人自拍视频网| 九九热爱视频精品| 天天摸天天做天天添欧美|