建立 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 版)。 例如,如要建立 surfaceflinger 的 HAL 介面檔案,請在 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_ 前置字串。
  • 新增註解。協助開發人員 config 項目、如何變更架構行為、有效值及其他 可能不準確或不適當

函式傳回類型可以是 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 用於藍牙相關 設定項目