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 כגרסת הפרוטוקול. מכשירי Android שתומכים בתכונות הנוספות של 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 accessory + audio + adb

מזהי המוצרים שנעשה בהם שימוש ב-AOAv1 (0x2D00 ו-0x2D01) ממשיכים לקבל תמיכה ב-AOAv2.

תמיכה באודיו

AOAv2 כולל תמיכה בפלט אודיו ממכשיר Android לציוד נלווה באמצעות ממשק אודיו סטנדרטי מסוג USB, עם יכולת להעביר אודיו PCM של 2 ערוצים ו-16 ביט, בקצב נתונים של 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 מאפשר לאביזרים לרשום מכשיר ממשק אנושי (HID) אחד או יותר מסוג USB במכשיר Android. הגישה הזו הופכת את כיוון התקשורת במכשירי USB HID רגילים, כמו מקלדות ועכברים של USB. בדרך כלל, מכשיר ה-HID הוא התקן היקפי שמחובר למארח USB (כלומר, למחשב אישי), אבל ב-AOA מארח ה-USB יכול לשמש כמכשיר קלט אחד או יותר להתקן היקפי USB.

התמיכה ב-HID היא שרת proxy לאירועי HID רגילים. ההטמעה לא מבוססת על הנחות לגבי התוכן או סוג האירועים, אלא פשוט מעבירה אותם למערכת הקלט, ומאפשרת לציוד ההיקפי של AOAv2 לפעול כמו כל מכשיר HID (עכבר, מקלדת, שלט לגיימינג וכו'). אפשר להשתמש בתמיכה ב-HID כדי לספק פונקציונליות בסיסית, כמו לחצן הפעלה/השהיה בתחנת עגינה של מדיה, או פונקציונליות מתקדמת, כמו תחנת עגינה עם עכבר ומקלדת QWERTY מלאה.

ב-AOAv2 נוספו בקשות בקרה חדשות של USB שמאפשרות לציוד ההיקפי לפעול כמכשיר קלט HID אחד או יותר במכשיר Android. התמיכה ב-HID מטופלת באופן מלא באמצעות בקשות בקרה בנקודת הקצה אפס, כך שאין צורך בממשק USB חדש. ארבע בקשות הבקרה החדשות הן:

  • ACCESSORY_REGISTER_HID רושם מכשיר HID חדש במכשיר Android. האביזר מספק מזהה שמשמש לזיהוי התקן ה-HID בשלושת הקריאות האחרות. המזהה הזה תקף עד שהכבל USB מנותק או עד שהאביזרים שולחים את הפקודה ACCESSORY_UNREGISTER_HID כדי לבטל את הרישום של מכשיר ה-HID.
  • ההודעה ACCESSORY_UNREGISTER_HID מבטלת את הרישום של מכשיר HID שרשום ב-ACCESSORY_REGISTER_HID.
  • ACCESSORY_SET_HID_REPORT_DESC שולחת למכשיר Android מתאר דוח של מכשיר HID. הבקשה הזו משמשת לתיאור היכולות של מכשיר ה-HID, וצריך לשלוח אותה לפני שמדווחים על אירועי HID למכשיר Android. אם מתאר הדוח גדול מגודל החבילה המקסימלי של נקודת הקצה אפס, נשלחות כמה פקודות 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:

  • המערכת לא מנסה למצוא אפליקציה שתשוחח עם האביזר.
  • ממשק ה-USB של האביזר לא מופיע בהגדרות ה-USB של מכשיר Android אחרי שהמכשיר עובר למצב אביזר.