終於到最後一個步驟了!
我們將結合前面所提到的一些方法和規範,
通過創立一個 Helloworld 的 HIDL 範例,
來了解先前提到的 passthrough 模式是怎麼兼容舊版的 HAL;
binderized 模式又是怎麼透過 Service 運作的。
這裡內容有點多,所以就拆成上、下篇來進行吧,
廢話不多說!讓我們給它看下去!
在 HIDL (3) 編碼規範 一文中有提到需要下面的結構:
在 HIDL (5) interface & package 一文中提到 package 前綴的規範如下表:
| Package Prefix | Location | Interface Type | 
|---|---|---|
| android.hardware.* | hardware/interfaces/* | HAL | 
| android.frameworks.* | frameworks/hardware/interfaces/* | frameworks/ 相關 | 
| android.system.* | system/hardware/interfaces/* | system/ 相關 | 
| android.hidl.* | system/libhidl/transport/* | core | 
在 HIDL (5) interface & package 一文中又有提到,
一般 OEM 的 HAL ,也就是廠商自己新增的通常都是在 vendor 目錄下。
本文中 helloworld 設定位於 hardware/interfaces 中,
所以目錄路徑為 hardware/interfaces/helloworld/1.0。
hardware/interfaces 目錄下的 package 為 android.hardware,
所以 package name 應該是 android.hardware.helloworld@1.0。
確定 HIDL 模塊的路徑和包名之後,
需要創建一個hal 文件,
這個文件包含了client 需要調用 HAL 的入口 api,
這裡命名為 IHelloWorld.hal,
代碼如下:
	1 package android.hardware.helloworld@1.0; 
  2   
  3 interface IHelloWorld { 
  4     justTest(string name) generates (string result, HelloTest value);
  5   
  6     justTest1(HelloTest name);
  7 };
其中 HelloTest 是用戶自定義類型,
如果是模塊公共的類型,
可以定義在 types.hal 中,
例如這裡:
	1 package android.hardware.helloworld@1.0; 
  2       
  3 enum HelloTest : uint8_t { 
  4     V_TEST1 = 0, 
  5     V_TEST2 = 1, 
  6 };
根據 Step 2. 中的 hal 文件利用 hidl-gen (詳細看 HIDL (4) hidl-gen),
先執行 source build/envsetup.sh && lunch 後,
再執行 ./hardware/interfaces/update-makefiles.sh,
生成對應的 Android.bp 檔案如下:
	1 // This file is autogenerated by hidl-gen -Landroidbp.                                                                                                                               
  2  
  3 hidl_interface {
  4     name: "android.hardware.helloworld@1.0",
  5     root: "android.hardware",
  6     vndk: {
  7         enabled: true,
  8     },
  9     srcs: [
 10         "types.hal",
 11         "IHelloWorld.hal",
 12     ],
 13     interfaces: [
 14         "android.hidl.base@1.0",
 15     ],
 16     types: [
 17         "HelloTest",
 18     ],
 19     gen_java: true,
 20 }
 21
注意:
update_makefiles.sh 就可以自動生成。在對應的 HIDL 目錄下 mm 編譯或者在根目錄下 make <FQName> 即可,
最終在 out/soong/.intermediates/hardware/interfaces/helloworld/1.0
下會生成對應模塊的 obj,詳細如下:
 android.hardware.helloworld@1.0/
 android.hardware.helloworld@1.0-adapter/
 android.hardware.helloworld@1.0-adapter_genc++/
 android.hardware.helloworld@1.0-adapter-helper/
 android.hardware.helloworld@1.0-adapter-helper_genc++/
 android.hardware.helloworld@1.0-adapter-helper_genc++_headers/
 android.hardware.helloworld@1.0_genc++/
 android.hardware.helloworld@1.0_genc++_headers/
 android.hardware.helloworld-V1.0-java/
 android.hardware.helloworld-V1.0-java_gen_java/
其中:
android.hardware.helloworld@1.0 就是模塊對應的庫文件;
android.hardware.helloworld@1.0_genc++
為生成對應的 C++ 臨時文件,在使用的時候都是鏈接到這裡;
android.hardware.helloworld@1.0_genc++
└── gen
└── android
└── hardware
└── helloworld
└── 1.0
├── HelloWorldAll.cpp
├── HelloWorldAll.cpp.d
└── types.cpp
android.hardware.helloworld@1.0_genc++_headers 為生成的 C++ 所需的頭文件;
android.hardware.helloworld@1.0_genc++_headers
└── gen
└── android
└── hardware
└── helloworld
└── 1.0
├── BnHwHelloWorld.h
├── BpHwHelloWorld.h
├── BsHelloWorld.h
├── hwtypes.h
├── IHelloWorld.h
├── IHelloWorld.h.d
├── IHwHelloWorld.h
└── types.h
android.hardware.helloworld-V1.0-java 為 java 代碼所使用的 java 庫文件;
android.hardware.helloworld-V1.0-java_gen_java 為 java 代碼所使用的 java 文件
android.hardware.helloworld-V1.0-java_gen_java
└── gen
└── android
└── hardware
└── helloworld
└── V1_0
├── HelloTest.java
├── IHelloWorld.java
└── IHelloWorld.java.d