供應商本機開發套件 (VNDK) 概述

供應商本機開發套件 (VNDK)是供應商或產品分區中的其他庫或二進位檔案在 dlopen 運行時使用的一組庫。

為什麼選擇 VNDK?

AOSP 允許僅框架更新,其中系統分區可以升級到最新的框架版本,而供應商分區保持不變。儘管是在不同時間建構的,但每個分區中的二進位必須能夠相互協作。

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

  • 框架模組和供應商模組之間的依賴性。在Android 8.0之前,供應商和系統分區中的模組可以相互連結。然而,來自供應商模組的依賴性為框架模組的開發帶來了不想要的限制。
  • AOSP 庫的擴充。 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 版本支援供應商模組:

  1. 穩定框架共享庫的 ABI/API 。新的框架模組和舊的供應商模組可以使用相同的共享庫來減少記憶體佔用和儲存大小。獨特的共享庫也避免了一些雙重載入問題。然而,維護穩定的 ABI/API 的開發成本很高,並且穩定每個框架共享庫導出的所有 ABI/API 是不切實際的。
  2. 複製舊框架共享庫。對側通道有嚴格的限制,側通道定義為框架模組和供應商模組之間通訊的所有機制,包括(但不限於)綁定器、套接字、管道、共享記憶體、共享檔案和系統屬性。除非通訊協定被凍結且穩定(例如透過 hwbinder 的 HIDL),否則不得進行通訊。雙重載入共享庫也可能會導致問題;例如,如果將新庫建立的物件傳遞到舊庫的函數中,則可能會發生錯誤,因為這些庫可能會以不同的方式解釋該物件。

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

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

同流程 HAL (SP-HAL)

同一進程 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 } 。如果也指定了vndk: {private:true} ,則這些函式庫稱為VNDK-SP-Private ,且它們對 SP-HALS 不可見。

以下是具有 RS 例外的純框架庫 (FWK-ONLY-RS)

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

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_CODENAMEREL ,請使用PLATFORM_SDK_VERSION (例如28 )。
    • 否則,請使用PLATFORM_VERSION_CODENAME (例如P )。

供應商測試套件 (VTS)

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