供應商原生開發套件 (VNDK) 是一組程式庫,供供應商或產品分割區中的其他程式庫或二進位檔在執行階段用於 dlopen。
淘汰
Android 8.0 推出供應商 NDK,在架構和供應商程式碼之間提供 API。VNDK 已成功使用多年,但仍有缺點:- 儲存空間
- 單一 VNDK APEX 會封裝所有 VNDK 程式庫,無論是否從裝置使用。
- GSI 包含多個版本的 VNDK APEX,可支援多個版本的供應商映像檔。
- 可更新性
- 很難將 VNDK APEX 與平台更新分開更新。
- 供應商映像檔經常透過無線更新 (OTA) 方式更新,因此將 VNDK 封裝在系統映像檔中,效益會降低。
VNDK 淘汰事宜詳情
所有 VNDK 程式庫都會封裝到 VNDK APEX 中,並安裝在系統 (-ext) 映像檔中。 隨著 VNDK 遭到淘汰,先前的 VNDK 程式庫會安裝在供應商 (或產品) 映像檔中,與其他供應商可用的程式庫相同。 這些功能會隨著 VNDK 淘汰而移除:- Android 15 的 VNDK APEX
- 如果為 Android 15 建構供應商或產品分割區,系統會移除指出目標 VNDK 版本的系統屬性:
ro.vndk.version
ro.product.vndk.version
- 由於沒有 VNDK,因此無法進行 VNDK 最佳化:
TARGET_VNDK_USING_CORE_VARIANT
適用於 Android Go 裝置use_vndk_as_stable
適用於供應商 APEX
- 供應商快照,高度取決於 VNDK
淘汰項目的例外狀況
VNDK 淘汰後,下列功能不會受到影響:- VNDK APEX (VNDK 版本為 14 以下),支援現有供應商映像檔時需要用到。
- LL-NDK 不屬於 VNDK。
為什麼要使用 VNDK?
AOSP 允許僅更新架構,也就是將系統分割區升級至最新架構版本,同時保留供應商分割區不變。儘管是在不同時間建構,每個分區中的二進位檔都必須能夠彼此搭配運作。
僅更新架構會遇到下列挑戰:
- 架構模組和供應商模組之間的依附元件。在 Android 8.0 之前,供應商和系統分割區中的模組可以互相連結。不過,供應商模組的依附元件對架構模組開發造成不必要的限制。
- Android 開放原始碼計畫程式庫的擴充功能。Android 規定所有 Android 裝置在系統分區替換為標準通用系統映像檔 (GSI) 時,都必須通過 CTS。不過,由於供應商會擴充 AOSP 程式庫,以提升效能或為 HIDL 實作項目新增額外功能,因此使用標準 GSI 刷寫系統分割區可能會導致供應商的 HIDL 實作項目中斷。如需避免這類中斷的指南,請參閱「VNDK 擴充功能」。
為解決這些問題,Android 包含多項功能,例如 VNDK (本節所述)、HIDL、hwbinder、裝置樹狀結構疊加層和 sepolicy 疊加層。
VNDK 專屬條款
VNDK 相關文件使用下列術語:- 模組是指共用程式庫或可執行檔。模組會建立建構時間依附元件。
- 程序是作業系統從可執行檔衍生的工作。程序會建立執行階段依附元件。
- 架構限定字詞與
system
分區相關: - 架構可執行檔是指
/system/bin
或/system/xbin
中的可執行檔。 - 架構共用程式庫是指
/system/lib[64]
下的共用程式庫。 - 架構模組是指架構共用程式庫和架構可執行檔。
- 架構程序是從架構可執行檔 (例如
/system/bin/app_process
) 衍生的程序。 - 供應商限定字詞與
vendor
分割區相關: - 供應商可執行檔是指
/vendor/bin
中的可執行檔。 - 供應商共用程式庫是指
/vendor/lib[64]
下方的共用程式庫。 - 供應商模組是指供應商可執行檔和供應商共用程式庫。
- 廠商程序:從廠商可執行檔 (例如
/vendor/bin/android.hardware.camera.provider@2.4-service
) 衍生的程序。
VNDK 概念
在理想的 Android 8.0 以上版本中,架構程序不會載入供應商共用程式庫,所有供應商程序只會載入供應商共用程式庫 (和部分架構共用程式庫),且架構程序和供應商程序之間的通訊會由 HIDL 和硬體繫結器控管。
在這種情況下,架構共用程式庫的穩定公開 API 可能不足以供供應商模組開發人員使用 (雖然 API 可能會在 Android 版本之間變更),因此供應商程序必須能存取部分架構共用程式庫。此外,由於效能要求可能會導致妥協,因此必須以不同方式處理一些對回應時間要求嚴苛的 HAL。
以下各節將詳細說明 VNDK 如何處理供應商和同程序 HAL (SP-HAL) 的架構共用程式庫。
供應商的架構共用程式庫
本節說明如何分類可供供應商程序存取的共用程式庫。如要在多個 Android 版本中支援供應商模組,有兩種做法:
- 穩定架構共用程式庫的 ABI/API。新的架構模組和舊的供應商模組可以使用相同的共用程式庫,減少記憶體用量和儲存空間大小。此外,使用專屬共用程式庫也能避免多項重複載入問題。不過,維護穩定的 ABI/API 開發成本很高,而且要穩定每個架構共用程式庫匯出的所有 ABI/API 也不切實際。
- 複製舊架構共用程式庫。並嚴格限制側邊通道,也就是架構模組和供應商模組之間的所有通訊機制,包括 (但不限於) 繫結器、插座、管道、共用記憶體、共用檔案和系統屬性。除非通訊協定已凍結且穩定 (例如透過 hwbinder 的 HIDL),否則不得進行通訊。重複載入共用程式庫也可能導致問題;舉例來說,如果將新程式庫建立的物件傳遞至舊程式庫的函式,這些程式庫可能會以不同方式解讀物件,進而發生錯誤。
視共用程式庫的特性而定,系統會採用不同的方法。因此,架構共用程式庫會分為以下三類:
- LL-NDK 程式庫是已知的穩定架構共用程式庫。他們的開發人員致力於維持 API/ABI 的穩定性。
- LL-NDK 包含下列程式庫:
libEGL.so
、libGLESv1_CM.so
、libGLESv2.so
、libGLESv3.so
、libandroid_net.so
、libc.so
、libdl.so
、liblog.so
、libm.so
、libnativewindow.so
、libneuralnetworks.so
、libsync.so
、libvndksupport.so
和libvulkan.so
。
- LL-NDK 包含下列程式庫:
- 符合資格的 VNDK 程式庫 (VNDK) 是架構共用程式庫,可安全地複製兩次。架構模組和供應商模組可以連結至自己的副本。架構共用程式庫必須符合下列條件,才能成為符合資格的 VNDK 程式庫:
- 不會傳送/接收架構的 IPC。
- 這與 ART 虛擬機器無關。
- 不會讀取/寫入檔案/磁碟分割區,檔案格式不穩定。
- 不含需要法律審查的特殊軟體授權。
- 程式碼擁有者不反對供應商使用。
- 僅限架構的程式庫 (FWK-ONLY) 是不屬於上述類別的架構共用程式庫。這些程式庫:
- 視為架構內部實作詳細資料。
- 供應商模組不得存取。
- 具有不穩定的 ABI/API,且不保證 API/ABI 相容性。
- 不會複製。
同程序 HAL (SP-HAL)
同程序 HAL (SP-HAL) 是一組預先決定的 HAL,實作方式為供應商共用程式庫,並載入架構程序。SP-HAL 會透過連結器命名空間隔離 (控制共用程式庫可見的程式庫和符號)。SP-HAL 只能依附於 LL-NDK 和 VNDK-SP。
VNDK-SP 是符合資格的 VNDK 程式庫預先定義子集。我們會仔細檢查 VNDK-SP 程式庫,確保將 VNDK-SP 程式庫重複載入架構程序時不會發生問題。SP-HAL 和 VNDK-SP 都是由 Google 定義。
下列程式庫是通過核准的 SP-HAL:
libGLESv1_CM_${driver}.so
libGLESv2_${driver}.so
libGLESv3_${driver}.so
libEGL_${driver}.so
vulkan.${driver}.so
android.hardware.renderscript@1.0-impl.so
android.hardware.graphics.mapper@2.0-impl.so
VNDK-SP 程式庫會在 Android.bp 檔案中指定 vndk: { support_system_process: true }
。如果也指定 vndk: {private:true}
,這些程式庫就會稱為 VNDK-SP-Private
,且 SP-HAL 看不到這些程式庫。
以下是僅限架構的程式庫,但有 RS 例外狀況 (FWK-ONLY-RS):
libft2.so
(RenderScript)libmediandk.so
(RenderScript)
VNDK 版本管理
VNDK 共用程式庫會加上版本編號:
- 系統會自動將
ro.vndk.version
系統屬性新增至/vendor/default.prop
。 - VNDK 和 VNDK-SP 共用程式庫會以 VNDK Apex
com.android.vndk.v${ro.vndk.version}
的形式安裝,並掛接到/apex/com.android.vndk.v${ro.vndk.version}
。
演算法會選擇下列 ro.vndk.version
的值:
- 如果
BOARD_VNDK_VERSION
「不等於」current
,請使用BOARD_VNDK_VERSION
。 - 如果
BOARD_VNDK_VERSION
等於current
: - 如果
PLATFORM_VERSION_CODENAME
是REL
,請使用PLATFORM_SDK_VERSION
(例如28
)。 - 否則,請使用
PLATFORM_VERSION_CODENAME
(例如P
)。
供應商測試套件 (VTS)
Android 供應商測試套件 (VTS) 規定 ro.vndk.version
屬性不得為空。新推出的裝置和升級裝置都必須定義 ro.vndk.version
。部分 VNDK 測試案例 (例如 VtsVndkFilesTest
和 VtsVndkDependencyTest
) 會依賴 ro.vndk.version
屬性載入相符的合格 VNDK 程式庫資料集。