summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2020-07-07 07:48:29 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-07-07 07:48:29 +0000
commitdadc0c5a72ea14dcc0f06415f4a466a7d6c03069 (patch)
tree0814c669072ee846833d2b11cd362675408c0fa4
parentcd842f2af380a4c5079888c03f42a83d7f21f9ab (diff)
parente62f703e4c22d54bdedcc595fd58d473cce790be (diff)
Merge "Broadcast events for AOA handshake"
-rwxr-xr-xapi/system-current.txt5
-rw-r--r--core/java/android/hardware/usb/UsbAccessory.java1
-rw-r--r--core/java/android/hardware/usb/UsbManager.java62
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--non-updatable-api/system-current.txt5
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java99
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 {