VNDK 扩展

Android 设备制造商出于各种原因更改 AOSP 库的源代码。一些供应商重新实现 AOSP 库中的函数以提高性能,而另一些供应商则向 AOSP 库添加新的钩子、新的 API 或新功能。本节提供了扩展 AOSP 库的指南,扩展方式应不会破坏 CTS/VTS。

直接替换

所有修改后的共享库都必须是 AOSP 对应库的二进制兼容直接替换。所有现有的 AOSP 用户都必须能够使用修改后的共享库,而无需重新编译。此要求意味着以下几点:

  • 不得移除 AOSP 函数。
  • 如果结构体向其用户公开,则不得更改结构体。
  • 不得加强函数的前提条件。
  • 函数必须提供等效的功能。
  • 不得削弱函数的后置条件。

扩展模块分类

按模块定义使用的功能对模块进行分类。

注意:此处使用功能而不是 API/ABI,因为有可能在不更改任何 API/ABI 的情况下添加功能。

根据模块中定义的功能,模块可以分为 DA 模块DX 模块

  • 仅定义 AOSP 模块 (DA 模块) 不定义 AOSP 对应库中没有的新功能。
    • 示例 1. 完好无损的未修改 AOSP 库是 DA 模块。
    • 示例 2. 如果供应商使用 SIMD 指令重写 libcrypto.so 中的函数(不添加新函数),则修改后的 libcrypto.so 将是 DA 模块。
  • 定义扩展模块 (DX 模块) 定义新功能,或者没有 AOSP 对应库。
    • 示例 1. 如果供应商向 libjpeg.so 添加一个辅助函数以访问某些内部数据,则修改后的 libjpeg.so 将是 DX 库,而新添加的函数将是库的扩展部分。
    • 示例 2. 如果供应商定义一个名为 libfoo.so 的非 AOSP 库,则 libfoo.so 将是 DX 库。

根据模块使用的功能,模块可以分为 UA 模块UX 模块

  • 仅使用 AOSP 模块 (UA 模块) 仅在其实现中使用 AOSP 功能。它们不依赖于任何非 AOSP 扩展。
    • 示例 1. 完好无损的未修改 AOSP 库是 UA 模块。
    • 示例 2. 如果修改后的共享库 libjpeg.so 仅依赖于其他 AOSP API,则它将是 UA 模块。
  • 使用扩展模块 (UX 模块) 在其实现中依赖于某些非 AOSP 功能。
    • 示例 1. 如果修改后的 libjpeg.so 依赖于另一个名为 libjpeg_turbo2.so 的非 AOSP 库,则修改后的 libjpeg.so 将是 UX 模块。
    • 示例 2. 如果供应商向其修改后的 libexif.so 添加一个新函数,并且他们修改后的 libjpeg.so 使用来自 libexif.so 的新添加函数,则他们修改后的 libjpeg.so 将是 UX 模块。

定义和用法彼此独立

使用的功能
仅 AOSP (UA) 扩展 (UX)
定义的功能 仅 AOSP (DA) DAUA DAUX
扩展 (DX) DXUA DXUX

VNDK 扩展机制

依赖于扩展功能的供应商模块将无法工作,因为具有相同名称的 AOSP 库不具有扩展功能。如果供应商模块直接或间接依赖于扩展功能,则供应商应将 DAUX、DXUA 和 DXUX 共享库复制到供应商分区(供应商进程始终首先在供应商分区中查找共享库)。但是,不得复制 LL-NDK 库,因此供应商模块不得依赖于修改后的 LL-NDK 库定义的功能。

如果相应的 AOSP 库可以提供相同的功能,并且当系统分区被通用系统映像 (GSI) 覆盖时供应商模块继续工作,则 DAUA 共享库可以保留在系统分区上。

直接替换非常重要,因为 GSI 中未修改的 VNDK 库将与名称冲突时修改后的共享库链接。如果 AOSP 库以 API/ABI 不兼容的方式修改,则 GSI 中的 AOSP 库可能无法链接或导致未定义的行为。