Android Open Accessory 2.0

В этом документе описаны изменения в протоколе Android Open Accessory (AOA) с момента его первого выпуска. Он дополняет документацию по AOA 1.0. AOAv2 добавляет следующие функции:

  • Аудиовыход (устаревший параметр в Android 8.0).
  • Поддержка аксессуара, действующего как одно или несколько HID-устройств для устройства Android.

API Android SDK, доступные разработчикам приложений для Android, не изменились.

Как определить, поддерживается ли AOAv2

Чтобы определить, поддерживает ли подключенное устройство Android аксессуары и версию протокола, аксессуар должен отправить команду getProtocol() и проверить результат. Устройства Android, поддерживающие только функции AOAv1, должны возвращать 1 в качестве версии протокола, а устройства, поддерживающие дополнительные функции AOAv2, – 2. Протокол AOAv2 обратно совместим с AOAv1, поэтому аксессуары, разработанные для оригинального протокола, продолжают работать с новыми устройствами Android.

В следующем примере из библиотеки Accessory Development Kit 2011 исходного кода (<adk-src>/adk1/board/AndroidAccessory/AndroidAccessory.cpp) показана проверка протокола:

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 добавлены новые идентификаторы USB-устройств для каждого сочетания USB-интерфейсов, доступных в режиме аксессуара:

Версия Идентификатор продукта Общение и связь Описание
AOAv1 0x2D00 аксессуар Предоставляет две конечные точки для массовой передачи данных, чтобы взаимодействовать с приложением Android.
0x2D01 аксессуар + ADB Для отладки при разработке аксессуаров. Доступно, только если пользователь включил отладку по USB в настройках устройства Android.
AOAv2 0x2D02 аудио Для потоковой передачи аудио с устройства Android на аксессуар.
0x2D03 аудио + adb
0x2D04 аксессуар + аудио
0x2D05 аксессуар + аудио + ADB

Идентификаторы товаров, используемые в AOAv1 (0x2D00 и 0x2D01), по-прежнему поддерживаются в AOAv2.

Функции для людей с нарушениями слуха

AOAv2 поддерживает вывод звука с устройства Android на аксессуар через стандартный интерфейс аудиокласса USB, способный передавать двухканальный 16-битный звук PCM с битрейтом 44 100 кГц (в будущем могут быть добавлены дополнительные аудиорежимы).

Чтобы включить поддержку аудио, аксессуар должен отправить новый запрос на управление по 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

Эту команду нужно отправить до отправки команды ACCESSORY_START для перехода в режим аксессуара.

Поддержка HID-устройств

AOAv2 позволяет аксессуарам регистрировать одно или несколько USB-устройств HID на устройстве Android. Этот подход меняет направление связи для обычных HID-устройств USB, таких как мыши и клавиатуры. Обычно устройство HID – это периферийное устройство, подключенное к хосту USB (например, персональному компьютеру), но в AOA хост USB может выступать в качестве одного или нескольких устройств ввода для периферийного устройства USB.

Поддержка HID – это прокси для стандартных событий HID. Реализация не делает никаких предположений о содержании или типе событий и просто передает их в систему ввода, позволяя аксессуару AOAv2 действовать как любое HID-устройство (мышь, клавиатура, игровой контроллер и т. д.). Поддержка HID позволяет использовать как базовые функции, например кнопку воспроизведения/паузы на док-станции, так и расширенные, например док-станцию с мышью и полноценной клавиатурой QWERTY.

В AOAv2 добавлены новые запросы управления USB, которые позволяют аксессуару действовать как одно или несколько HID-устройств ввода для устройства Android. Поддержка HID полностью обрабатывается через запросы управления на конечной точке 0, поэтому новый USB-интерфейс не требуется. Четыре новых запроса на управление:

  • ACCESSORY_REGISTER_HID регистрирует новое HID-устройство на устройстве Android. Аксессуар предоставляет идентификатор, который используется для идентификации HID-устройства в трех других вызовах. Этот идентификатор действителен до отключения USB или до тех пор, пока аксессуар не отправит ACCESSORY_UNREGISTER_HID для отмены регистрации HID-устройства.
  • ACCESSORY_UNREGISTER_HID отменяет регистрацию HID-устройства, ранее зарегистрированного с помощью ACCESSORY_REGISTER_HID.
  • ACCESSORY_SET_HID_REPORT_DESC отправляет дескриптор отчета для HID-устройства на устройство Android. Этот запрос используется для описания возможностей устройства HID и должен быть отправлен до того, как будут переданы какие-либо события HID на устройство Android. Если дескриптор отчета больше максимального размера пакета для конечной точки 0, для передачи всего дескриптора отправляется несколько команд ACCESSORY_SET_HID_REPORT_DESC.
  • ACCESSORY_SEND_HID_EVENT отправляет события ввода с аксессуара на устройство Android.

Определения кодов для новых запросов управления:

/* 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

Совместимость с AOAv1

Исходный протокол (AOAv1) позволяет приложению Android напрямую взаимодействовать с хостом USB (аксессуаром) через USB. AOAv2 продолжает эту поддержку и добавляет новые функции, позволяющие аксессуару взаимодействовать с самой ОС Android (в частности, с аудиосистемой и системой ввода). Благодаря архитектуре AOAv2 можно создать аксессуар, который будет поддерживать новые функции аудио и HID, а также исходный набор функций. Просто используйте новые функции вместе с исходными.

Как подключить AOAv2 без приложения Android

Вы можете создать аксессуар (например, аудиодок-станцию), который поддерживает аудио и HID, но не взаимодействует с приложением на устройстве Android. В этом случае пользователям не нужно будет получать диалоговые окна с запросом на поиск и связывание нового аксессуара с приложением Android, которое может с ним взаимодействовать.

Чтобы после подключения аксессуара такие диалоговые окна не появлялись, аксессуар может не отправлять названия производителя и модели на устройство Android. Если эти строки не передаются на устройство Android:

  • Система не пытается найти приложение для связи с аксессуаром.
  • После того как устройство Android переходит в режим аксессуара, USB-интерфейс аксессуара отсутствует в конфигурации USB-устройства Android.