Accesorio abierto de Android 2.0

En este documento, se describen los cambios en el protocolo de Android Open Accessory (AOA) desde su lanzamiento inicial y se complementa la documentación de AOA 1.0. AOAv2 agrega las siguientes funciones:

  • Salida de audio (que dejó de estar disponible en Android 8.0)
  • Compatibilidad con el accesorio que actúa como uno o más dispositivos de interfaz humana (HID) para el dispositivo Android

Las APIs del SDK de Android disponibles para los desarrolladores de apps para Android no se modificaron.

Cómo detectar la compatibilidad con AOAv2

Para determinar si un dispositivo Android conectado admite accesorios y la versión del protocolo compatible, un accesorio debe enviar un comando getProtocol() y verificar el resultado. Los dispositivos Android que solo admiten las funciones de AOAv1 deben mostrar 1 como la versión del protocolo. Los dispositivos que admiten las funciones adicionales de AOAv2 deben mostrar 2 como la versión del protocolo. AOAv2 es retrocompatible con AOAv1, por lo que los accesorios diseñados para el protocolo de accesorios original siguen funcionando con dispositivos Android más nuevos.

En el siguiente ejemplo de la biblioteca del código fuente (<adk-src>/adk1/board/AndroidAccessory/AndroidAccessory.cpp) del kit de desarrollo de accesorios de 2011, se muestra esta verificación de protocolo:

bool AndroidAccessory::switchDevice(byte addr)
{
    int protocol = getProtocol(addr);
    if (protocol >= 1) {
        Serial.print("device supports protocol 1 or higher\n");
    } else {
        Serial.print("could not read device protocol version\n");
        return false;
    }

    sendString(addr, ACCESSORY_STRING_MANUFACTURER, manufacturer);
    sendString(addr, ACCESSORY_STRING_MODEL, model);
    sendString(addr, ACCESSORY_STRING_DESCRIPTION, description);
    sendString(addr, ACCESSORY_STRING_VERSION, version);
    sendString(addr, ACCESSORY_STRING_URI, uri);
    sendString(addr, ACCESSORY_STRING_SERIAL, serial);

    usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR |
                USB_SETUP_RECIPIENT_DEVICE, ACCESSORY_START, 0, 0, 0, 0, NULL);
    return true;
}

AOAv2 incluye nuevos IDs de productos USB para cada combinación de interfaces USB disponibles en el modo de accesorio:

Versión ID del producto Comunicación Descripción
AOAv1 0x2D00 accesorio Proporciona dos extremos masivos para comunicarse con una app para Android.
0x2D01 accesorio + adb Para depurar durante el desarrollo de accesorios. Solo está disponible si el usuario habilitó la depuración por USB en la configuración del dispositivo Android.
AOAv2 0x2D02 Audio Para transmitir audio desde un dispositivo Android a un accesorio.
0x2D03 audio + adb
0x2D04 accesorio + audio
0x2D05 accesorio + audio + adb

Los IDs de productos que se usan en AOAv1 (0x2D00 y 0x2D01) siguen siendo compatibles con AOAv2.

Compatibilidad con audio

AOAv2 incluye compatibilidad con la salida de audio de un dispositivo Android a un accesorio a través de una interfaz de clase de audio USB estándar capaz de audio PCM de 2 canales y 16 bits con una tasa de bits de 44100 KHz (es posible que se agreguen modos de audio adicionales en el futuro).

Para habilitar la compatibilidad con audio, el accesorio debe enviar una nueva solicitud de control USB:

**SET_AUDIO_MODE**
requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
request:        58
value:          0 for no audio (default),
                1 for 2 channel, 16-bit PCM at 44100 KHz
index:          0
data            none

Este comando se debe enviar antes de enviar el comando ACCESSORY_START para ingresar al modo de accesorio.

Compatibilidad con HID

AOAv2 permite que los accesorios registren uno o más dispositivos de interfaz humana (HID) USB con un dispositivo Android. Este enfoque invierte la dirección de comunicación de los dispositivos HID USB típicos, como los mouse y teclados USB. Por lo general, el dispositivo HID es un periférico conectado a un host USB (es decir, una computadora personal), pero en AOA, el host USB puede actuar como uno o más dispositivos de entrada para un periférico USB.

La compatibilidad con HID es un proxy para eventos HID estándar. La implementación no hace suposiciones sobre el contenido o el tipo de eventos y simplemente lo pasa al sistema de entrada, lo que permite que un accesorio de AOAv2 actúe como cualquier dispositivo HID (mouse, teclado, control de juegos, etc.). Puedes usar la compatibilidad con HID para proporcionar funciones básicas, como un botón de reproducción/pausa en una estación de carga multimedia, o funciones avanzadas, como una estación de carga con un mouse y un teclado QWERTY completo.

AOAv2 agrega nuevas solicitudes de control USB que permiten que el accesorio actúe como uno o más dispositivos de entrada HID en el dispositivo Android. La compatibilidad con HID se controla completamente a través de solicitudes de control en el extremo cero, por lo que no se necesita una interfaz USB nueva. Las cuatro solicitudes de control nuevas son las siguientes:

  • ACCESSORY_REGISTER_HID registra un nuevo dispositivo HID con el dispositivo Android. El accesorio proporciona un ID que se usa para identificar el dispositivo HID para las otras tres llamadas. Este ID es válido hasta que se desconecta el USB o hasta que el accesorio envía ACCESSORY_UNREGISTER_HID para anular el registro del dispositivo HID.
  • ACCESSORY_UNREGISTER_HID cancela el registro de un dispositivo HID que se registró anteriormente con ACCESSORY_REGISTER_HID.
  • ACCESSORY_SET_HID_REPORT_DESC envía un descriptor de informe para un dispositivo HID al dispositivo Android. Esta solicitud se usa para describir las capacidades del dispositivo HID y se debe enviar antes de informar cualquier evento HID al dispositivo Android. Si el descriptor de informe es mayor que el tamaño máximo del paquete para el extremo cero, se envían varios comandos ACCESSORY_SET_HID_REPORT_DESC para transferir todo el descriptor.
  • ACCESSORY_SEND_HID_EVENT envía eventos de entrada del accesorio al dispositivo Android.

Las definiciones de código para las nuevas solicitudes de control son las siguientes:

/* Control request for registering a HID device.
 * Upon registering, a unique ID is sent by the accessory in the
 * value parameter. This ID will be used for future commands for
 * the device
 *
 *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
 *  request:        ACCESSORY_REGISTER_HID_DEVICE
 *  value:          Accessory assigned ID for the HID device
 *  index:          total length of the HID report descriptor
 *  data            none
 */
#define ACCESSORY_REGISTER_HID         54

/* Control request for unregistering a HID device.
 *
 *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
 *  request:        ACCESSORY_REGISTER_HID
 *  value:          Accessory assigned ID for the HID device
 *  index:          0
 *  data            none
 */
#define ACCESSORY_UNREGISTER_HID         55

/* Control request for sending the HID report descriptor.
 * If the HID descriptor is longer than the endpoint zero max packet size,
 * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC
 * commands. The data for the descriptor must be sent sequentially
 * if multiple packets are needed.
 *
 *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
 *  request:        ACCESSORY_SET_HID_REPORT_DESC
 *  value:          Accessory assigned ID for the HID device
 *  index:          offset of data in descriptor
 *                      (needed when HID descriptor is too big for one packet)
 *  data            the HID report descriptor
 */
#define ACCESSORY_SET_HID_REPORT_DESC         56

/* Control request for sending HID events.
 *
 *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
 *  request:        ACCESSORY_SEND_HID_EVENT
 *  value:          Accessory assigned ID for the HID device
 *  index:          0
 *  data            the HID report for the event
 */
#define ACCESSORY_SEND_HID_EVENT         57

Interoperabilidad con AOAv1

El protocolo original (AOAv1) proporciona compatibilidad para que una app para Android se comunique directamente con un host USB (accesorio) a través de USB. AOAv2 continúa con esta compatibilidad y agrega nuevas funciones para permitir que el accesorio se comunique con el sistema operativo Android (en especial, los sistemas de entrada y audio). El diseño de AOAv2 permite compilar un accesorio que usa la nueva compatibilidad con audio y HID, además del conjunto de funciones original. Solo usa las funciones nuevas junto con las originales.

Cómo conectar AOAv2 sin una app para Android

Puedes diseñar un accesorio (como una estación de carga de audio) que use compatibilidad con audio y HID, pero que no se comunique con una app en el dispositivo Android. En el caso de estos accesorios, los usuarios no necesitan recibir mensajes de diálogo para encontrar y asociar el accesorio recién conectado con una app para Android que pueda comunicarse con él.

Para suprimir esos diálogos después de que se conecta un accesorio, este puede optar por no enviar los nombres del fabricante y el modelo al dispositivo Android. Cuando no se proporcionan estas cadenas al dispositivo Android, ocurre lo siguiente:

  • El sistema no intenta encontrar una app para comunicarse con el accesorio.
  • La interfaz USB del accesorio no está presente en la configuración USB del dispositivo Android después de que este entra en modo de accesorio.