Android 8.0 版本将 USB 命令的处理从 init
脚本移至原生 USB 守护进程,以提高配置和代码可靠性。对于 Gadget 功能配置,init
脚本(属性触发器)用于执行设备专用的 Gadget 操作。
在之前的版本中,这些设备专用配置是通过设备专用的 init
脚本(使用属性触发器)实现的。迁移到硬件抽象层 (HAL) 设计后,实现方式更加简洁,并解决了以下问题
- 写入内核 sysfs 节点等操作可能会失败,但不会传播回设置属性触发器的框架代码。因此,即使操作已静默失败,框架也会错误地假定操作已成功。
init
脚本可以执行的操作数量有限。
Android 12 版本为网络控制模型 (NCM) 添加了 USB Gadget HAL 支持,以及返回 HAL 版本号和 USB 速度的 API 调用。如需详细了解可通过 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 之前的设备,不会有任何设备特定的工作。Android 8.0 使用 HAL 接口来查询 USB 端口的状态,并执行数据角色和电源角色交换。
实现
每个在 Android 8.0 上启动的设备都需要实现新的 USB HAL 接口。默认的实现应该负责处理 Android 8.0 之前的设备。如果设备使用 dual_role_usb
类来报告 type-c 端口状态,则默认实现就足够了。可能需要在设备特定的 USB 脚本中进行微小的更改,以将 typc-c 节点的所有权转移给系统。