Android Open Accessory 1.0

Android USB アクセサリーは、Android Open Accessory(AOA)プロトコルに準拠する必要があります。AOA プロトコルは、アクセサリーによる Android 搭載デバイスとの通信の検出方法と設定方法を定義したものです。アクセサリーは次の手順に従う必要があります。

  1. デバイスとの接続を待ち、検出します。
  2. デバイスがアクセサリー モードをサポートしているか判別します。
  3. 必要に応じて、デバイスをアクセサリー モードで起動させます。
  4. デバイスが AOA をサポートしていれば、デバイスとの通信を確立します。

以降のセクションでは、これらの手順の実装方法について説明します。

デバイス接続を待機して検出する

アクセサリーは、Android 搭載デバイスとの接続を継続的に確認する必要があります。デバイスが接続されたら、デバイスがアクセサリー モードをサポートしているかどうかを判別します。

アクセサリー モードのサポートを判別する

注: アクセサリーの接続に USB デバッグは必要ありませんが、開発中は ADB が必要になる場合があります。詳しくは、デバッグに関する考慮事項をご覧ください。

Android 搭載デバイスが接続されると、次の 3 つの状態のいずれかになります。

  • Android アクセサリー モードをサポートしており、アクセサリー モードになっている。
  • Android アクセサリー モードをサポートしているが、アクセサリー モードにはなっていない。
  • Android アクセサリー モードをサポートしていない。

アクセサリーは、最初の接続時に、接続されたデバイスの USB デバイス記述子に含まれているバージョン、ベンダー ID、プロダクト ID を確認します。ベンダー ID は Google の ID(0x18D1)と一致する必要があります。デバイスがすでにアクセサリー モードになっている場合、プロダクト ID は 0x2D00 または 0x2D01 でなければなりません。アクセサリーは独自の通信プロトコルを使用して、一括転送エンドポイント経由でデバイスとの通信を確立できます(デバイスをアクセサリー モードで起動する必要はありません)。

注: 0x2D00 は、アクセサリー モードをサポートする Android 搭載デバイス用に予約された ID です。0x2D01 は、アクセサリー モードと Android Debug Bridge(ADB)プロトコルをサポートするデバイス用に予約された ID です。このプロトコルは、ADB 用の 2 つの一括エンドポイントを持つ第 2 のインターフェースを公開します。パソコンでアクセサリーをシミュレートする場合は、これらのエンドポイントを使用してアクセサリー アプリをデバッグできます。一般的に、アクセサリーがデバイス上で ADB へのパススルーを実装していない限り、このインターフェースは使用しません。

USB デバイス記述子のバージョン、ベンダー ID、プロダクト ID が予想される値と一致しない場合、デバイスが Android アクセサリー モードをサポートしているかどうかをアクセサリーが判別することはできません。アクセサリーは、デバイスのサポートを判別するためにデバイスをアクセサリー モードで起動しようと試みます(詳細は下記を参照)。

重要なポイント: USB アクセサリーは、最初の handshake 時にヘッダーを送信する必要があります。ヘッダーには、メーカー、モデル、バージョンが含まれています。バージョンは省略可能なフィールドですが、バージョンのみで一致する Android アプリをインストールしても、アクセサリーがバージョンを送信しない場合、Android 10 以前を搭載した Android デバイスは、システム プロセスでスローされている例外により再起動します。

アクセサリー モードで起動を試みる

バージョン、ベンダー ID、プロダクト ID がアクセサリー モードの Android 搭載デバイスに対応していない場合、デバイスがアクセサリー モードをサポートしている(ただし、そのモードになっていない)のかサポートしていないのかをアクセサリーが判別することはできません。これは、アクセサリー モードをサポートする(ただし、そのモードになっていない)デバイスが最初に報告するのはデバイス メーカーのベンダー ID とプロダクト ID であり、AOA のベンダー ID とプロダクト ID ではないためです。

アクセサリーは、デバイスがアクセサリー モードをサポートしているかどうかを判別するため、デバイスをアクセサリー モードで起動しようと試みます。

  1. デバイスが Android アクセサリー プロトコルをサポートしているかどうかを判別するには、コントロール リクエスト 51(GET プロトコル)を送信します。デバイスがこのプロトコルをサポートしていれば、サポートしているプロトコル バージョンを表すゼロ以外の数値を返します。コントロール リクエストはエンドポイント 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 をユーザーに提示します)。コントロール リクエストは各文字列 ID ごとにエンドポイント 0 にあり、次の特性を持ちます。
    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 を確認することでアクセサリー モードのサポートを判別しています。デバイスがアクセサリー モードへの切り替えに成功した場合、これらの ID は正しい(デバイス メーカーの ID ではなく、Google のベンダー ID とプロダクト ID に対応している)はずです。ID とバージョンが正しければ、アクセサリーはデバイスとの通信を確立するステップに進みます。

注: 現在、AOA は AOA と MTP の同時接続をサポートしていません。AOA から MTP に切り替えるには、USB デバイスを物理的に取り外すか電源を切断してから、MTP を使用して再接続します。

いずれかのステップが失敗した場合、アクセサリーはデバイスが Android アクセサリー モードをサポートしていないと判断し、別のデバイスが接続されるのを待ちます。

デバイスとの通信を確立する

アクセサリーは、アクセサリー モードの Android 搭載デバイスを検出すると、デバイスのインターフェース記述子とエンドポイント記述子をクエリして、デバイスと通信するための一括エンドポイントを取得します。

インターフェースと一括エンドポイントの数は、次に示すように、Android 搭載デバイスのプロダクト ID によって異なります。

  • プロダクト ID が 0x2D00 の場合、インターフェースは 1 つで、入力および出力通信用に 2 つの一括エンドポイントがあります。
  • プロダクト ID が 0x2D01 の場合、インターフェースは 2 つで、入力および出力通信用にそれぞれ 2 つの一括エンドポイントがあります。第 1 のインターフェースは標準の通信を処理し、第 2 のインターフェースは ADB 通信を処理します。インターフェースを使用するには、第 1 の一括入力 / 出力エンドポイントを見つけて、SET_CONFIGURATION0x09)デバイス リクエストによりデバイス設定の値を 1 に設定し、エンドポイントを使用して通信を行います。