Broadcast events for AOA handshake

Broadcast intents on below control request

Log both the request and response for 51 control request (Get Protocol)
Log both the request and response for 52 control request (Identifying information)
Log both the request and response for 53 control request (Start accessory mode)

bug: 139264039

Test: Check the broadcast intent could be received
Change-Id: I7c8db41ee05398200e235cf10dde96ba89b306e8
This commit is contained in:
rickyniu
2020-02-18 22:17:42 +08:00
parent a14f7fbd25
commit e62f703e4c
6 changed files with 172 additions and 1 deletions

View File

@@ -3673,8 +3673,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

View File

@@ -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;

View File

@@ -159,6 +159,22 @@ public class UsbManager {
public static final String ACTION_USB_ACCESSORY_DETACHED =
"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.
@@ -302,6 +318,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)}

View File

@@ -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" />

View File

@@ -3613,8 +3613,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

View File

@@ -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 {