供應商原生開發套件 (VNDK)

供應商本機開發工具包 (VNDK) 是一組專門供供應商實施其 HAL 的庫。 VNDK 包含在system.img中,並在運行時動態鏈接到供應商代碼。

為什麼選擇 VNDK?

Android 8.0 及更高版本支持僅框架更新,其中系統分區可以升級到最新版本,而供應商分區保持不變。這意味著在不同時間構建的二進製文件必須能夠相互協作; VNDK 涵蓋了跨 Android 版本的 API/ABI 更改。

僅框架更新包括以下挑戰:

  • 框架模塊和供應商模塊之間的依賴關係。在 Android 8.0 之前,雙方的模塊都可以與對方的模塊鏈接。但是,來自供應商模塊的依賴性對框架模塊的開發施加了不希望的限制。
  • AOSP 庫的擴展。當系統分區被標准通用系統映像 (GSI) 替換時,Android 8.0 及更高版本要求所有 Android 設備通過 CTS。但是,隨著供應商擴展 AOSP 庫以提高性能或為其 HIDL 實施添加額外功能,使用標準 GSI 刷新系統分區可能會破壞供應商的 HIDL 實施。 (有關防止此類損壞的指南,請參閱VNDK 擴展。)

為了應對這些挑戰,Android 8.0 引入了多種技術,例如 VNDK(在本節中介紹)、 HIDL 、hwbinder、設備樹覆蓋和 sepolicy 覆蓋。

VNDK 資源

本節包括以下 VNDK 資源:

  • VNDK 概念(如下)描述了框架共享庫、同進程 HAL (SP-HAL) 和 VNDK 術語。
  • VNDK 擴展將供應商特定的更改分類。例如,必須將供應商模塊所依賴的具有擴展功能的庫複製到供應商分區中,但禁止 ABI 不兼容的更改。
  • VNDK 構建系統支持描述了與 VNDK 相關的構建系統配置和模塊定義語法。
  • VNDK 定義工具可幫助您將源代碼樹遷移到 Android 8.0 及更高版本。
  • 鏈接器命名空間提供對共享庫鏈接的細粒度控制。
  • 目錄、規則和 sepolicy定義了運行 Android 8.0 及更高版本的設備的目錄結構、VNDK 規則和相關的 sepolicy。
  • VNDK 設計演示說明了 Android 8.0 及更高版本中使用的基本 VDNK 概念。

VNDK 概念

在理想的 Android 8.0 及更高版本中,框架進程不加載供應商共享庫,所有供應商進程僅加載供應商共享庫(以及一部分框架共享庫),並且框架進程和供應商進程之間的通信由 HIDL 和硬件管理粘合劑。

這樣的世界包括來自框架共享庫的穩定的公共 API 可能不足以供供應商模塊開發人員使用(儘管 API 可以在 Android 版本之間更改),要求供應商進程可以訪問框架共享庫的某些部分。此外,由於性能要求可能導致妥協,因此必須區別對待一些對響應時間要求嚴格的 HAL。

以下部分詳細介紹了 VNDK 如何為供應商和同進程 HAL (SP-HAL) 處理框架共享庫。

供應商的框架共享庫

本節描述了對供應商進程可訪問的共享庫進行分類的標準。有兩種方法可以跨多個 Android 版本支持供應商模塊:

  1. 穩定框架共享庫的 ABI/API 。新的框架模塊和舊的供應商模塊可以使用相同的共享庫來減少內存佔用和存儲大小。獨特的共享庫還避免了幾個雙重加載問題。但是,維持穩定的 ABI/API 的開發成本很高,要穩定每個框架共享庫導出的所有 ABI/API 是不現實的。
  2. 複製舊的框架共享庫。附帶對側通道的嚴格限制,定義為框架模塊和供應商模塊之間通信的所有機制,包括(但不限於)綁定器、套接字、管道、共享內存、共享文件和系統屬性。除非通信協議被凍結和穩定(例如通過 hwbinder 的 HIDL),否則必須沒有通信。雙重加載共享庫也可能會導致問題;例如,如果將新庫創建的對像從舊庫傳遞給函數,則可能會發生錯誤,因為這些庫可能會以不同的方式解釋該對象。

根據共享庫的特性使用不同的方法。因此,框架共享庫分為三個子類別:

  • LL-NDK 庫是已知穩定的框架共享庫。他們的開發人員致力於維護他們的 API/ABI 穩定性。
    • LL-NDK 包括以下庫: libEGL.solibGLESv1_CM.solibGLESv2.solibGLESv3.solibandroid_net.solibc.solibdl.soliblog.solibm.solibnativewindow.solibneuralnetworks.solibsync.solibvndksupport.solibvulkan.so
  • 合格的 VNDK 庫 (VNDK)是可以安全複製兩次的框架共享庫框架模塊供應商模塊可以鏈接到它們自己的副本。只有滿足以下條件,框架共享庫才能成為合格的 VNDK 庫:
    • 它不會向/從框架發送/接收 IPC。
    • 它與 ART 虛擬機無關。
    • 它不會讀取/寫入文件格式不穩定的文件/分區。
    • 它沒有需要法律審查的特殊軟件許可證。
    • 它的代碼所有者不反對供應商的使用。
  • 僅框架庫 (FWK-ONLY)是不屬於上述類別的框架共享庫。這些庫:
    • 被視為框架內部實現細節。
    • 供應商模塊不得訪問。
    • 具有不穩定的 ABI/API,並且沒有 API/ABI 兼容性保證。
    • 不被複製。

同進程 HAL (SP-HAL)

Same-Process HAL ( SP-HAL ) 是一組預先確定的 HAL,它們被實現為供應商共享庫並加載到框架進程中。 SP-HAL 由鏈接器命名空間隔離(控制對共享庫可見的庫和符號)。 SP-HAL 必須僅依賴於LL-NDKVNDK-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 } 。如果還指定vendor_available: false ,則這些庫稱為VNDK-SP-Private並且它們對SP-HALS不可見。

以下是具有 RS 異常 (FWK-ONLY-RS) 的僅框架庫

  • libft2.so (渲染腳本)
  • libmediandk.so (渲染腳本)

VNDK 術語

  • 模塊是指共享庫可執行文件
  • 進程是從Executables產生的操作系統任務。
  • 框架限定的術語是指與系統分區相關的概念。
  • 供應商限定術語是指與供應商分區相關的概念。

例如:

  • 框架可執行文件是指/system/bin/system/xbin中的可執行文件。
  • 框架共享庫是指/system/lib[64]下的共享庫。
  • 框架模塊指的是框架共享庫框架可執行文件
  • 框架進程是從框架可執行文件(例如/system/bin/app_process )產生的進程。
  • 供應商可執行文件是指/vendor/bin中的可執行文件
  • 供應商共享庫是指/vendor/lib[64]下的共享庫。
  • 供應商模塊是指供應商可執行文件供應商共享庫
  • 供應商進程是從供應商可執行文件(例如
  • /vendor/bin/android.hardware.camera.provider@2.4-service )。

VNDK 版本控制

在 Android 9 中,VNDK 共享庫是版本化的:

  • ro.vndk.version系統屬性會自動添加到/vendor/default.prop
  • VNDK 共享庫安裝到/system/lib[64]/vndk-${ro.vndk.version}
  • VNDK-SP 共享庫安裝到/system/lib[64]/vndk-sp-${ro.vndk.version}
  • 動態鏈接器配置文件安裝到/system/etc/ld.config.${ro.vndk.version}.txt

ro.vndk.version的值由以下算法選擇:

  • 如果BOARD_VNDK_VERSION不等於current ,請使用BOARD_VNDK_VERSION
  • 如果BOARD_VNDK_VERSION等於current
    • 如果PLATFORM_VERSION_CODENAMEREL ,請使用PLATFORM_SDK_VERSION (例如28 )。
    • 否則,使用PLATFORM_VERSION_CODENAME (例如P )。

升級設備

如果 Android 8.x 設備通過在沒有BOARD_VNDK_VERSION的情況下構建而禁用了 VNDK 運行時強制,它可能會在升級到 Android 9 時將PRODUCT_USE_VNDK_OVERRIDE := false添加到BoardConfig.mk

如果PRODUCT_USE_VNDK_OVERRIDEfalse ,則ro.vndk.lite屬性將自動添加到/vendor/default.prop並且其值為true 。因此,動態鏈接器將從/system/etc/ld.config.vndk_lite.txt加載鏈接器命名空間配置,該配置僅隔離 SP-HAL 和 VNDK-SP。

要將 Android 7.0 或更低版本的設備升級到 Android 9,請將PRODUCT_TREBLE_LINKER_NAMESPACES_OVERRIDE := false添加到BoardConfig.mk

供應商測試套件 (VTS)

Android 9 供應商測試套件 (VTS) 要求使用非空ro.vndk.version屬性。新推出的設備和升級設備都必須定義ro.vndk.version 。一些 VNDK 測試用例(例如VtsVndkFilesTestVtsVndkDependencyTest )依賴ro.vndk.version屬性來加載匹配的合格 VNDK 庫數據集。

如果ro.product.first_api_level屬性大於 27,則不得定義ro.vndk.lite屬性。如果在新推出的 Android 9 設備中定義了ro.vndk.liteVtsTreblePlatformVersionTest將失敗。

文件歷史

本部分跟踪對 VNDK 文檔的更改。

Android 9 的變化

  • 添加 VNDK 版本控制部分。
  • 添加 VTS 部分。
  • 一些 VNDK 類別已重命名:
    • LL-NDK-Indirect 已重命名為 LL-NDK-Private。
    • VNDK-Indirect 已重命名為 VNDK-Private。
    • VNDK-SP-Indirect-Private 已重命名為 VNDK-SP-Private。
    • VNDK-SP-Indirect 已被刪除。

安卓 8.1 的變化

  • SP-NDK 庫已合併到 LL-NDK 庫中。
  • 在 RS 命名空間部分將libui.so替換為libft2.so 。包含libui.so是一個錯誤。
  • libGLESv3.solibandroid_net.so添加到 LL-NDK 庫。
  • libion.so添加到 VNDK-SP 庫。
  • 從 LL-NDK 庫中刪除libstdc++.so 。請改用libc++.so 。某些版本的獨立工具鏈可能會將-lstdc++添加到默認鏈接器標誌中。要禁用默認值,請將-nodefaultlibs -lc -lm -ldl添加到LDFLAGS
  • libz.so從 LL-NDK 移動到 VNDK-SP 庫。在某些配置中, libz.so可能繼續是 LL-NDK。但是,應該沒有可觀察到的差異。