实现 USB HAL

Android 8.0 版本将 USB 命令的处理从 init 脚本移到了原生 USB 守护程序,以改进配置并提高代码可靠性。对于 Gadget 函数配置,系统会使用 init 脚本(属性触发器)执行设备专属的小工具操作。

在以前的版本中,这些设备专属的配置通过设备专属的 init 脚本(使用属性触发器)来实现。移至硬件抽象层 (HAL) 的设计可以带来一种更简洁的实现,这种实现能够解决以下问题:

  1. 操作(例如写入到内核 sysfs 节点)可能会失败,但系统不会将操作结果传回设置属性触发器的框架代码。因此,框架会误认为这些操作已成功,即使它们已静默失败也是如此。
  2. init 脚本包含的可执行的操作数量有限。

Android 12 版本添加了对网络控制模型 (NCM) 和 API 调用(返回 HAL 版本号和 USB 速度)的 USB Gadget HAL 支持。如需详细了解可通过 USB HAL 执行的 API 调用,请参阅 android.hardware.usb 软件包摘要

HAL 和 Treble

过去,系统使用设备专属的 init 脚本替代 HAL 层来执行设备专属的 USB 操作。USB(通过 ADB)是用于调试系统问题的主要接口。让原生守护程序执行 USB 配置可以消除对框架代码的依赖,这样即使框架崩溃,USB 也应该能够正常运行。

Android 8.0 中还引入了 Treble 模型,在该模型下,所有 HAL 都与系统服务隔离开来,并且都需要在各自的原生守护程序中运行。这样就不需要使用专有的 USB 守护程序,因为 HAL 层可兼做 USB 守护程序。

默认 HAL 实现支持 Android 版本低于 8.0 的所有设备。因此,对于这些设备,不需要执行任何设备专属的工作。Android 8.0 使用 HAL 接口查询 USB 端口的状态,以及执行数据角色和电源角色交换。

实现

需要在搭载 Android 8.0 的每台设备上实现新的 USB HAL 接口。默认实现应支持 Android 版本低于 8.0 的设备。如果设备使用 dual_role_usb 类来报告 C 型端口的状态,默认实现便足以满足需求。可能需要在设备专属的 USB 脚本中进行细微的更改,以便将 C 型节点的所有权转移给系统。