首页 > 解决方案 > 在 Android 供应商软件中使用 AHardwareBuffer_fromHardwareBuffer()?

问题描述

我正在实现一个 Android ODM 系统。我想创建一个围绕ImageReader构建的VirtualDisplay,以便提供虚拟显示的进程将接收来自 SurfaceFlinger 的一系列帧作为HardwareBuffer实例。

目的是通过使用AHardwareBuffer_fromHardwareBuffer()获取每个接收到的 HardwareBuffer 的 Linux dmabuf 句柄以获取相应的本机对象,然后使用 eglCreateNativeClientBufferANDROID() 将其转换为 EGLImage,最后使用eglExportDMABUFImageMESA()获取 dmabuf 文件描述符。

API 的关键部分——AHardwareBuffer_fromHardwareBuffer()——位于名为“libandroid”的本机库中。Google 文档(参见https://source.android.com/devices/architecture/images/vndk_design_android_o.pdf)明确指出禁止供应商程序在 libandroid 中使用 API。

这看起来很奇怪,因为 libandroid 已经暴露在应用程序 NDK 中。我认为这意味着 libandroid 已经要求所有未来 Android 版本的向后可移植性。

是否有任何现有方法可以使我的供应商程序链接到此 API?如果没有,AHardwareBuffer_fromHardwareBuffer() 是否可以像其他一些与 AHardwareBuffer 相关的本机 C++ API 一样迁移到 VNDK?

更新:

这是一项预安装的服务,需要(除了执行这些 VirtualDisplay 和 ImageReader 机制之外)与我的客户正在实施的自定义 HAL 进行一些交互(因此:不是任何实现标准 Google HIDL 接口之一的东西)。

我认为这让我们需要预先安装到 /vendor 分区,对吧?我不知道从技术上讲这是否使我成为“VNDK 进程”,但是在我将“vendor: true”放入蓝图文件的任何时候,对链接到 libandroid 的限制都会生效。

这个预安装的服务位于 AOSP 树中,因为我想使用平台密钥对其进行签名,以便该服务可以在 AndroidManifest.xml 中设置其android:persistent属性,以避免它被 ActivityManager 任意关闭。

如果这个 VirtualDisplay 没有最终被实例化,其他预安装的应用程序将会很糟糕。我不确定这对 GSI 意味着什么。也许您可能会说,安装了用于测试的 GSI 映像后,其他预安装的应用程序也不存在,因此没有问题。

标签: androidsurfaceflinger

解决方案


这个过程是不是恰好预装在设备上的常规应用程序(提供活动、服务等的 APK)?我想如果您使用的是 VirtualDisplay 和 ImageReader。如果是这样,使用libandroid应该没有问题。

对 libandroid 的限制专门针对 VNDK 进程,即系统的较低级别部分。存在限制是因为 libandroid 中的一些东西依赖于 Android 框架、ART 运行时等,以及它们的未版本化和非固定内部接口。因此,VNDK 可用库的通常版本控制(实际上来自旧版本操作系统的 vndk 二进制文件必须在较新版本的操作系统上运行)不适用于 libandroid,因为这些依赖于不稳定的内部接口。

但是,如果您正在编写位于框架之上并且仅使用公共 API 的东西,那么它就不是 VNDK 进程,并且这些限制不适用。

(注:我在 Android 上工作,并参与了 AHardwareBuffer API。但我不是 VNDK 专家,也不是供应商流程和供应商预装应用程序规则方面的专家。所以这反映了我个人的理解,而不是Android团队的官方声明:如果有官方文档与我所说的相矛盾,那可能是对的,我错了。)


推荐阅读