Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

創建HAL接口

您必須使用HIDL來描述用於條件編譯框架的所有構建標誌。相關的構建標誌必須分組並包含在單個.hal文件中。使用HIDL指定配置項具有以下優點:

  • 版本化(要添加新的配置項,供應商/ OEM必須顯式擴展HAL)
  • 有據可查
  • 使用SELinux的訪問控制
  • 通過供應商測試套件對配置項進行完整性檢查(範圍檢查,項之間的相互依賴性檢查等)
  • 自動生成的C ++和Java API

識別框架使用的構建標誌

首先確定用於有條件地編譯框架的構建配置,然後放棄過時的配置以縮小集合。例如,為surfaceflinger標識了以下構建標記集:

  • TARGET_USES_HWC2
  • TARGET_BOARD_PLATFORM
  • TARGET_DISABLE_TRIPLE_BUFFERING
  • TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
  • NUM_FRAMEBUFFER_SURFACE_BUFFERS
  • TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK
  • VSYNC_EVENT_PHASE_OFFSET_NS
  • SF_VSYNC_EVENT_PHASE_OFFSET_NS
  • PRESENT_TIME_OFFSET_FROM_VSYNC_NS
  • MAX_VIRTUAL_DISPLAY_DIMENSION

創建一個HAL接口

子系統的構建配置可通過HAL接口訪問,而用於提供配置值的接口則分組在HAL包android.hardware.configstore (當前為1.0版)中。例如,為了創建一個HAL接口文件surfaceflinger ,在hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal

package android.hardware.configstore@1.0;

interface ISurfaceFlingerConfigs {
    // TO-BE-FILLED-BELOW
};

創建.hal文件後,運行hardware/interfaces/update-makefiles.sh將新的.hal文件添加到Android.bpAndroid.mk文件中。

為構建標誌添加功能

對於每個構建標記,將新功能添加到接口。例如,在hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal

interface ISurfaceFlingerConfigs {
    disableTripleBuffering() generates(OptionalBool ret);
    forceHwcForVirtualDisplays() generates(OptionalBool ret);
    enum NumBuffers: uint8_t {
        USE_DEFAULT = 0,
        TWO = 2,
        THREE = 3,
    };
    numFramebufferSurfaceBuffers() generates(NumBuffers ret);
    runWithoutSyncFramework() generates(OptionalBool ret);
    vsyncEventPhaseOffsetNs generates (OptionalUInt64 ret);
    presentTimeOffsetFromSyncNs generates (OptionalUInt64 ret);
    maxVirtualDisplayDimension() generates(OptionalInt32 ret);
};

添加功能時:

  • 名稱要簡潔。避免將makefile變量名稱轉換為函數名稱,並記住不再需要TARGET_BOARD_前綴。
  • 添加評論。幫助開發人員了解配置項的目的,配置項如何更改框架行為,有效值以及其他相關信息。

函數返回類型可以是Optional[Bool|String|Int32|UInt32|Int64|UInt64] 。類型是在同一目錄中的types.hal中定義的,並用指示該值是否由HAL指定的字段包裝原始值。如果不是,則使用默認值。

struct OptionalString {
    bool specified;
    string value;
};

在適當的時候,定義最能代表配置項類型的枚舉,並將該枚舉用作返回類型。在上面的示例中,定義了NumBuffers枚舉以限制有效值的數量。定義此類自定義數據類型時,請添加字段或枚舉值(例如USE_DEFAULT )以表示該值是否由HAL指定。

在HIDL中,單個構建標記成為單個函數不是強制性的。模塊所有者可以選擇將緊密相關的構建標誌聚合到一個結構中,並具有一個返回該結構的函數(這樣做可以減少函數調用的次數)。

例如,在hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal兩個構建標記聚合到單個結構中的選項是:

 interface ISurfaceFlingerConfigs {
    // other functions here
    struct SyncConfigs {
        OptionalInt64 vsyncEventPhaseoffsetNs;
        OptionalInt64 presentTimeoffsetFromSyncNs;
    };
    getSyncConfigs() generates (SyncConfigs ret);
    // other functions here
};

單個HAL功能的替代品

作為對所有構建標誌使用單個HAL函數的替代方法,HAL接口還提供了諸如getBoolean(string key)getInteger(string key)簡單函數。實際的key=value對存儲在單獨的文件中,並且HAL服務通過讀取/解析這些文件來提供值。

儘管此方法易於定義,但不包括HIDL提供的好處(強製版本控制,易於編寫文檔,訪問控制),因此不建議使用。

單個和多個接口

用於配置項的HAL接口的設計提供了兩種選擇:

  • 一個涵蓋所有配置項目的界面
  • 多個接口,每個接口涵蓋一組相關的配置項

單個界面比較容易,但是隨著更多配置項添加到單個文件中,它可能變得難以維護。另外,訪問控制不是很細粒度,因此被授予對接口的訪問權限的進程可以讀取所有配置項(不能授予對部分配置項的訪問權限)。或者,如果未授予訪問權限,則無法讀取配置項。

由於這些問題,Android將多個接口與單個HAL接口一起用於一組相關的配置項。例如, ISurfaceflingerConfigssurfaceflinger -相關的配置項,並IBluetoothConfigs藍牙相關的配置項。