Android 开放式配件 1.0

Android USB 配件必须遵守 Android 开放式配件 (AOA) 协议,该协议定义了配件如何检测 Android 设备并与其建立通信。配件应执行以下步骤

  1. 等待并检测已连接的设备。
  2. 确定设备对配件模式的支持。
  3. 尝试在配件模式下启动设备(如果需要)。
  4. 如果设备支持 AOA,则与设备建立通信。

以下部分介绍了如何实现这些步骤。

等待并检测已连接的设备

配件应持续检查是否有已连接的 Android 设备。当设备连接后,配件应确定设备是否支持配件模式。

确定配件模式支持

注意:连接配件不需要 USB 调试,但在开发期间可能需要 ADB。有关详情,请参阅调试注意事项

当 Android 设备连接时,它可以处于以下三种状态之一

  • 支持 Android 配件模式,并且已处于配件模式。
  • 支持 Android 配件模式,但未处于配件模式。
  • 不支持 Android 配件模式。

在初始连接期间,配件应检查已连接设备的 USB 设备描述符的版本、供应商 ID 和产品 ID。供应商 ID 应与 Google 的 ID (0x18D1) 匹配。如果设备已处于配件模式,则产品 ID 应为 0x2D000x2D01,并且配件可以通过批量传输端点使用自己的通信协议与设备建立通信(设备无需在配件模式下启动)。

注意: 0x2D00 保留给支持配件模式的 Android 设备。0x2D01 保留给支持配件模式以及 Android 调试桥 (ADB) 协议的设备,该协议公开了第二个接口,其中包含两个用于 ADB 的批量端点。如果您在计算机上模拟配件,则可以使用这些端点来调试配件应用程序。通常,除非配件在设备上实现到 ADB 的直通,否则请勿使用此接口。

如果 USB 设备描述符中的版本、供应商 ID 或产品 ID 与预期值不匹配,则配件无法确定设备是否支持 Android 配件模式。配件应尝试在配件模式下启动设备(详见下文),以确定设备是否支持。

要点: USB 配件必须在初始握手时发送标头。标头包含制造商、型号和版本。虽然版本是可选字段,但如果安装的 Android 应用仅与版本匹配,但配件未发送版本,则运行 Android 10 及更低版本的 Android 设备将由于系统进程中抛出的异常而重启。

尝试在配件模式下启动

如果版本、供应商和产品 ID 与处于配件模式的 Android 设备不对应,则配件无法确定设备是否支持(但未处于)配件模式,或者设备是否不支持配件模式。发生这种情况的原因可能是,支持配件模式(但未处于配件模式)的设备最初报告的是设备制造商的供应商和产品 ID,而不是 AOA 的供应商和产品 ID。

配件应尝试在配件模式下启动设备,以确定设备是否支持该模式

  1. 发送 51 控制请求(“Get Protocol”),以确定设备是否支持 Android 配件协议。如果设备支持该协议,则会返回一个非零数字,表示支持的协议版本。控制请求在端点 0 上,具有以下特征
    requestType:    USB_DIR_IN | USB_TYPE_VENDOR
    request:        51
    value:          0
    index:          0
    data:           protocol version number (16 bits little endian sent from the
                    device to the accessory)
    
  2. 如果设备返回支持的协议版本,则向设备发送包含识别字符串信息的控制请求。此信息允许设备确定适合配件的应用程序(或者,如果不存在合适的应用程序,则向用户显示 URL)。控制请求在端点 0 上(对于每个字符串 ID),具有以下特征
    requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
    request:        52
    value:          0
    index:          string ID
    data            zero terminated UTF8 string sent from accessory to device
    

    支持以下字符串 ID,每个字符串的最大大小为 256 字节(必须以 \0 结尾)。

    manufacturer name:  0
    model name:         1
    description:        2
    version:            3
    URI:                4
    serial number:      5
    
  3. 发送控制请求,以请求设备在配件模式下启动。控制请求在端点 0 上,具有以下特征
    requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
    request:        53
    value:          0
    index:          0
    data:           none
    

完成这些步骤后,配件应等待连接的 USB 设备在总线上以配件模式重新引入自身,然后重新枚举连接的设备。该算法通过检查供应商和产品 ID 来确定配件模式支持,如果设备成功切换到配件模式,则这些 ID 应该是正确的(例如,对应于 Google 的供应商和产品 ID,而不是设备制造商的 ID)。如果 ID 和版本正确,则配件将转到建立与设备的通信

注意: AOA 当前不支持同时进行 AOA 和 MTP 连接。要从 AOA 切换到 MTP,配件必须首先断开 USB 设备连接(物理断开或以电学等效方式断开),然后使用 MTP 重新连接。

如果任何步骤失败,则配件确定设备不支持 Android 配件模式,并等待下一个设备连接。

建立与设备的通信

如果配件检测到处于配件模式的 Android 设备,则配件可以查询设备接口和端点描述符,以获取用于与设备通信的批量端点。

接口和批量端点的数量取决于产品 ID。产品 ID 为

  • 0x2D00 的 Android 设备具有一个接口,其中包含两个用于输入和输出通信的批量端点。
  • 0x2D01 的设备具有两个接口,每个接口包含两个用于输入和输出通信的批量端点。第一个接口处理标准通信,第二个接口处理 ADB 通信。要使用接口,请找到第一个批量输入和输出端点,使用 SET_CONFIGURATION (0x09) 设备请求将设备配置设置为值 1,然后使用端点进行通信。