Vendor Native Development Kit(VNDK)

Vendor Native Development Kit(VNDK)は、HAL を実装するベンダー専用のライブラリのセットです。VNDK は system.img に対応しており、実行時にベンダーコードに動的にリンクされます。

VNDK を使用する理由

Android 8.0 以降では、ベンダー パーティションを変更せずにシステム パーティションを最新バージョンにアップグレードできるフレームワークのみの更新が可能です。これは、異なる時間にビルドされたバイナリが相互に機能しなければならないことを意味します。VNDK は、Android リリース間の API や ABI の変更を扱います。

フレームワークのみの更新には、次のような問題があります。

  • フレームワーク モジュールとベンダー モジュール間の依存関係。 Android 8.0 以前では、両側からのモジュールは、反対側からのモジュールとリンクできました。しかし、ベンダー モジュールからの依存関係は、フレームワーク モジュールの開発に望ましくない制限を課していました。
  • AOSP ライブラリへの拡張機能。Android 8.0 以降では、システム パーティションが標準の Generic System Image(GSI)に置き換えられると、すべての Android デバイスが CTS に合格する必要があります。しかし、ベンダーが AOSP ライブラリを拡張して HIDL の実装にパフォーマンスや機能を追加すると、システム パーティションを標準の GSI でフラッシュするときにベンダーの HIDL 実装が破損する可能性があります(このような破損を防ぐためのガイドラインについては、VNDK 拡張機能をご覧ください)。

このような問題に対処するために、Android 8.0 では VNDK(このセクションで説明します)、HIDL、hwbinder、デバイスツリー オーバーレイ、sepolicy オーバーレイなど、複数の技術を導入しました。

VNDK のリソース

このセクションには、次の VNDK のリソースが含まれています。

  • VNDK のコンセプト(以下)では、フレームワークの共有ライブラリ、Same-Process HAL(SP-HAL)、VNDK の用語を説明します。
  • VNDK 拡張機能は、ベンダー固有の変更を複数のカテゴリに分類します。たとえば、ベンダー モジュールが依存する拡張機能のあるライブラリは、ベンダー パーティションにコピーする必要がありますが、ABI の互換性のない変更は禁止されています。
  • VNDK ビルドシステムのサポートでは、VNDK に関連するビルドシステム構成とモジュール定義構文について説明します。
  • VNDK 定義ツールは、ソースツリーを Android 8.0 以降に移行するのに役立ちます。
  • リンカー名前空間は、共有ライブラリのリンクを細かく制御します。
  • ディレクトリ、ルール、sepolicy は、Android 8.0 以降を搭載するデバイスのディレクトリ構造、VNDK のルール、関連する sepolicy を定義します。
  • VDNK の設計プレゼンテーションでは、Android 8.0 以降で使用される基本的な VDNK のコンセプトを説明します。

VNDK のコンセプト

フレームワーク プロセスがベンダーの共有ライブラリを読み込まず、すべてのベンダー プロセスがベンダーの共有ライブラリ(およびフレームワークの共有ライブラリの一部)のみを読み込み、フレームワーク プロセスとベンダー プロセス間の通信が HIDL とハードウェア バインダーによって管理されているのが、Android 8.0 以降の理想的な状況です。

このような状況では、API は Android リリース間で変更が可能であるものの、フレームワーク共有ライブラリの安定した公開 API がベンダー モジュールのデベロッパーには不十分である可能性があるため、フレームワーク共有ライブラリの一部がベンダー プロセスからアクセスできる必要あります。さらに、パフォーマンス要件の妥協につながる可能性があるため、応答時間が重視される HAL の一部は扱い方も異なる必要があります。

以下のセクションでは、VNDK でベンダーと Same-Process HAL(SP-HAL)のフレームワーク共有ライブラリを処理する方法について説明します。

ベンダー用のフレームワーク共有ライブラリ

このセクションでは、ベンダーのプロセスからアクセス可能な共有ライブラリを分類するための条件について説明します。複数の Android リリースでベンダー モジュールをサポートするには、2 つの方法があります。

  1. フレームワーク共有ライブラリの ABI や API を安定化させる。 新しいフレームワーク モジュールと古いベンダー モジュールは、同じ共有ライブラリを使用してメモリのフットプリントと保存容量を削減できます。また、独自の共有ライブラリは、複数の二重読み込みの問題を避けることもできます。しかし、安定した ABI や API を維持するとなると開発コストが高くつき、すべてのフレームワーク共有ライブラリでエクスポートされるすべての ABI や API を安定させるのは現実的ではありません。
  2. 古いフレームワークの共有ライブラリをコピーする。サイドチャネルに対する強力な制限があり、バインダーやソケット、パイプ、共有メモリ、共有ファイル、システム プロパティを含むフレームワーク モジュールとベンダー モジュール間で通信するためのすべてのメカニズムとして定義されます。通信プロトコルが固定され、安定してる場合を除き、通信はできません(例: hwbinder を通じた HIDL)。共有ライブラリを二重読み込みすると問題が発生する場合もあります。たとえば、新しいライブラリによって作成されたオブジェクトが古いライブラリの関数に渡された場合、これらのライブラリでオブジェクトの解釈が異なるため、エラーとなる可能性があります。

共有ライブラリの特性に応じて、異なる方法が使用されます。その結果、フレームワーク共有ライブラリは次の 3 つのサブカテゴリに分類されます。

  • 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)は、2 回コピーしても安全なフレームワーク共有ライブラリです。フレームワーク モジュールとベンダー モジュールは、それぞれ自身のコピーにリンクできます。フレームワーク共有ライブラリは、次の条件を満たす場合にのみ有効な VNDK ライブラリになります。
    • フレームワークとの間で IPC を送受信しない。
    • ART 仮想マシンとは関係がない。
    • 不安定なファイル形式でファイルやパーティションを読み書きしない。
    • 法的審査が必要な特別なソフトウェア ライセンスがない。
    • ベンダーの用途について、コード所有者からの異論がない。
  • フレームワークのみのライブラリ(FWK-ONLY)は、上記のカテゴリには属さないフレームワーク共有ライブラリです。これらのライブラリの特徴は次のとおりです。
    • フレームワーク内部実装の詳細と見なされます。
    • ベンダー モジュールからはアクセスできません。
    • 不安定な ABI や API があり、API と ABI の互換性は保証されません。
    • コピーされません。

Same-Process HAL(SP-HAL)

Same-Process HAL(SP-HAL)は、ベンダー共有ライブラリとして実装され、フレームワーク プロセスに読み込まれた、事前決定済み 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 } を指定します。vendor_available: false も指定されている場合、これらのライブラリは VNDK-SP-Private と呼ばれ、SP-HALS には表示されません。

以下は、RS 例外を含むフレームワークのみのライブラリ(FWK-ONLY-RS)です

  • libft2.so(Renderscript)
  • libmediandk.so(Renderscript)

VNDK の用語

  • モジュールは、共有ライブラリまたは実行可能ファイルを指します。
  • プロセスは、実行可能ファイルから生成されるオペレーティング システムのタスクです。
  • フレームワークが修飾された用語は、システム パーティションに関連するコンセプトを指します。
  • ベンダーが修飾された用語は、ベンダー パーティションに関連するコンセプトを指します。

たとえば、次のようになります。

  • フレームワーク実行可能ファイルは、/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_VERSIONcurrent と等しくない場合は、BOARD_VNDK_VERSION を使用します。
  • BOARD_VNDK_VERSIONcurrent と等しい場合は次のようになります。
    • PLATFORM_VERSION_CODENAMEREL の場合は、PLATFORM_SDK_VERSION を使用します(例: 28)。
    • それ以外の場合は、PLATFORM_VERSION_CODENAME を使用します(例: P)。

デバイスのアップグレード

VNDK ランタイムが BOARD_VNDK_VERSION なしでビルドされたことにより、Android 8.x デバイスで VNDK ランタイムの適用が無効になっている場合、Android 9 へのアップグレードの際に PRODUCT_USE_VNDK_OVERRIDE := falseBoardConfig.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 := falseBoardConfig.mk に追加します。

ベンダー テストスイート(VTS)

Android 9 のベンダー テストスイート(VTS)は、空ではない ro.vndk.version プロパティを必須としています。新たにリリースされたデバイスとアップグレードするデバイスの両方で ro.vndk.version を定義する必要があります。一部の VNDK テストケース(例: VtsVndkFilesTestVtsVndkDependencyTest)は、一致する有効な VNDK ライブラリ データセットを読み込むために ro.vndk.version プロパティに依存します。

ro.product.first_api_level プロパティが 27 より大きい場合、ro.vndk.lite プロパティを定義することはできません。ro.vndk.lite が新たにリリースされた Android 9 を搭載するデバイスで定義されている場合、VtsTreblePlatformVersionTest は失敗します。

ドキュメントの履歴

このセクションでは、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 が削除されました。

Android 8.1 の変更点

  • SP-NDK ライブラリが LL-NDK ライブラリに統合されました。
  • RS 名前空間セクションの libui.solibft2.so に置き換えられました。libui.so を含めるエラーがありました。
  • libGLESv3.solibandroid_net.so が LLK-NDK ライブラリに追加されました。
  • libion.so が VNDK-SP ライブラリに追加されました。
  • libstdc++.so が LL-NDK ライブラリから削除されました。代わりに libc++.so を使用してくださいスタンドアロン ツールチェーンの一部のバージョンでは、-lstdc++ がデフォルトのリンカーフラグに追加されています。デフォルトを無効にするために、-nodefaultlibs -lc -lm -ldlLDFLAGS に追加されました。
  • libz.so が LL-NDK から VNDK-SP ライブラリに移動されました。一部の構成では、libz.so が LL-NDK として引き続き使用されます。ただし、認識できる違いはありません。