在 Android 10 中,ConfigStore HAL 會使用建構標記,將設定值儲存在 vendor
分割區中,而 system
分割區中的服務會使用 HIDL 存取這些值 (Android 9 也是如此)。不過,由於 ConfigStore HAL 耗用大量記憶體,且難以使用,因此已遭淘汰。
ConfigStore HAL 仍保留在 AOSP 中,以支援舊版供應商分區。在搭載 Android 10 以上版本的裝置上,surfaceflinger
會先讀取系統屬性;如果 `SurfaceFlingerProperties.sysprop` 中未定義設定項目的系統屬性,`surfaceflinger` 會改用 ConfigStore HAL。
Android 8.0 將單一的 Android OS 分割為一般 (system.img
) 和硬體專屬 (vendor.img
和 odm.img
) 分割區。因此,您必須從安裝至系統分割區的模組中移除條件式編譯,且這類模組必須在執行階段判斷系統的設定 (並根據該設定採取不同行為)。
ConfigStore HAL 提供一組 API,用於存取唯讀設定項目,這些項目可用於設定 Android 架構。本頁面說明 ConfigStore HAL 的設計 (以及為何不使用系統屬性),本節的其他頁面則詳細說明 HAL 介面、服務實作和用戶端使用情形,所有內容都以 surfaceflinger
為例。如需 ConfigStore 介面類別的相關說明,請參閱新增介面類別和項目。
為什麼不使用系統屬性?
我們曾考慮使用系統屬性,但發現幾個基本問題,包括:
- 值的長度限制。系統屬性的值長度有嚴格限制 (92 個位元組)。此外,由於這些限制已直接以 C 巨集的形式向 Android 應用程式公開,增加長度可能會導致回溯相容性問題。
- 不支援類型。所有值基本上都是字串,API 只會將字串剖析為
int
或bool
。其他複合資料類型 (例如陣列和結構體) 應由用戶端編碼/解碼 (例如"aaa,bbb,ccc"
可以編碼為三個字串的陣列)。 - 覆寫。由於唯讀系統屬性是實作為只能寫入一次的屬性,因此供應商/ODM 如要覆寫 AOSP 定義的唯讀值,必須先匯入自己的唯讀值,再匯入 AOSP 定義的唯讀值。這會導致 AOSP 定義的值覆寫供應商定義的可重寫值。
- 位址空間規定。系統屬性在每個程序中佔用的位址空間相對較大。系統屬性會分組為
prop_area
128 KB 的固定大小單位,即使只存取其中的單一系統屬性,也會全部分配給程序位址空間。這可能會導致 32 位元裝置發生問題,因為位址空間非常寶貴。
我們嘗試克服這些限制,同時兼顧相容性,但仍擔心系統屬性無法支援存取唯讀設定項目。最後,我們決定系統屬性更適合在所有 Android 裝置上即時共用幾個動態更新的項目,而且需要專用的新系統來存取唯讀設定項目。
ConfigStore HAL 設計
基本設計很簡單:
圖 1. ConfigStore HAL 設計
- 在 HIDL 中說明建構旗標 (目前用於有條件地編譯架構)。
- 供應商和原始設備製造商 (OEM) 會實作 HAL 服務,為建構標記提供 SoC 和裝置專屬值。
- 修改架構,使用 HAL 服務在執行階段找出設定項目的值。
架構目前參照的設定項目會納入版本化 HIDL 套件 (android.hardware.configstore@1.0
)。供應商/原始設備製造商會透過實作這個套件中的介面,為設定項目提供值,而架構會在需要取得設定項目的值時使用這些介面。
安全性考量
在相同介面中定義的建構標記會受到相同 SELinux 政策影響。如果一或多個建構標記應採用不同的 SELinux 政策,就必須分隔到另一個介面。這可能需要大幅修訂 android.hardware.configstore package
,因為分離的介面不再回溯相容。