实现 USB HAL

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

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

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

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 型节点的所有权转移给系统。