1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.cts.verifierusbcompanion; 17 18 import android.hardware.usb.UsbConstants; 19 import android.hardware.usb.UsbDevice; 20 import android.hardware.usb.UsbDeviceConnection; 21 import android.util.Log; 22 23 class AoapInterface { 24 /** 25 * Use Google Vendor ID when in accessory mode 26 */ 27 private static final int USB_ACCESSORY_VENDOR_ID = 0x18D1; 28 29 /** 30 * Product ID to use when in accessory mode 31 */ 32 private static final int USB_ACCESSORY_PRODUCT_ID = 0x2D00; 33 34 /** 35 * Product ID to use when in accessory mode and adb is enabled 36 */ 37 private static final int USB_ACCESSORY_ADB_PRODUCT_ID = 0x2D01; 38 39 /** 40 * Indexes for strings sent by the host via ACCESSORY_SEND_STRING 41 */ 42 public static final int ACCESSORY_STRING_MANUFACTURER = 0; 43 public static final int ACCESSORY_STRING_MODEL = 1; 44 public static final int ACCESSORY_STRING_DESCRIPTION = 2; 45 public static final int ACCESSORY_STRING_VERSION = 3; 46 public static final int ACCESSORY_STRING_URI = 4; 47 public static final int ACCESSORY_STRING_SERIAL = 5; 48 49 /** 50 * Control request for retrieving device's protocol version 51 * 52 * requestType: USB_DIR_IN | USB_TYPE_VENDOR 53 * request: ACCESSORY_GET_PROTOCOL 54 * value: 0 55 * index: 0 56 * data version number (16 bits little endian) 57 * 1 for original accessory support 58 * 2 adds HID and device to host audio support 59 */ 60 private static final int ACCESSORY_GET_PROTOCOL = 51; 61 62 /** 63 * Control request for host to send a string to the device 64 * 65 * requestType: USB_DIR_OUT | USB_TYPE_VENDOR 66 * request: ACCESSORY_SEND_STRING 67 * value: 0 68 * index: string ID 69 * data zero terminated UTF8 string 70 * 71 * The device can later retrieve these strings via the 72 * ACCESSORY_GET_STRING_* ioctls 73 */ 74 private static final int ACCESSORY_SEND_STRING = 52; 75 76 /** 77 * Control request for starting device in accessory mode. 78 * The host sends this after setting all its strings to the device. 79 * 80 * requestType: USB_DIR_OUT | USB_TYPE_VENDOR 81 * request: ACCESSORY_START 82 * value: 0 83 * index: 0 84 * data none 85 */ 86 private static final int ACCESSORY_START = 53; 87 88 private static final String TAG = AoapInterface.class.getSimpleName(); 89 90 public static int getProtocol(UsbDeviceConnection conn) { 91 byte[] buffer = new byte[2]; 92 int len = conn.controlTransfer( 93 UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_VENDOR, 94 AoapInterface.ACCESSORY_GET_PROTOCOL, 0, 0, buffer, 2, 10000); 95 if (len != 2) { 96 return -1; 97 } 98 return (buffer[1] << 8) | buffer[0]; 99 } 100 101 public static void sendString(UsbDeviceConnection conn, int index, String string) { 102 byte[] buffer = (string + "\0").getBytes(); 103 int len = conn.controlTransfer( 104 UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR, 105 AoapInterface.ACCESSORY_SEND_STRING, 0, index, 106 buffer, buffer.length, 10000); 107 if (len != buffer.length) { 108 throw new RuntimeException("Failed to send string " + index + ": \"" + string + "\""); 109 } else { 110 Log.i(TAG, "Sent string " + index + ": \"" + string + "\""); 111 } 112 } 113 114 public static void sendAoapStart(UsbDeviceConnection conn) { 115 int len = conn.controlTransfer( 116 UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR, 117 AoapInterface.ACCESSORY_START, 0, 0, null, 0, 10000); 118 if (len < 0) { 119 throw new RuntimeException("control transfer for accessory start failed:" + len); 120 } 121 } 122 123 public static boolean isDeviceInAoapMode(UsbDevice device) { 124 final int vid = device.getVendorId(); 125 final int pid = device.getProductId(); 126 return vid == USB_ACCESSORY_VENDOR_ID 127 && (pid == USB_ACCESSORY_PRODUCT_ID 128 || pid == USB_ACCESSORY_ADB_PRODUCT_ID); 129 } 130 } 131