diff options
| author | 2020-07-07 07:48:29 +0000 | |
|---|---|---|
| committer | 2020-07-07 07:48:29 +0000 | |
| commit | dadc0c5a72ea14dcc0f06415f4a466a7d6c03069 (patch) | |
| tree | 0814c669072ee846833d2b11cd362675408c0fa4 | |
| parent | cd842f2af380a4c5079888c03f42a83d7f21f9ab (diff) | |
| parent | e62f703e4c22d54bdedcc595fd58d473cce790be (diff) | |
Merge "Broadcast events for AOA handshake"
| -rwxr-xr-x | api/system-current.txt | 5 | ||||
| -rw-r--r-- | core/java/android/hardware/usb/UsbAccessory.java | 1 | ||||
| -rw-r--r-- | core/java/android/hardware/usb/UsbManager.java | 62 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 1 | ||||
| -rw-r--r-- | non-updatable-api/system-current.txt | 5 | ||||
| -rw-r--r-- | services/usb/java/com/android/server/usb/UsbDeviceManager.java | 99 |
6 files changed, 172 insertions, 1 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 5aec63396ff6..6a04450817ab 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3674,8 +3674,13 @@ package android.hardware.usb { method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void grantPermission(android.hardware.usb.UsbDevice, String); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbGadget(); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setCurrentFunctions(long); + field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_ACCESSORY_HANDSHAKE = "android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE"; field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_PORT_CHANGED = "android.hardware.usb.action.USB_PORT_CHANGED"; field public static final String ACTION_USB_STATE = "android.hardware.usb.action.USB_STATE"; + field public static final String EXTRA_ACCESSORY_HANDSHAKE_END = "android.hardware.usb.extra.ACCESSORY_HANDSHAKE_END"; + field public static final String EXTRA_ACCESSORY_START = "android.hardware.usb.extra.ACCESSORY_START"; + field public static final String EXTRA_ACCESSORY_STRING_COUNT = "android.hardware.usb.extra.ACCESSORY_STRING_COUNT"; + field public static final String EXTRA_ACCESSORY_UEVENT_TIME = "android.hardware.usb.extra.ACCESSORY_UEVENT_TIME"; field public static final long FUNCTION_ACCESSORY = 2L; // 0x2L field public static final long FUNCTION_ADB = 1L; // 0x1L field public static final long FUNCTION_AUDIO_SOURCE = 64L; // 0x40L diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java index a94266b811d5..f4cfc74aa77d 100644 --- a/core/java/android/hardware/usb/UsbAccessory.java +++ b/core/java/android/hardware/usb/UsbAccessory.java @@ -24,7 +24,6 @@ import android.os.Parcelable; import android.os.RemoteException; import com.android.internal.util.Preconditions; -import java.util.Objects; import java.util.Objects; diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index d16f070f7209..ef305e2c1867 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -160,6 +160,22 @@ public class UsbManager { "android.hardware.usb.action.USB_ACCESSORY_DETACHED"; /** + * Broadcast Action: A broadcast for USB accessory handshaking information delivery + * + * This intent is sent when a USB accessory connect attempt + * + * <p>For more information about communicating with USB accessory handshake, refer to + * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p> + * + * {@hide} + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @SystemApi + @RequiresPermission(Manifest.permission.MANAGE_USB) + public static final String ACTION_USB_ACCESSORY_HANDSHAKE = + "android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE"; + + /** * Boolean extra indicating whether USB is connected or disconnected. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * @@ -303,6 +319,52 @@ public class UsbManager { public static final String EXTRA_ACCESSORY = "accessory"; /** + * A long extra indicating ms from boot to get get_protocol UEvent + * This is obtained with SystemClock.elapsedRealtime() + * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. + * + * {@hide} + */ + @SystemApi + public static final String EXTRA_ACCESSORY_UEVENT_TIME = + "android.hardware.usb.extra.ACCESSORY_UEVENT_TIME"; + + /** + * An integer extra indicating numbers of send string during handshake + * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts + * + * <p>For more information about control request with identifying string information + * between communicating with USB accessory handshake, refer to + * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p> + * + * {@hide} + */ + @SystemApi + public static final String EXTRA_ACCESSORY_STRING_COUNT = + "android.hardware.usb.extra.ACCESSORY_STRING_COUNT"; + + /** + * Boolean extra indicating whether got start accessory or not + * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. + * + * {@hide} + */ + @SystemApi + public static final String EXTRA_ACCESSORY_START = + "android.hardware.usb.extra.ACCESSORY_START"; + + /** + * A long extra indicating ms from boot to sent {@link #ACTION_USB_ACCESSORY_HANDSHAKE} + * This is obtained with SystemClock.elapsedRealtime() + * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. + * + * {@hide} + */ + @SystemApi + public static final String EXTRA_ACCESSORY_HANDSHAKE_END = + "android.hardware.usb.extra.ACCESSORY_HANDSHAKE_END"; + + /** * Name of extra added to the {@link android.app.PendingIntent} * passed into {@link #requestPermission(UsbDevice, PendingIntent)} * or {@link #requestPermission(UsbAccessory, PendingIntent)} diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 16797fd901ee..0985fea3d26a 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -263,6 +263,7 @@ <protected-broadcast android:name="android.hardware.usb.action.USB_PORT_CHANGED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_DETACHED" /> + <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE" /> <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" /> diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index e3aceecc113d..b693b0ef0664 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -3614,8 +3614,13 @@ package android.hardware.usb { method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void grantPermission(android.hardware.usb.UsbDevice, String); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbGadget(); method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setCurrentFunctions(long); + field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_ACCESSORY_HANDSHAKE = "android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE"; field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_PORT_CHANGED = "android.hardware.usb.action.USB_PORT_CHANGED"; field public static final String ACTION_USB_STATE = "android.hardware.usb.action.USB_STATE"; + field public static final String EXTRA_ACCESSORY_HANDSHAKE_END = "android.hardware.usb.extra.ACCESSORY_HANDSHAKE_END"; + field public static final String EXTRA_ACCESSORY_START = "android.hardware.usb.extra.ACCESSORY_START"; + field public static final String EXTRA_ACCESSORY_STRING_COUNT = "android.hardware.usb.extra.ACCESSORY_STRING_COUNT"; + field public static final String EXTRA_ACCESSORY_UEVENT_TIME = "android.hardware.usb.extra.ACCESSORY_UEVENT_TIME"; field public static final long FUNCTION_ACCESSORY = 2L; // 0x2L field public static final long FUNCTION_ADB = 1L; // 0x1L field public static final long FUNCTION_AUDIO_SOURCE = 64L; // 0x40L diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 7595e3f249ce..57345f1c0e21 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -164,6 +164,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private static final int MSG_FUNCTION_SWITCH_TIMEOUT = 17; private static final int MSG_GADGET_HAL_REGISTERED = 18; private static final int MSG_RESET_USB_GADGET = 19; + private static final int MSG_ACCESSORY_HANDSHAKE_TIMEOUT = 20; + private static final int MSG_INCREASE_SENDSTRING_COUNT = 21; private static final int AUDIO_MODE_SOURCE = 1; @@ -176,6 +178,13 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser // Request is cancelled if host does not configure device within 10 seconds. private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000; + /** + * Timeout for receiving USB accessory request + * Reset when receive next control request + * Broadcast intent if not receive next control request or enter next step. + */ + private static final int ACCESSORY_HANDSHAKE_TIMEOUT = 10 * 1000; + private static final String BOOT_MODE_PROPERTY = "ro.bootmode"; private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv"; @@ -222,8 +231,19 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser String accessory = event.get("ACCESSORY"); if (state != null) { mHandler.updateState(state); + } else if ("GETPROTOCOL".equals(accessory)) { + if (DEBUG) Slog.d(TAG, "got accessory get protocol"); + long elapsedRealtime = SystemClock.elapsedRealtime(); + mHandler.setAccessoryUEventTime(elapsedRealtime); + resetAccessoryHandshakeTimeoutHandler(); + } else if ("SENDSTRING".equals(accessory)) { + if (DEBUG) Slog.d(TAG, "got accessory send string"); + mHandler.sendEmptyMessage(MSG_INCREASE_SENDSTRING_COUNT); + resetAccessoryHandshakeTimeoutHandler(); } else if ("START".equals(accessory)) { if (DEBUG) Slog.d(TAG, "got accessory start"); + mHandler.removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT); + mHandler.setStartAccessoryTrue(); startAccessoryMode(); } } @@ -395,6 +415,23 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mHandler.sendEmptyMessage(MSG_UPDATE_USER_RESTRICTIONS); } + /* + * Start the timeout-timer upon receiving "get_protocol" uevent. + * Restart the timer every time if any succeeding uevnet received. + * (Only when USB is under accessory mode) + * <p>About the details of the related control request and sequence ordering, refer to + * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p> + */ + private void resetAccessoryHandshakeTimeoutHandler() { + long functions = getCurrentFunctions(); + // some accesories send get_protocol after start accessory + if ((functions & UsbManager.FUNCTION_ACCESSORY) == 0) { + mHandler.removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT), + ACCESSORY_HANDSHAKE_TIMEOUT); + } + } + private void startAccessoryMode() { if (!mHasUsbAccessory) return; @@ -416,6 +453,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser if (functions != UsbManager.FUNCTION_NONE) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_MODE_ENTER_TIMEOUT), ACCESSORY_REQUEST_TIMEOUT); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT), + ACCESSORY_HANDSHAKE_TIMEOUT); setCurrentFunctions(functions); } } @@ -468,6 +507,15 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private int mMidiCard; private int mMidiDevice; + /** + * mAccessoryConnectionStartTime record the timing of start_accessory + * mSendStringCount count the number of receiving uevent send_string + * mStartAccessory record whether start_accessory is received + */ + private long mAccessoryConnectionStartTime = 0L; + private int mSendStringCount = 0; + private boolean mStartAccessory = false; + private final Context mContext; private final UsbAlsaManager mUsbAlsaManager; private final UsbPermissionManager mPermissionManager; @@ -645,6 +693,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser // defer accessoryAttached if system is not ready if (mBootCompleted) { mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); + removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT); + broadcastUsbAccessoryHandshake(); } // else handle in boot completed } else { Slog.e(TAG, "nativeGetAccessoryStrings failed"); @@ -701,6 +751,30 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser return false; } + private void broadcastUsbAccessoryHandshake() { + long elapsedRealtime = SystemClock.elapsedRealtime(); + long accessoryHandShakeEnd = elapsedRealtime; + + // send a sticky broadcast containing USB accessory handshake information + Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_HANDSHAKE) + .putExtra(UsbManager.EXTRA_ACCESSORY_UEVENT_TIME, + mAccessoryConnectionStartTime) + .putExtra(UsbManager.EXTRA_ACCESSORY_STRING_COUNT, + mSendStringCount) + .putExtra(UsbManager.EXTRA_ACCESSORY_START, + mStartAccessory) + .putExtra(UsbManager.EXTRA_ACCESSORY_HANDSHAKE_END, + accessoryHandShakeEnd); + + if (DEBUG) { + Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras()); + } + + sendStickyBroadcast(intent); + resetUsbAccessoryHandshakeDebuggingInfo(); + accessoryHandShakeEnd = 0L; + } + protected void updateUsbStateBroadcastIfNeeded(long functions) { // send a sticky broadcast containing current USB state Intent intent = new Intent(UsbManager.ACTION_USB_STATE); @@ -998,6 +1072,16 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } break; } + case MSG_ACCESSORY_HANDSHAKE_TIMEOUT: { + if (DEBUG) { + Slog.v(TAG, "Accessory handshake timeout"); + } + broadcastUsbAccessoryHandshake(); + break; + } + case MSG_INCREASE_SENDSTRING_COUNT: { + mSendStringCount = mSendStringCount + 1; + } } } @@ -1015,6 +1099,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } if (mCurrentAccessory != null) { mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); + broadcastUsbAccessoryHandshake(); } updateUsbNotification(false); @@ -1301,6 +1386,20 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser * Evaluates USB function policies and applies the change accordingly. */ protected abstract void setEnabledFunctions(long functions, boolean forceRestart); + + public void setAccessoryUEventTime(long accessoryConnectionStartTime) { + mAccessoryConnectionStartTime = accessoryConnectionStartTime; + } + + public void setStartAccessoryTrue() { + mStartAccessory = true; + } + + public void resetUsbAccessoryHandshakeDebuggingInfo() { + mAccessoryConnectionStartTime = 0L; + mSendStringCount = 0; + mStartAccessory = false; + } } private static final class UsbHandlerLegacy extends UsbHandler { |