iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 10
0
  • Guide:
    • Treble 是什麼?
    • Treble 架構
    • HIDL 概述
    • HIDL 編碼規範
    • HIDL 中的 hidl-gen 使用
    • HIDL interface 和 package
    • HIDL import & inheritance
    • HIDL 實作

HIDL 是圍繞 interface 進行編譯的,
interface 是面向對象的語言使用的一種用來定義行為的抽像類型。
每個 interface 都是 package 的一部分。

Package (軟件包)

package 名稱可以具有子級,例如 package.subpackage
已發布的 HIDL package 的根目錄是 hardware/interfaces 
vendor/vendorName(例如 Pixel 設備為 vendor/google)。
軟件包名稱在根目錄下形成一個或多個子目錄;
定義 package 的所有文件都位於同一目錄下。
例如 package android.hardware.example.extension.light@2.0
可以在 hardware/interfaces/example/extension/light/2.0 下找到。

例如:

hardware/interfaces/nfc/1.0/INfc.hal

17 package android.hardware.nfc@1.0;
18
19 import INfcClientCallback;
20
21 interface INfc {
36     @entry
37     @callflow(next={"write", "coreInitialized", "prediscover", "powerCycle", "controlGranted"})
38     open(INfcClientCallback clientCallback) generates (NfcStatus status);

要使用接口 INfc,必須要確定其 package。
通過 Android HIDL 編碼規範 知道包名的命名規則:

PACKAGE.MODULE[.SUBMODULE[.SUBMODULE[…]]]@VERSION

結合例子得到:
PACKAGEandroid.hardware
MODULEnfc
VERSION1.0
其中的 PACKAGE 是通過 ROOT-DIRECTORY 隱射來得到的。

下表列出了 Package 前綴和位置:

所以,上面例子中 android.hardware.nfc 路徑,
應該是來源於 hardware/interfaces/nfc
那麼如何確定這個 ROOT-DIRECTORY
其實這個是在編譯的時候 Android.mkAndroid.bp 設定的,
例如 android.hardware 定義在 hardware/interfaces/Android.bp 中:

	1 hidl_package_root {                                                                                                                                                                  
  2     name: "android.hardware",
  3     path: "hardware/interfaces",
  4 }

當然 OEM 也可以在 vendor 的目錄下定義自己的 HIDL,
例如定義 vendor 名為 test(路徑為vendor/test):

	1 hidl_package_root {                                                                                                                                                                  
  2     name: "vendor.test.hardware",
  3     path: "vendor/test/hardware/interfaces",
  4 }

這樣如果定義 display 的 HIDL 文件可以是:

 1 package vendor.test.hardware.display.config@1.0;
 2 
 3 interface IDisplayConfig {
 4     enum DisplayType : int32_t {
 5         INVALID = -1,
 6 
 7         DISPLAY_PRIMARY = 0,
 8         DISPLAY_EXTERNAL = 1,
 9         DISPLAY_VIRTUAL = 2,
10     };

通過這裡得知:

  • PACKAGE 為 vendor.test.hardware
  • MODULE 為 display
  • SUBMODULE 為 config
  • VERSION 為 1.0

Interface (接口)

除了 types.hal 之外,其他 .hal 文件均定義一個接口。
接口通常定義如下:

interface IBar extends IFoo { // IFoo is another interface
    // embedded types
    struct MyStruct {/*...*/};

    // interface methods
    create(int32_t id) generates (MyStruct s);
    close();
};

這裡在說明什麼顯式、隱式聲明的原本看不是很懂,
但結合 JAVA 的用法就能不難猜出,
通常你要沿用一個既有的功能,
你得用 extends 的方法來使用那個類別裡的函式。
這裡差不多就是那個意思,而且還強調一點,
android.hidl.base@1.0::IBase 這個 interface,
已經被偷偷地 import 進來可以直接使用,
(就像是 JAVA 裡的 java.lang.Object
當然裡面的 method 也不用再特別宣告一次可以直接使用,
看來真的是很貼心 JAVA 和 C++ 的使用者呢。(笑)
這些 method 有幾種如下:

  • ping
  • interfaceChain
  • interfaceDescriptor
  • notifySyspropsChanged
  • linkToDeath
  • unlinkToDeath
  • setHALInstrumentation
  • getDebugInfo
  • debug
  • getHashChain

Reference :

Interfaces & Packages | Android Open Source Project


上一篇
[Day-09] Android HIDL (4) hidl-gen
下一篇
[Day-11] Android HIDL (6) import & inheritance
系列文
Android Pie 底層開發學習心得30

尚未有邦友留言

立即登入留言