diff options
author | 2022-06-14 17:43:27 +0800 | |
---|---|---|
committer | 2022-11-30 11:12:06 +0800 | |
commit | 74272e24224233e0ad5caa363de609b534219a82 (patch) | |
tree | 8e5d07a42bad8a9c6dbf79aec46b12a8a5967845 | |
parent | fb11cf828915e76f4df7e1dee7a3f0325f219d37 (diff) |
usb: Implement the AIDL in framework
Implement the AIDL and HIDL coexist in framework
Bug: 218791946
Test: USB function switch success and AIDL service is running.
atest VtsHalUsbGadgetV2_0HostTest
Signed-off-by: Ricky Niu <rickyniu@google.com>
Change-Id: I6d9bc861a4aceb753bf6f816daccd039e423994d
13 files changed, 1053 insertions, 258 deletions
diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java index 7d804938dc38..26e20f601c7a 100644 --- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java +++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java @@ -29,12 +29,18 @@ import android.os.ServiceManager; import java.util.function.Consumer; import java.util.concurrent.Executor; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; public class UsbCommand extends Svc.Command { public UsbCommand() { super("usb"); } + /** + * Counter for tracking UsbOperation operations. + */ + private static final AtomicInteger sUsbOperationCount = new AtomicInteger(); + @Override public String shortHelp() { return "Control Usb state"; @@ -92,8 +98,10 @@ public class UsbCommand extends Svc.Command { if ("setFunctions".equals(args[1])) { try { + int operationId = sUsbOperationCount.incrementAndGet(); + System.out.println("setCurrentFunctions opId:" + operationId); usbMgr.setCurrentFunctions(UsbManager.usbFunctionsFromString( - args.length >= 3 ? args[2] : "")); + args.length >= 3 ? args[2] : ""), operationId); } catch (RemoteException e) { System.err.println("Error communicating with UsbManager: " + e); } diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index b6e2d2a3e98b..3228ce6cf939 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -121,6 +121,7 @@ package android.hardware.usb { field public static final int GADGET_HAL_V1_0 = 10; // 0xa field public static final int GADGET_HAL_V1_1 = 11; // 0xb field public static final int GADGET_HAL_V1_2 = 12; // 0xc + field public static final int GADGET_HAL_V2_0 = 20; // 0x14 field public static final int USB_DATA_TRANSFER_RATE_10G = 10240; // 0x2800 field public static final int USB_DATA_TRANSFER_RATE_20G = 20480; // 0x5000 field public static final int USB_DATA_TRANSFER_RATE_40G = 40960; // 0xa000 diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl index 51236fe3b2c0..248b5d0398f6 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -122,10 +122,10 @@ interface IUsbManager boolean isFunctionEnabled(String function); /* Sets the current USB function. */ - void setCurrentFunctions(long functions); + void setCurrentFunctions(long functions, int operationId); /* Compatibility version of setCurrentFunctions(long). */ - void setCurrentFunction(String function, boolean usbDataUnlocked); + void setCurrentFunction(String function, boolean usbDataUnlocked, int operationId); /* Gets the current USB functions. */ long getCurrentFunctions(); diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index 342c33665b02..7a8117c1b684 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -38,6 +38,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.hardware.usb.gadget.V1_0.GadgetFunction; import android.hardware.usb.gadget.V1_2.UsbSpeed; +import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.ParcelFileDescriptor; @@ -52,6 +53,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicInteger; /** * This class allows you to access the state of USB and communicate with USB devices. @@ -95,7 +97,7 @@ public class UsbManager { * If the sticky intent has not been found, that indicates USB is disconnected, * USB is not configued, MTP function is enabled, and all the other functions are disabled. * - * {@hide} + * @hide */ @SystemApi public static final String ACTION_USB_STATE = @@ -185,7 +187,7 @@ public class UsbManager { * <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} + * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @SystemApi @@ -197,7 +199,7 @@ public class UsbManager { * Boolean extra indicating whether USB is connected or disconnected. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * - * {@hide} + * @hide */ @SystemApi public static final String USB_CONNECTED = "connected"; @@ -206,7 +208,7 @@ public class UsbManager { * Boolean extra indicating whether USB is connected or disconnected as host. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * - * {@hide} + * @hide */ public static final String USB_HOST_CONNECTED = "host_connected"; @@ -214,7 +216,7 @@ public class UsbManager { * Boolean extra indicating whether USB is configured. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * - * {@hide} + * @hide */ @SystemApi public static final String USB_CONFIGURED = "configured"; @@ -225,7 +227,7 @@ public class UsbManager { * has explicitly asked for this data to be unlocked. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * - * {@hide} + * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String USB_DATA_UNLOCKED = "unlocked"; @@ -234,7 +236,7 @@ public class UsbManager { * A placeholder indicating that no USB function is being specified. * Used for compatibility with old init scripts to indicate no functions vs. charging function. * - * {@hide} + * @hide */ @UnsupportedAppUsage public static final String USB_FUNCTION_NONE = "none"; @@ -243,7 +245,7 @@ public class UsbManager { * Name of the adb USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * - * {@hide} + * @hide */ public static final String USB_FUNCTION_ADB = "adb"; @@ -251,7 +253,7 @@ public class UsbManager { * Name of the RNDIS ethernet USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * - * {@hide} + * @hide */ @SystemApi public static final String USB_FUNCTION_RNDIS = "rndis"; @@ -260,7 +262,7 @@ public class UsbManager { * Name of the MTP USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * - * {@hide} + * @hide */ public static final String USB_FUNCTION_MTP = "mtp"; @@ -268,7 +270,7 @@ public class UsbManager { * Name of the PTP USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * - * {@hide} + * @hide */ public static final String USB_FUNCTION_PTP = "ptp"; @@ -276,7 +278,7 @@ public class UsbManager { * Name of the audio source USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * - * {@hide} + * @hide */ public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source"; @@ -284,7 +286,7 @@ public class UsbManager { * Name of the MIDI USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * - * {@hide} + * @hide */ public static final String USB_FUNCTION_MIDI = "midi"; @@ -292,7 +294,7 @@ public class UsbManager { * Name of the Accessory USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * - * {@hide} + * @hide */ public static final String USB_FUNCTION_ACCESSORY = "accessory"; @@ -300,7 +302,7 @@ public class UsbManager { * Name of the NCM USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * - * {@hide} + * @hide */ @SystemApi public static final String USB_FUNCTION_NCM = "ncm"; @@ -308,32 +310,39 @@ public class UsbManager { /** * Name of Gadget Hal Not Present; * - * {@hide} + * @hide */ public static final String GADGET_HAL_UNKNOWN = "unknown"; /** * Name of the USB Gadget Hal Version v1.0; * - * {@hide} + * @hide */ public static final String GADGET_HAL_VERSION_1_0 = "V1_0"; /** * Name of the USB Gadget Hal Version v1.1; * - * {@hide} + * @hide */ public static final String GADGET_HAL_VERSION_1_1 = "V1_1"; /** * Name of the USB Gadget Hal Version v1.2; * - * {@hide} + * @hide */ public static final String GADGET_HAL_VERSION_1_2 = "V1_2"; /** + * Name of the USB Gadget Hal Version v2.0; + * + * @hide + */ + public static final String GADGET_HAL_VERSION_2_0 = "V2_0"; + + /** * Name of extra for {@link #ACTION_USB_PORT_CHANGED} * containing the {@link UsbPort} object for the port. * @@ -369,7 +378,7 @@ public class UsbManager { * This is obtained with SystemClock.elapsedRealtime() * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * - * {@hide} + * @hide */ @SystemApi public static final String EXTRA_ACCESSORY_UEVENT_TIME = @@ -383,7 +392,7 @@ public class UsbManager { * between communicating with USB accessory handshake, refer to * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p> * - * {@hide} + * @hide */ @SystemApi public static final String EXTRA_ACCESSORY_STRING_COUNT = @@ -393,7 +402,7 @@ public class UsbManager { * Boolean extra indicating whether got start accessory or not * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * - * {@hide} + * @hide */ @SystemApi public static final String EXTRA_ACCESSORY_START = @@ -405,7 +414,7 @@ public class UsbManager { * sending {@link #ACTION_USB_ACCESSORY_HANDSHAKE}. * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * - * {@hide} + * @hide */ @SystemApi public static final String EXTRA_ACCESSORY_HANDSHAKE_END = @@ -439,7 +448,7 @@ public class UsbManager { /** * The Value for USB gadget hal is not presented. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int GADGET_HAL_NOT_SUPPORTED = -1; @@ -447,7 +456,7 @@ public class UsbManager { /** * Value for Gadget Hal Version v1.0. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int GADGET_HAL_V1_0 = 10; @@ -455,7 +464,7 @@ public class UsbManager { /** * Value for Gadget Hal Version v1.1. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int GADGET_HAL_V1_1 = 11; @@ -463,15 +472,23 @@ public class UsbManager { /** * Value for Gadget Hal Version v1.2. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int GADGET_HAL_V1_2 = 12; /** + * Value for Gadget Hal Version v2.0. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final int GADGET_HAL_V2_0 = 20; + + /** * Value for USB_STATE is not configured. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_UNKNOWN = -1; @@ -479,7 +496,7 @@ public class UsbManager { /** * Value for USB Transfer Rate of Low Speed in Mbps (real value is 1.5Mbps). * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_LOW_SPEED = 2; @@ -487,7 +504,7 @@ public class UsbManager { /** * Value for USB Transfer Rate of Full Speed in Mbps. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_FULL_SPEED = 12; @@ -495,7 +512,7 @@ public class UsbManager { /** * Value for USB Transfer Rate of High Speed in Mbps. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_HIGH_SPEED = 480; @@ -503,7 +520,7 @@ public class UsbManager { /** * Value for USB Transfer Rate of Super Speed in Mbps. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_5G = 5 * 1024; @@ -511,7 +528,7 @@ public class UsbManager { /** * Value for USB Transfer Rate of 10G. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_10G = 10 * 1024; @@ -519,7 +536,7 @@ public class UsbManager { /** * Value for USB Transfer Rate of 20G. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_20G = 20 * 1024; @@ -527,7 +544,7 @@ public class UsbManager { /** * Value for USB Transfer Rate of 40G. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_40G = 40 * 1024; @@ -543,7 +560,7 @@ public class UsbManager { /** * The Value for USB hal is not presented. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_NOT_SUPPORTED = -1; @@ -551,7 +568,7 @@ public class UsbManager { /** * Value for USB Hal Version v1.0. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V1_0 = 10; @@ -559,7 +576,7 @@ public class UsbManager { /** * Value for USB Hal Version v1.1. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V1_1 = 11; @@ -567,7 +584,7 @@ public class UsbManager { /** * Value for USB Hal Version v1.2. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V1_2 = 12; @@ -575,7 +592,7 @@ public class UsbManager { /** * Value for USB Hal Version v1.3. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V1_3 = 13; @@ -590,63 +607,63 @@ public class UsbManager { /** * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)} - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_NONE = 0; /** * Code for the mtp usb function. Passed as a mask into {@link #setCurrentFunctions(long)} - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_MTP = GadgetFunction.MTP; /** * Code for the ptp usb function. Passed as a mask into {@link #setCurrentFunctions(long)} - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_PTP = GadgetFunction.PTP; /** * Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)} - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_RNDIS = GadgetFunction.RNDIS; /** * Code for the midi usb function. Passed as a mask into {@link #setCurrentFunctions(long)} - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_MIDI = GadgetFunction.MIDI; /** * Code for the accessory usb function. - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_ACCESSORY = GadgetFunction.ACCESSORY; /** * Code for the audio source usb function. - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_AUDIO_SOURCE = GadgetFunction.AUDIO_SOURCE; /** * Code for the adb usb function. - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_ADB = GadgetFunction.ADB; /** * Code for the ncm source usb function. - * {@hide} + * @hide */ @SystemApi public static final long FUNCTION_NCM = 1 << 10; @@ -656,6 +673,11 @@ public class UsbManager { private static final Map<String, Long> FUNCTION_NAME_TO_CODE = new HashMap<>(); + /** + * Counter for tracking UsbOperation operations. + */ + private static final AtomicInteger sUsbOperationCount = new AtomicInteger(); + static { FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP); FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_PTP, FUNCTION_PTP); @@ -687,6 +709,7 @@ public class UsbManager { GADGET_HAL_V1_0, GADGET_HAL_V1_1, GADGET_HAL_V1_2, + GADGET_HAL_V2_0, }) public @interface UsbGadgetHalVersion {} @@ -705,7 +728,7 @@ public class UsbManager { private final IUsbManager mService; /** - * {@hide} + * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public UsbManager(Context context, IUsbManager service) { @@ -816,7 +839,7 @@ public class UsbManager { * {@link #FUNCTION_PTP} are supported. * @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found. * - * {@hide} + * @hide */ public ParcelFileDescriptor getControlFd(long function) { try { @@ -977,7 +1000,7 @@ public class UsbManager { * Only system components can call this function. * @param device to request permissions for * - * {@hide} + * @hide */ public void grantPermission(UsbDevice device) { grantPermission(device, Process.myUid()); @@ -989,7 +1012,7 @@ public class UsbManager { * @param device to request permissions for * @uid uid to give permission * - * {@hide} + * @hide */ public void grantPermission(UsbDevice device, int uid) { try { @@ -1005,7 +1028,7 @@ public class UsbManager { * @param device to request permissions for * @param packageName of package to grant permissions * - * {@hide} + * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_USB) @@ -1030,7 +1053,7 @@ public class UsbManager { * @param function name of the USB function * @return true if the USB function is enabled * - * {@hide} + * @hide */ @Deprecated @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -1062,14 +1085,17 @@ public class UsbManager { * @param functions the USB function(s) to set, as a bitwise mask. * Must satisfy {@link UsbManager#areSettableFunctions} * - * {@hide} + * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_USB) public void setCurrentFunctions(@UsbFunctionMode long functions) { + int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid(); try { - mService.setCurrentFunctions(functions); + mService.setCurrentFunctions(functions, operationId); } catch (RemoteException e) { + Log.e(TAG, "setCurrentFunctions: failed to call setCurrentFunctions. functions:" + + functions + ", opId:" + operationId, e); throw e.rethrowFromSystemServer(); } } @@ -1081,14 +1107,17 @@ public class UsbManager { * @param functions the USB function(s) to set. * @param usbDataUnlocked unused - * {@hide} + * @hide */ @Deprecated @UnsupportedAppUsage public void setCurrentFunction(String functions, boolean usbDataUnlocked) { + int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid(); try { - mService.setCurrentFunction(functions, usbDataUnlocked); + mService.setCurrentFunction(functions, usbDataUnlocked, operationId); } catch (RemoteException e) { + Log.e(TAG, "setCurrentFunction: failed to call setCurrentFunction. functions:" + + functions + ", opId:" + operationId, e); throw e.rethrowFromSystemServer(); } } @@ -1103,7 +1132,7 @@ public class UsbManager { * @return The currently enabled functions, in a bitwise mask. * A zero mask indicates that the current function is the charging function. * - * {@hide} + * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_USB) @@ -1129,7 +1158,7 @@ public class UsbManager { * @param functions functions to set, in a bitwise mask. * Must satisfy {@link UsbManager#areSettableFunctions} * - * {@hide} + * @hide */ public void setScreenUnlockedFunctions(long functions) { try { @@ -1145,7 +1174,7 @@ public class UsbManager { * @return The currently set screen enabled functions. * A zero mask indicates that the screen unlocked functions feature is not enabled. * - * {@hide} + * @hide */ public long getScreenUnlockedFunctions() { try { @@ -1167,19 +1196,17 @@ public class UsbManager { * * @return The value of currently USB Bandwidth. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(Manifest.permission.MANAGE_USB) public int getUsbBandwidthMbps() { int usbSpeed; - try { usbSpeed = mService.getCurrentUsbSpeed(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } - return usbSpeedToBandwidth(usbSpeed); } @@ -1191,7 +1218,7 @@ public class UsbManager { * * @return a integer {@code GADGET_HAL_*} represent hal version. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(Manifest.permission.MANAGE_USB) @@ -1211,7 +1238,7 @@ public class UsbManager { * * @return a integer {@code USB_HAL_*} represent hal version. * - * {@hide} + * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(Manifest.permission.MANAGE_USB) @@ -1507,7 +1534,7 @@ public class UsbManager { * @param usbDeviceConnectionHandler The component to handle usb connections, * {@code null} to unset. * - * {@hide} + * @hide */ public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) { try { @@ -1526,7 +1553,7 @@ public class UsbManager { * * @return Whether the mask is settable. * - * {@hide} + * @hide */ public static boolean areSettableFunctions(long functions) { return functions == FUNCTION_NONE @@ -1540,7 +1567,7 @@ public class UsbManager { * * @return String representation of given mask * - * {@hide} + * @hide */ public static String usbFunctionsToString(long functions) { StringJoiner joiner = new StringJoiner(","); @@ -1576,7 +1603,7 @@ public class UsbManager { * * @return A mask of all valid functions in the string * - * {@hide} + * @hide */ public static long usbFunctionsFromString(String functions) { if (functions == null || functions.equals(USB_FUNCTION_NONE)) { @@ -1598,7 +1625,7 @@ public class UsbManager { * * @return a value of USB bandwidth * - * {@hide} + * @hide */ public static int usbSpeedToBandwidth(int speed) { switch (speed) { @@ -1632,12 +1659,14 @@ public class UsbManager { * * @return String representation of Usb Gadget Hal Version * - * {@hide} + * @hide */ public static @NonNull String usbGadgetHalVersionToString(int version) { String halVersion; - if (version == GADGET_HAL_V1_2) { + if (version == GADGET_HAL_V2_0) { + halVersion = GADGET_HAL_VERSION_2_0; + } else if (version == GADGET_HAL_V1_2) { halVersion = GADGET_HAL_VERSION_1_2; } else if (version == GADGET_HAL_V1_1) { halVersion = GADGET_HAL_VERSION_1_1; diff --git a/services/usb/Android.bp b/services/usb/Android.bp index 52cfe25d9f26..133f924047da 100644 --- a/services/usb/Android.bp +++ b/services/usb/Android.bp @@ -33,5 +33,6 @@ java_library_static { "android.hardware.usb.gadget-V1.0-java", "android.hardware.usb.gadget-V1.1-java", "android.hardware.usb.gadget-V1.2-java", + "android.hardware.usb.gadget-V1-java", ], } diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 1c081c1c153d..ffdb07b27ad0 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -44,6 +44,7 @@ import android.debug.AdbManagerInternal; import android.debug.AdbNotifications; import android.debug.AdbTransportType; import android.debug.IAdbTransport; +import android.hardware.usb.IUsbOperationInternal; import android.hardware.usb.ParcelableUsbPort; import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbConfiguration; @@ -54,9 +55,7 @@ import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; import android.hardware.usb.gadget.V1_0.GadgetFunction; -import android.hardware.usb.gadget.V1_0.IUsbGadget; import android.hardware.usb.gadget.V1_0.Status; -import android.hardware.usb.gadget.V1_2.IUsbGadgetCallback; import android.hardware.usb.gadget.V1_2.UsbSpeed; import android.hidl.manager.V1_0.IServiceManager; import android.hidl.manager.V1_0.IServiceNotification; @@ -88,9 +87,12 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.SomeArgs; +import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; import com.android.server.LocalServices; +import com.android.server.usb.hal.gadget.UsbGadgetHal; +import com.android.server.usb.hal.gadget.UsbGadgetHalInstance; import com.android.server.utils.EventLogger; import com.android.server.wm.ActivityTaskManagerInternal; @@ -106,6 +108,7 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Scanner; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; /** * UsbDeviceManager manages USB state in device mode. @@ -216,6 +219,13 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private static EventLogger sEventLogger; + private UsbGadgetHal mUsbGadgetHal; + + /** + * Counter for tracking UsbOperation operations. + */ + private static final AtomicInteger sUsbOperationCount = new AtomicInteger(); + static { sDenyInterfaces = new HashSet<>(); sDenyInterfaces.add(UsbConstants.USB_CLASS_AUDIO); @@ -298,15 +308,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); initRndisAddress(); + int operationId = sUsbOperationCount.incrementAndGet(); boolean halNotPresent = false; - try { - IUsbGadget.getService(true); - } catch (RemoteException e) { - Slog.e(TAG, "USB GADGET HAL present but exception thrown", e); - } catch (NoSuchElementException e) { - halNotPresent = true; - Slog.i(TAG, "USB GADGET HAL not present in the device", e); - } + + mUsbGadgetHal = UsbGadgetHalInstance.getInstance(this, null); + Slog.d(TAG, "getInstance done"); mControlFds = new HashMap<>(); FileDescriptor mtpFd = nativeOpenControl(UsbManager.USB_FUNCTION_MTP); @@ -320,7 +326,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd); - if (halNotPresent) { + if (mUsbGadgetHal == null) { /** * Initialze the legacy UsbHandler */ @@ -334,6 +340,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser alsaManager, permissionManager); } + mHandler.handlerInitDone(operationId); + if (nativeIsStartRequested()) { if (DEBUG) Slog.d(TAG, "accessory attached at boot"); startAccessoryMode(); @@ -455,6 +463,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private void startAccessoryMode() { if (!mHasUsbAccessory) return; + int operationId = sUsbOperationCount.incrementAndGet(); + mAccessoryStrings = nativeGetAccessoryStrings(); boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE); // don't start accessory mode if our mandatory strings have not been set @@ -475,7 +485,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser ACCESSORY_REQUEST_TIMEOUT); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT), ACCESSORY_HANDSHAKE_TIMEOUT); - setCurrentFunctions(functions); + setCurrentFunctions(functions, operationId); } } @@ -504,6 +514,20 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } } + public static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) { + Slog.println(priority, TAG, msg); + if (pw != null) { + pw.println(msg); + } + } + + public static void logAndPrintException(IndentingPrintWriter pw, String msg, Exception e) { + Slog.e(TAG, msg, e); + if (pw != null) { + pw.println(msg + e); + } + } + abstract static class UsbHandler extends Handler { // current USB state @@ -608,6 +632,19 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser sendMessage(m); } + public boolean sendMessage(int what) { + removeMessages(what); + Message m = Message.obtain(this, what); + return sendMessageDelayed(m,0); + } + + public void sendMessage(int what, int operationId) { + removeMessages(what); + Message m = Message.obtain(this, what); + m.arg1 = operationId; + sendMessage(m); + } + public void sendMessage(int what, Object arg) { removeMessages(what); Message m = Message.obtain(this, what); @@ -615,6 +652,22 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser sendMessage(m); } + public void sendMessage(int what, Object arg, int operationId) { + removeMessages(what); + Message m = Message.obtain(this, what); + m.obj = arg; + m.arg1 = operationId; + sendMessage(m); + } + + public void sendMessage(int what, boolean arg, int operationId) { + removeMessages(what); + Message m = Message.obtain(this, what); + m.arg1 = (arg ? 1 : 0); + m.arg2 = operationId; + sendMessage(m); + } + public void sendMessage(int what, Object arg, boolean arg1) { removeMessages(what); Message m = Message.obtain(this, what); @@ -623,6 +676,15 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser sendMessage(m); } + public void sendMessage(int what, long arg, boolean arg1, int operationId) { + removeMessages(what); + Message m = Message.obtain(this, what); + m.obj = arg; + m.arg1 = (arg1 ? 1 : 0); + m.arg2 = operationId; + sendMessage(m); + } + public void sendMessage(int what, boolean arg1, boolean arg2) { removeMessages(what); Message m = Message.obtain(this, what); @@ -680,7 +742,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser sendMessageDelayed(msg, HOST_STATE_UPDATE_DELAY); } - private void setAdbEnabled(boolean enable) { + private void setAdbEnabled(boolean enable, int operationId) { if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); if (enable) { @@ -689,7 +751,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, ""); } - setEnabledFunctions(mCurrentFunctions, true); + setEnabledFunctions(mCurrentFunctions, true, operationId); updateAdbNotification(false); } @@ -701,6 +763,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private void updateCurrentAccessory() { // We are entering accessory mode if we have received a request from the host // and the request has not timed out yet. + int operationId = sUsbOperationCount.incrementAndGet(); + boolean enteringAccessoryMode = hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT); if (mConfigured && enteringAccessoryMode) { @@ -732,18 +796,18 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } } else { if (!enteringAccessoryMode) { - notifyAccessoryModeExit(); + notifyAccessoryModeExit(operationId); } else if (DEBUG) { Slog.v(TAG, "Debouncing accessory mode exit"); } } } - private void notifyAccessoryModeExit() { + private void notifyAccessoryModeExit(int operationId) { // make sure accessory mode is off // and restore default functions Slog.d(TAG, "exited USB accessory mode"); - setEnabledFunctions(UsbManager.FUNCTION_NONE, false); + setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); if (mCurrentAccessory != null) { if (mBootCompleted) { @@ -869,8 +933,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mMidiEnabled && mConfigured, mMidiCard, mMidiDevice); } - private void setScreenUnlockedFunctions() { - setEnabledFunctions(mScreenUnlockedFunctions, false); + private void setScreenUnlockedFunctions(int operationId) { + setEnabledFunctions(mScreenUnlockedFunctions, false, operationId); } private static class AdbTransport extends IAdbTransport.Stub { @@ -883,7 +947,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser @Override public void onAdbEnabled(boolean enabled, byte transportType) { if (transportType == AdbTransportType.USB) { - mHandler.sendMessage(MSG_ENABLE_ADB, enabled); + int operationId = sUsbOperationCount.incrementAndGet(); + mHandler.sendMessage(MSG_ENABLE_ADB, enabled, operationId); } } } @@ -906,6 +971,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser public void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_STATE: + int operationId = sUsbOperationCount.incrementAndGet(); mConnected = (msg.arg1 == 1); mConfigured = (msg.arg2 == 1); @@ -923,9 +989,9 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser // restore defaults when USB is disconnected if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { - setScreenUnlockedFunctions(); + setScreenUnlockedFunctions(operationId); } else { - setEnabledFunctions(UsbManager.FUNCTION_NONE, false); + setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); } } updateUsbFunctions(); @@ -1036,13 +1102,15 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser updateUsbNotification(false); break; case MSG_ENABLE_ADB: - setAdbEnabled(msg.arg1 == 1); + setAdbEnabled(msg.arg1 == 1, msg.arg2); break; case MSG_SET_CURRENT_FUNCTIONS: long functions = (Long) msg.obj; - setEnabledFunctions(functions, false); + operationId = (int) msg.arg1; + setEnabledFunctions(functions, false, operationId); break; case MSG_SET_SCREEN_UNLOCKED_FUNCTIONS: + operationId = sUsbOperationCount.incrementAndGet(); mScreenUnlockedFunctions = (Long) msg.obj; if (mSettings != null) { SharedPreferences.Editor editor = mSettings.edit(); @@ -1053,12 +1121,13 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { // If the screen is unlocked, also set current functions. - setScreenUnlockedFunctions(); + setScreenUnlockedFunctions(operationId); } else { - setEnabledFunctions(UsbManager.FUNCTION_NONE, false); + setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); } break; case MSG_UPDATE_SCREEN_LOCK: + operationId = sUsbOperationCount.incrementAndGet(); if (msg.arg1 == 1 == mScreenLocked) { break; } @@ -1068,23 +1137,25 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } if (mScreenLocked) { if (!mConnected) { - setEnabledFunctions(UsbManager.FUNCTION_NONE, false); + setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); } } else { if (mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE && mCurrentFunctions == UsbManager.FUNCTION_NONE) { // Set the screen unlocked functions if current function is charging. - setScreenUnlockedFunctions(); + setScreenUnlockedFunctions(operationId); } } break; case MSG_UPDATE_USER_RESTRICTIONS: + operationId = sUsbOperationCount.incrementAndGet(); // Restart the USB stack if USB transfer is enabled but no longer allowed. if (isUsbDataTransferActive(mCurrentFunctions) && !isUsbTransferAllowed()) { - setEnabledFunctions(UsbManager.FUNCTION_NONE, true); + setEnabledFunctions(UsbManager.FUNCTION_NONE, true, operationId); } break; case MSG_SYSTEM_READY: + operationId = sUsbOperationCount.incrementAndGet(); mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); @@ -1102,17 +1173,19 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser NotificationManager.IMPORTANCE_HIGH)); } mSystemReady = true; - finishBoot(); + finishBoot(operationId); break; case MSG_LOCALE_CHANGED: updateAdbNotification(true); updateUsbNotification(true); break; case MSG_BOOT_COMPLETED: + operationId = sUsbOperationCount.incrementAndGet(); mBootCompleted = true; - finishBoot(); + finishBoot(operationId); break; case MSG_USER_SWITCHED: { + operationId = sUsbOperationCount.incrementAndGet(); if (mCurrentUser != msg.arg1) { if (DEBUG) { Slog.v(TAG, "Current user switched to " + msg.arg1); @@ -1125,16 +1198,18 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mSettings.getString(String.format(Locale.ENGLISH, UNLOCKED_CONFIG_PREF, mCurrentUser), "")); } - setEnabledFunctions(UsbManager.FUNCTION_NONE, false); + setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); } break; } case MSG_ACCESSORY_MODE_ENTER_TIMEOUT: { + operationId = sUsbOperationCount.incrementAndGet(); if (DEBUG) { - Slog.v(TAG, "Accessory mode enter timeout: " + mConnected); + Slog.v(TAG, "Accessory mode enter timeout: " + mConnected + + " ,operationId: " + operationId); } if (!mConnected || (mCurrentFunctions & UsbManager.FUNCTION_ACCESSORY) == 0) { - notifyAccessoryModeExit(); + notifyAccessoryModeExit(operationId); } break; } @@ -1157,7 +1232,9 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } } - protected void finishBoot() { + public abstract void handlerInitDone(int operationId); + + protected void finishBoot(int operationId) { if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) { if (mPendingBootBroadcast) { updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions)); @@ -1165,9 +1242,9 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { - setScreenUnlockedFunctions(); + setScreenUnlockedFunctions(operationId); } else { - setEnabledFunctions(UsbManager.FUNCTION_NONE, false); + setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); } if (mCurrentAccessory != null) { mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); @@ -1507,7 +1584,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser /** * Evaluates USB function policies and applies the change accordingly. */ - protected abstract void setEnabledFunctions(long functions, boolean forceRestart); + protected abstract void setEnabledFunctions(long functions, + boolean forceRestart, int operationId); public void setAccessoryUEventTime(long accessoryConnectionStartTime) { mAccessoryConnectionStartTime = accessoryConnectionStartTime; @@ -1522,6 +1600,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mSendStringCount = 0; mStartAccessory = false; } + + public abstract void setCurrentUsbFunctionsCb(long functions, + int status, int mRequest, long mFunctions, boolean mChargingFunctions); + + public abstract void getUsbSpeedCb(int speed); } private static final class UsbHandlerLegacy extends UsbHandler { @@ -1540,6 +1623,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private String mCurrentFunctionsStr; private boolean mUsbDataUnlocked; + /** + * Keeps track of the latest setCurrentUsbFunctions request number. + */ + private int mCurrentRequest = 0; + UsbHandlerLegacy(Looper looper, Context context, UsbDeviceManager deviceManager, UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) { super(looper, context, deviceManager, alsaManager, permissionManager); @@ -1573,6 +1661,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } } + @Override + public void handlerInitDone(int operationId) { + } + private void readOemUsbOverrideConfig(Context context) { String[] configList = context.getResources().getStringArray( com.android.internal.R.array.config_oemUsbModeOverride); @@ -1675,11 +1767,14 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } @Override - protected void setEnabledFunctions(long usbFunctions, boolean forceRestart) { + protected void setEnabledFunctions(long usbFunctions, + boolean forceRestart, int operationId) { boolean usbDataUnlocked = isUsbDataTransferActive(usbFunctions); if (DEBUG) { - Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions + ", " - + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked); + Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions + + " ,forceRestart=" + forceRestart + + " ,usbDataUnlocked=" + usbDataUnlocked + + " ,operationId=" + operationId); } if (usbDataUnlocked != mUsbDataUnlocked) { @@ -1775,7 +1870,6 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser || !mCurrentFunctionsStr.equals(functions) || !mCurrentFunctionsApplied || forceRestart) { - Slog.i(TAG, "Setting USB config to " + functions); mCurrentFunctionsStr = functions; mCurrentOemFunctions = oemFunctions; mCurrentFunctionsApplied = false; @@ -1871,15 +1965,18 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false; return true; } - } - private static final class UsbHandlerHal extends UsbHandler { + @Override + public void setCurrentUsbFunctionsCb(long functions, + int status, int mRequest, long mFunctions, boolean mChargingFunctions){ + } - /** - * Proxy object for the usb gadget hal daemon. - */ - @GuardedBy("mGadgetProxyLock") - private IUsbGadget mGadgetProxy; + @Override + public void getUsbSpeedCb(int speed){ + } + } + + private final class UsbHandlerHal extends UsbHandler { private final Object mGadgetProxyLock = new Object(); @@ -1926,33 +2023,20 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager, UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) { super(looper, context, deviceManager, alsaManager, permissionManager); + int operationId = sUsbOperationCount.incrementAndGet(); try { - ServiceNotification serviceNotification = new ServiceNotification(); - - boolean ret = IServiceManager.getService() - .registerForNotifications(GADGET_HAL_FQ_NAME, "", serviceNotification); - if (!ret) { - Slog.e(TAG, "Failed to register usb gadget service start notification"); - return; - } synchronized (mGadgetProxyLock) { - mGadgetProxy = IUsbGadget.getService(true); - mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(), - USB_GADGET_HAL_DEATH_COOKIE); mCurrentFunctions = UsbManager.FUNCTION_NONE; mCurrentUsbFunctionsRequested = true; mUsbSpeed = UsbSpeed.UNKNOWN; mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0; - mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback()); + updateUsbGadgetHalVersion(); } String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); - updateUsbGadgetHalVersion(); } catch (NoSuchElementException e) { Slog.e(TAG, "Usb gadget hal not found", e); - } catch (RemoteException e) { - Slog.e(TAG, "Usb Gadget hal not responding", e); } catch (Exception e) { Slog.e(TAG, "Error initializing UsbHandler", e); } @@ -1965,7 +2049,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser if (cookie == USB_GADGET_HAL_DEATH_COOKIE) { Slog.e(TAG, "Usb Gadget hal service died cookie: " + cookie); synchronized (mGadgetProxyLock) { - mGadgetProxy = null; + mUsbGadgetHal = null; } } } @@ -1988,18 +2072,22 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser public void handleMessage(Message msg) { switch (msg.what) { case MSG_SET_CHARGING_FUNCTIONS: - setEnabledFunctions(UsbManager.FUNCTION_NONE, false); + int operationId = sUsbOperationCount.incrementAndGet(); + setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); break; case MSG_SET_FUNCTIONS_TIMEOUT: - Slog.e(TAG, "Set functions timed out! no reply from usb hal"); + operationId = sUsbOperationCount.incrementAndGet(); + Slog.e(TAG, "Set functions timed out! no reply from usb hal" + + " ,operationId:" + operationId); if (msg.arg1 != 1) { // Set this since default function may be selected from Developer options - setEnabledFunctions(mScreenUnlockedFunctions, false); + setEnabledFunctions(mScreenUnlockedFunctions, false, operationId); } break; case MSG_GET_CURRENT_USB_FUNCTIONS: Slog.i(TAG, "processing MSG_GET_CURRENT_USB_FUNCTIONS"); mCurrentUsbFunctionsReceived = true; + operationId = msg.arg2; if (mCurrentUsbFunctionsRequested) { Slog.i(TAG, "updating mCurrentFunctions"); @@ -2009,91 +2097,71 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser "mCurrentFunctions:" + mCurrentFunctions + "applied:" + msg.arg1); mCurrentFunctionsApplied = msg.arg1 == 1; } - finishBoot(); + finishBoot(operationId); break; case MSG_FUNCTION_SWITCH_TIMEOUT: /** * Dont force to default when the configuration is already set to default. */ + operationId = sUsbOperationCount.incrementAndGet(); if (msg.arg1 != 1) { // Set this since default function may be selected from Developer options - setEnabledFunctions(mScreenUnlockedFunctions, false); + setEnabledFunctions(mScreenUnlockedFunctions, false, operationId); } break; case MSG_GADGET_HAL_REGISTERED: boolean preexisting = msg.arg1 == 1; + operationId = sUsbOperationCount.incrementAndGet(); synchronized (mGadgetProxyLock) { try { - mGadgetProxy = IUsbGadget.getService(); - mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(), - USB_GADGET_HAL_DEATH_COOKIE); + mUsbGadgetHal = UsbGadgetHalInstance.getInstance(mUsbDeviceManager, + null); if (!mCurrentFunctionsApplied && !preexisting) { - setEnabledFunctions(mCurrentFunctions, false); + setEnabledFunctions(mCurrentFunctions, false, operationId); } } catch (NoSuchElementException e) { Slog.e(TAG, "Usb gadget hal not found", e); - } catch (RemoteException e) { - Slog.e(TAG, "Usb Gadget hal not responding", e); } } break; case MSG_RESET_USB_GADGET: synchronized (mGadgetProxyLock) { - if (mGadgetProxy == null) { - Slog.e(TAG, "reset Usb Gadget mGadgetProxy is null"); + if (mUsbGadgetHal == null) { + Slog.e(TAG, "reset Usb Gadget mUsbGadgetHal is null"); break; } try { - android.hardware.usb.gadget.V1_1.IUsbGadget gadgetProxy = - android.hardware.usb.gadget.V1_1.IUsbGadget - .castFrom(mGadgetProxy); - gadgetProxy.reset(); - } catch (RemoteException e) { + mUsbGadgetHal.reset(); + } catch (Exception e) { Slog.e(TAG, "reset Usb Gadget failed", e); } } break; case MSG_UPDATE_USB_SPEED: - synchronized (mGadgetProxyLock) { - if (mGadgetProxy == null) { - Slog.e(TAG, "mGadgetProxy is null"); - break; - } + operationId = sUsbOperationCount.incrementAndGet(); + if (mUsbGadgetHal == null) { + Slog.e(TAG, "mGadgetHal is null, operationId:" + operationId); + break; + } - try { - android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy = - android.hardware.usb.gadget.V1_2.IUsbGadget - .castFrom(mGadgetProxy); - if (gadgetProxy != null) { - gadgetProxy.getUsbSpeed(new UsbGadgetCallback()); - } - } catch (RemoteException e) { - Slog.e(TAG, "get UsbSpeed failed", e); - } + try { + mUsbGadgetHal.getUsbSpeed(operationId); + } catch (Exception e) { + Slog.e(TAG, "get UsbSpeed failed", e); } break; case MSG_UPDATE_HAL_VERSION: - synchronized (mGadgetProxyLock) { - if (mGadgetProxy == null) { - Slog.e(TAG, "mGadgetProxy is null"); - break; - } - - android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy = - android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy); - if (gadgetProxy == null) { - android.hardware.usb.gadget.V1_1.IUsbGadget gadgetProxyV1By1 = - android.hardware.usb.gadget.V1_1.IUsbGadget - .castFrom(mGadgetProxy); - if (gadgetProxyV1By1 == null) { - mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0; - break; - } - mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_1; - break; + if (mUsbGadgetHal == null) { + Slog.e(TAG, "mUsbGadgetHal is null"); + break; + } + else { + try { + mCurrentGadgetHalVersion = mUsbGadgetHal.getGadgetHalVersion(); + } catch (RemoteException e) { + Slog.e(TAG, "update Usb gadget version failed", e); } - mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_2; } break; default: @@ -2101,56 +2169,31 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } } - private class UsbGadgetCallback extends IUsbGadgetCallback.Stub { - int mRequest; - long mFunctions; - boolean mChargingFunctions; - - UsbGadgetCallback() { - } - - UsbGadgetCallback(int request, long functions, - boolean chargingFunctions) { - mRequest = request; - mFunctions = functions; - mChargingFunctions = chargingFunctions; - } - - @Override - public void setCurrentUsbFunctionsCb(long functions, - int status) { - /** - * Callback called for a previous setCurrenUsbFunction - */ - if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT) - || (mFunctions != functions)) { - return; - } + @Override + public void setCurrentUsbFunctionsCb(long functions, + int status, int mRequest, long mFunctions, boolean mChargingFunctions) { - removeMessages(MSG_SET_FUNCTIONS_TIMEOUT); - Slog.e(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status); - if (status == Status.SUCCESS) { - mCurrentFunctionsApplied = true; - } else if (!mChargingFunctions) { - Slog.e(TAG, "Setting default fuctions"); - sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS); - } + if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT) + || (mFunctions != functions)) { + return; } - @Override - public void getCurrentUsbFunctionsCb(long functions, - int status) { - sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions, - status == Status.FUNCTIONS_APPLIED); + removeMessages(MSG_SET_FUNCTIONS_TIMEOUT); + Slog.i(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status); + if (status == Status.SUCCESS) { + mCurrentFunctionsApplied = true; + } else if (!mChargingFunctions) { + Slog.e(TAG, "Setting default fuctions"); + sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS); } + } - @Override - public void getUsbSpeedCb(int speed) { - mUsbSpeed = speed; - } + @Override + public void getUsbSpeedCb(int speed) { + mUsbSpeed = speed; } - private void setUsbConfig(long config, boolean chargingFunctions) { + private void setUsbConfig(long config, boolean chargingFunctions, int operationId) { if (true) Slog.d(TAG, "setUsbConfig(" + config + ") request:" + ++mCurrentRequest); /** * Cancel any ongoing requests, if present. @@ -2160,8 +2203,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser removeMessages(MSG_SET_CHARGING_FUNCTIONS); synchronized (mGadgetProxyLock) { - if (mGadgetProxy == null) { - Slog.e(TAG, "setUsbConfig mGadgetProxy is null"); + if (mUsbGadgetHal == null) { + Slog.e(TAG, "setUsbConfig mUsbGadgetHal is null"); return; } try { @@ -2178,10 +2221,9 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser LocalServices.getService(AdbManagerInternal.class) .stopAdbdForTransport(AdbTransportType.USB); } - UsbGadgetCallback usbGadgetCallback = new UsbGadgetCallback(mCurrentRequest, - config, chargingFunctions); - mGadgetProxy.setCurrentUsbFunctions(config, usbGadgetCallback, - SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS); + mUsbGadgetHal.setCurrentUsbFunctions(mCurrentRequest, + config, chargingFunctions, + SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS, operationId); sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions, SET_FUNCTIONS_TIMEOUT_MS); if (mConnected) { @@ -2190,17 +2232,19 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS); } if (DEBUG) Slog.d(TAG, "timeout message queued"); - } catch (RemoteException e) { + } catch (Exception e) {//RemoteException e) { Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e); } } } @Override - protected void setEnabledFunctions(long functions, boolean forceRestart) { + protected void setEnabledFunctions(long functions, boolean forceRestart, int operationId) { if (DEBUG) { - Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", " - + "forceRestart=" + forceRestart); + Slog.d(TAG, "setEnabledFunctionsi " + + "functions=" + functions + + ", forceRestart=" + forceRestart + + ", operationId=" + operationId); } if (mCurrentGadgetHalVersion < UsbManager.GADGET_HAL_V1_2) { if ((functions & UsbManager.FUNCTION_NCM) != 0) { @@ -2221,7 +2265,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser functions = getAppliedFunctions(functions); // Set the new USB configuration. - setUsbConfig(functions, chargingFunctions); + setUsbConfig(functions, chargingFunctions, operationId); if (mBootCompleted && isUsbDataTransferActive(functions)) { // Start up dependent services. @@ -2229,6 +2273,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } } } + + @Override + public void handlerInitDone(int operationId) { + mUsbGadgetHal.getCurrentUsbFunctions(operationId); + } } /* returns the currently attached USB accessory */ @@ -2270,6 +2319,21 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser return mHandler.getGadgetHalVersion(); } + public void setCurrentUsbFunctionsCb(long functions, + int status, int mRequest, long mFunctions, boolean mChargingFunctions) { + mHandler.setCurrentUsbFunctionsCb(functions, status, + mRequest, mFunctions, mChargingFunctions); + } + + public void getCurrentUsbFunctionsCb(long functions, int status) { + mHandler.sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions, + status == Status.FUNCTIONS_APPLIED); + } + + public void getUsbSpeedCb(int speed) { + mHandler.getUsbSpeedCb(speed); + } + /** * Returns a dup of the control file descriptor for the given function. */ @@ -2295,7 +2359,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser * * @param functions The functions to set, or empty to set the charging function. */ - public void setCurrentFunctions(long functions) { + public void setCurrentFunctions(long functions, int operationId) { if (DEBUG) { Slog.d(TAG, "setCurrentFunctions(" + UsbManager.usbFunctionsToString(functions) + ")"); } @@ -2312,7 +2376,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } else if (functions == UsbManager.FUNCTION_ACCESSORY) { MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_ACCESSORY); } - mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions); + mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, operationId); } /** @@ -2340,7 +2404,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } private void onAdbEnabled(boolean enabled) { - mHandler.sendMessage(MSG_ENABLE_ADB, enabled); + int operationId = sUsbOperationCount.incrementAndGet(); + mHandler.sendMessage(MSG_ENABLE_ADB, enabled, operationId); } /** diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index d821dee75d7d..d09f729bf4ea 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -622,16 +622,16 @@ public class UsbService extends IUsbManager.Stub { } @Override - public void setCurrentFunctions(long functions) { + public void setCurrentFunctions(long functions, int operationId) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); Preconditions.checkArgument(UsbManager.areSettableFunctions(functions)); Preconditions.checkState(mDeviceManager != null); - mDeviceManager.setCurrentFunctions(functions); + mDeviceManager.setCurrentFunctions(functions, operationId); } @Override - public void setCurrentFunction(String functions, boolean usbDataUnlocked) { - setCurrentFunctions(UsbManager.usbFunctionsFromString(functions)); + public void setCurrentFunction(String functions, boolean usbDataUnlocked, int operationId) { + setCurrentFunctions(UsbManager.usbFunctionsFromString(functions), operationId); } @Override diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java new file mode 100644 index 000000000000..bdfe60ac07c1 --- /dev/null +++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.hal.gadget; + +import static android.hardware.usb.UsbManager.GADGET_HAL_V2_0; + +import static com.android.server.usb.UsbDeviceManager.logAndPrint; +import static com.android.server.usb.UsbDeviceManager.logAndPrintException; + +import android.annotation.Nullable; +import android.hardware.usb.gadget.IUsbGadget; +import android.hardware.usb.gadget.IUsbGadgetCallback; +import android.hardware.usb.UsbManager.UsbGadgetHalVersion; +import android.os.ServiceManager; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; +import android.util.LongSparseArray; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.IndentingPrintWriter; +import com.android.server.usb.UsbDeviceManager; + +import java.util.ArrayList; +import java.util.concurrent.ThreadLocalRandom; +import java.util.NoSuchElementException; +import java.util.Objects; + +/** + * Implements the methods to interact with AIDL USB HAL. + */ +public final class UsbGadgetAidl implements UsbGadgetHal { + private static final String TAG = UsbGadgetAidl.class.getSimpleName(); + private static final String USB_GADGET_AIDL_SERVICE = IUsbGadget.DESCRIPTOR + "/default"; + // Proxy object for the usb gadget hal daemon. + @GuardedBy("mGadgetProxyLock") + private IUsbGadget mGadgetProxy; + private final UsbDeviceManager mDeviceManager; + public final IndentingPrintWriter mPw; + // Mutex for all mutable shared state. + private final Object mGadgetProxyLock = new Object(); + // Callback when the UsbDevice status is changed by the kernel. + private UsbGadgetCallback mUsbGadgetCallback; + + public @UsbGadgetHalVersion int getGadgetHalVersion() throws RemoteException { + synchronized (mGadgetProxyLock) { + if (mGadgetProxy == null) { + throw new RemoteException("IUsb not initialized yet"); + } + } + Slog.i(TAG, "USB Gadget HAL AIDL version: GADGET_HAL_V2_0"); + return GADGET_HAL_V2_0; + } + + @Override + public void systemReady() { + } + + public void serviceDied() { + logAndPrint(Log.ERROR, mPw, "Usb Gadget AIDL hal service died"); + synchronized (mGadgetProxyLock) { + mGadgetProxy = null; + } + connectToProxy(null); + } + + private void connectToProxy(IndentingPrintWriter pw) { + synchronized (mGadgetProxyLock) { + if (mGadgetProxy != null) { + return; + } + + try { + mGadgetProxy = IUsbGadget.Stub.asInterface( + ServiceManager.waitForService(USB_GADGET_AIDL_SERVICE)); + } catch (NoSuchElementException e) { + logAndPrintException(pw, "connectToProxy: usb gadget hal service not found." + + " Did the service fail to start?", e); + } + } + } + + static boolean isServicePresent(IndentingPrintWriter pw) { + try { + return ServiceManager.isDeclared(USB_GADGET_AIDL_SERVICE); + } catch (NoSuchElementException e) { + logAndPrintException(pw, "connectToProxy: usb gadget Aidl hal service not found.", e); + } + + return false; + } + + public UsbGadgetAidl(UsbDeviceManager deviceManager, IndentingPrintWriter pw) { + mDeviceManager = Objects.requireNonNull(deviceManager); + mPw = pw; + connectToProxy(mPw); + } + + @Override + public void getCurrentUsbFunctions(long operationId) { + synchronized (mGadgetProxyLock) { + try { + mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback(), operationId); + } catch (RemoteException e) { + logAndPrintException(mPw, + "RemoteException while calling getCurrentUsbFunctions" + + ", opID:" + operationId, e); + return; + } + } + } + + @Override + public void getUsbSpeed(long operationId) { + try { + synchronized (mGadgetProxyLock) { + mGadgetProxy.getUsbSpeed(new UsbGadgetCallback(), operationId); + } + } catch (RemoteException e) { + logAndPrintException(mPw, + "RemoteException while calling getUsbSpeed" + + ", opID:" + operationId, e); + return; + } + } + + @Override + public void reset() { + try { + synchronized (mGadgetProxyLock) { + mGadgetProxy.reset(); + } + } catch (RemoteException e) { + logAndPrintException(mPw, + "RemoteException while calling getUsbSpeed", e); + return; + } + } + + @Override + public void setCurrentUsbFunctions(int mRequest, long mFunctions, + boolean mChargingFunctions, int timeout, long operationId) { + try { + mUsbGadgetCallback = new UsbGadgetCallback(mRequest, + mFunctions, mChargingFunctions); + synchronized (mGadgetProxyLock) { + mGadgetProxy.setCurrentUsbFunctions(mFunctions, mUsbGadgetCallback, + timeout, operationId); + } + } catch (RemoteException e) { + logAndPrintException(mPw, + "RemoteException while calling setCurrentUsbFunctions: " + + "mRequest=" + mRequest + + ", mFunctions=" + mFunctions + + ", mChargingFunctions=" + mChargingFunctions + + ", timeout=" + timeout + + ", opID:" + operationId, e); + return; + } + } + + private class UsbGadgetCallback extends IUsbGadgetCallback.Stub { + public int mRequest; + public long mFunctions; + public boolean mChargingFunctions; + + UsbGadgetCallback() { + } + + UsbGadgetCallback(int request, long functions, + boolean chargingFunctions) { + mRequest = request; + mFunctions = functions; + mChargingFunctions = chargingFunctions; + } + + @Override + public void setCurrentUsbFunctionsCb(long functions, + int status, long transactionId) { + mDeviceManager.setCurrentUsbFunctionsCb(functions, status, + mRequest, mFunctions, mChargingFunctions); + } + + @Override + public void getCurrentUsbFunctionsCb(long functions, + int status, long transactionId) { + mDeviceManager.getCurrentUsbFunctionsCb(functions, status); + } + + @Override + public void getUsbSpeedCb(int speed, long transactionId) { + mDeviceManager.getUsbSpeedCb(speed); + } + + @Override + public String getInterfaceHash() { + return IUsbGadgetCallback.HASH; + } + + @Override + public int getInterfaceVersion() { + return IUsbGadgetCallback.VERSION; + } + } +} + diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java new file mode 100644 index 000000000000..267247b5b835 --- /dev/null +++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.hal.gadget; + +import android.annotation.IntDef; +import android.hardware.usb.gadget.IUsbGadgetCallback; +import android.hardware.usb.IUsbOperationInternal; +import android.hardware.usb.UsbManager.UsbHalVersion; +import android.os.RemoteException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.String; + +/** + * @hide + */ +public interface UsbGadgetHal { + /** + * Power role: This USB port can act as a source (provide power). + * @hide + */ + public static final int HAL_POWER_ROLE_SOURCE = 1; + + /** + * Power role: This USB port can act as a sink (receive power). + * @hide + */ + public static final int HAL_POWER_ROLE_SINK = 2; + + @IntDef(prefix = { "HAL_POWER_ROLE_" }, value = { + HAL_POWER_ROLE_SOURCE, + HAL_POWER_ROLE_SINK + }) + @Retention(RetentionPolicy.SOURCE) + @interface HalUsbPowerRole{} + + /** + * Data role: This USB port can act as a host (access data services). + * @hide + */ + public static final int HAL_DATA_ROLE_HOST = 1; + + /** + * Data role: This USB port can act as a device (offer data services). + * @hide + */ + public static final int HAL_DATA_ROLE_DEVICE = 2; + + @IntDef(prefix = { "HAL_DATA_ROLE_" }, value = { + HAL_DATA_ROLE_HOST, + HAL_DATA_ROLE_DEVICE + }) + @Retention(RetentionPolicy.SOURCE) + @interface HalUsbDataRole{} + + /** + * This USB port can act as a downstream facing port (host). + * + * @hide + */ + public static final int HAL_MODE_DFP = 1; + + /** + * This USB port can act as an upstream facing port (device). + * + * @hide + */ + public static final int HAL_MODE_UFP = 2; + @IntDef(prefix = { "HAL_MODE_" }, value = { + HAL_MODE_DFP, + HAL_MODE_UFP, + }) + @Retention(RetentionPolicy.SOURCE) + @interface HalUsbPortMode{} + + /** + * UsbPortManager would call this when the system is done booting. + */ + public void systemReady(); + + /** + * This function is used to query the USB functions included in the + * current USB configuration. + * + * @param transactionId Used for tracking the current request and is passed down to the HAL + * implementation as needed. + */ + public void getCurrentUsbFunctions(long transactionId); + + /** + * The function is used to query current USB speed. + * + * @param transactionId Used for tracking the current request and is passed down to the HAL + * implementation as needed. + */ + public void getUsbSpeed(long transactionId); + + /** + * This function is used to reset USB gadget driver. + * Performs USB data connection reset. The connection will disconnect and + * reconnect. + */ + public void reset(); + + /** + * Invoked to query the version of current gadget hal implementation. + */ + public @UsbHalVersion int getGadgetHalVersion() throws RemoteException; + + /** + * This function is used to set the current USB gadget configuration. + * The USB gadget needs to be torn down if a USB configuration is already + * active. + * + * @param functions list of functions defined by GadgetFunction to be + * included in the gadget composition. + * @param timeout The maximum time (in milliseconds) within which the + * IUsbGadgetCallback needs to be returned. + * @param transactionId Used for tracking the current request and is passed down to the HAL + * implementation as needed. + */ + public void setCurrentUsbFunctions(int request, long functions, + boolean chargingFunctions, int timeout, long transactionId); +} + diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java new file mode 100644 index 000000000000..d268315a900f --- /dev/null +++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.hal.gadget; + +import static com.android.server.usb.UsbPortManager.logAndPrint; + +import com.android.internal.util.IndentingPrintWriter; +import com.android.server.usb.hal.gadget.UsbGadgetHidl; +import com.android.server.usb.hal.gadget.UsbGadgetAidl; +import com.android.server.usb.UsbDeviceManager; + +import android.util.Log; +/** + * Helper class that queries the underlying hal layer to populate UsbPortHal instance. + */ +public final class UsbGadgetHalInstance { + + public static UsbGadgetHal getInstance(UsbDeviceManager deviceManager, + IndentingPrintWriter pw) { + + logAndPrint(Log.DEBUG, pw, "Querying USB Gadget HAL version"); + if (UsbGadgetAidl.isServicePresent(null)) { + logAndPrint(Log.INFO, pw, "USB Gadget HAL AIDL present"); + return new UsbGadgetAidl(deviceManager, pw); + } + if (UsbGadgetHidl.isServicePresent(null)) { + logAndPrint(Log.INFO, pw, "USB Gadget HAL HIDL present"); + return new UsbGadgetHidl(deviceManager, pw); + } + + logAndPrint(Log.ERROR, pw, "USB Gadget HAL AIDL/HIDL not present"); + return null; + } +} + diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java new file mode 100644 index 000000000000..3e5ecc5eddf4 --- /dev/null +++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.usb.hal.gadget; + +import static android.hardware.usb.UsbManager.GADGET_HAL_NOT_SUPPORTED; +import static android.hardware.usb.UsbManager.GADGET_HAL_V1_0; +import static android.hardware.usb.UsbManager.GADGET_HAL_V1_1; +import static android.hardware.usb.UsbManager.GADGET_HAL_V1_2; + +import static com.android.server.usb.UsbDeviceManager.logAndPrint; +import static com.android.server.usb.UsbDeviceManager.logAndPrintException; + +import android.annotation.Nullable; +import android.hardware.usb.gadget.V1_0.Status; +import android.hardware.usb.gadget.V1_0.IUsbGadget; +import android.hardware.usb.gadget.V1_2.IUsbGadgetCallback; +import android.hardware.usb.gadget.V1_2.UsbSpeed; +import android.hardware.usb.UsbAccessory; +import android.hardware.usb.UsbManager; +import android.hardware.usb.UsbManager.UsbGadgetHalVersion; +import android.hardware.usb.UsbManager.UsbHalVersion; +import android.hidl.manager.V1_0.IServiceManager; +import android.hidl.manager.V1_0.IServiceNotification; +import android.os.IHwBinder; +import android.os.RemoteException; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.IndentingPrintWriter; +import com.android.server.usb.UsbDeviceManager; + +import java.util.ArrayList; +import java.util.NoSuchElementException; +import java.util.Objects; +/** + * + */ +public final class UsbGadgetHidl implements UsbGadgetHal { + // Cookie sent for usb gadget hal death notification. + private static final int USB_GADGET_HAL_DEATH_COOKIE = 2000; + // Proxy object for the usb gadget hal daemon. + @GuardedBy("mGadgetProxyLock") + private IUsbGadget mGadgetProxy; + private UsbDeviceManager mDeviceManager; + private final IndentingPrintWriter mPw; + // Mutex for all mutable shared state. + private final Object mGadgetProxyLock = new Object(); + private UsbGadgetCallback mUsbGadgetCallback; + + public @UsbGadgetHalVersion int getGadgetHalVersion() throws RemoteException { + int version; + synchronized(mGadgetProxyLock) { + if (mGadgetProxy == null) { + throw new RemoteException("IUsbGadget not initialized yet"); + } + if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) { + version = UsbManager.GADGET_HAL_V1_2; + } else if (android.hardware.usb.gadget.V1_1.IUsbGadget.castFrom(mGadgetProxy) != null) { + version = UsbManager.GADGET_HAL_V1_1; + } else { + version = UsbManager.GADGET_HAL_V1_0; + } + logAndPrint(Log.INFO, mPw, "USB Gadget HAL HIDL version: " + version); + return version; + } + } + + final class DeathRecipient implements IHwBinder.DeathRecipient { + private final IndentingPrintWriter mPw; + + DeathRecipient(IndentingPrintWriter pw) { + mPw = pw; + } + + @Override + public void serviceDied(long cookie) { + if (cookie == USB_GADGET_HAL_DEATH_COOKIE) { + logAndPrint(Log.ERROR, mPw, "Usb Gadget hal service died cookie: " + cookie); + synchronized (mGadgetProxyLock) { + mGadgetProxy = null; + } + } + } + } + + final class ServiceNotification extends IServiceNotification.Stub { + @Override + public void onRegistration(String fqName, String name, boolean preexisting) { + logAndPrint(Log.INFO, mPw, "Usb gadget hal service started " + fqName + " " + name); + connectToProxy(null); + } + } + + private void connectToProxy(IndentingPrintWriter pw) { + synchronized (mGadgetProxyLock) { + if (mGadgetProxy != null) { + return; + } + + try { + mGadgetProxy = IUsbGadget.getService(); + mGadgetProxy.linkToDeath(new DeathRecipient(pw), USB_GADGET_HAL_DEATH_COOKIE); + } catch (NoSuchElementException e) { + logAndPrintException(pw, "connectToProxy: usb gadget hal service not found." + + " Did the service fail to start?", e); + } catch (RemoteException e) { + logAndPrintException(pw, "connectToProxy: usb gadget hal service not responding" + , e); + } + } + } + + @Override + public void systemReady() { + } + + static boolean isServicePresent(IndentingPrintWriter pw) { + try { + IUsbGadget.getService(true); + } catch (NoSuchElementException e) { + logAndPrintException(pw, "connectToProxy: usb gadget hidl hal service not found.", e); + return false; + } catch (RemoteException e) { + logAndPrintException(pw, "IUSBGadget hal service present but failed to get service", e); + } + + return true; + } + + public UsbGadgetHidl(UsbDeviceManager deviceManager, IndentingPrintWriter pw) { + mDeviceManager = Objects.requireNonNull(deviceManager); + mPw = pw; + try { + ServiceNotification serviceNotification = new ServiceNotification(); + + boolean ret = IServiceManager.getService() + .registerForNotifications("android.hardware.usb.gadget@1.0::IUsbGadget", + "", serviceNotification); + if (!ret) { + logAndPrint(Log.ERROR, pw, "Failed to register service start notification"); + } + } catch (RemoteException e) { + logAndPrintException(pw, "Failed to register service start notification", e); + return; + } + connectToProxy(mPw); + } + + @Override + public void getCurrentUsbFunctions(long transactionId) { + try { + synchronized(mGadgetProxyLock) { + mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback()); + } + } catch (RemoteException e) { + logAndPrintException(mPw, + "RemoteException while calling getCurrentUsbFunctions", e); + return; + } + } + + @Override + public void getUsbSpeed(long transactionId) { + try { + synchronized(mGadgetProxyLock) { + if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) { + android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy = + android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy); + gadgetProxy.getUsbSpeed(new UsbGadgetCallback()); + } + } + } catch (RemoteException e) { + logAndPrintException(mPw, "get UsbSpeed failed", e); + } + } + + @Override + public void reset() { + try { + synchronized(mGadgetProxyLock) { + if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) { + android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy = + android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy); + gadgetProxy.reset(); + } + } + } catch (RemoteException e) { + logAndPrintException(mPw, + "RemoteException while calling getUsbSpeed", e); + return; + } + } + + @Override + public void setCurrentUsbFunctions(int mRequest, long mFunctions, + boolean mChargingFunctions, int timeout, long operationId) { + try { + mUsbGadgetCallback = new UsbGadgetCallback(null, mRequest, + mFunctions, mChargingFunctions); + synchronized(mGadgetProxyLock) { + mGadgetProxy.setCurrentUsbFunctions(mFunctions, mUsbGadgetCallback, timeout); + } + } catch (RemoteException e) { + logAndPrintException(mPw, + "RemoteException while calling setCurrentUsbFunctions" + + " mRequest = " + mRequest + + ", mFunctions = " + mFunctions + + ", timeout = " + timeout + + ", mChargingFunctions = " + mChargingFunctions + + ", operationId =" + operationId, e); + return; + } + } + + private class UsbGadgetCallback extends IUsbGadgetCallback.Stub { + public int mRequest; + public long mFunctions; + public boolean mChargingFunctions; + + UsbGadgetCallback() { + } + UsbGadgetCallback(IndentingPrintWriter pw, int request, + long functions, boolean chargingFunctions) { + mRequest = request; + mFunctions = functions; + mChargingFunctions = chargingFunctions; + } + + @Override + public void setCurrentUsbFunctionsCb(long functions, + int status) { + mDeviceManager.setCurrentUsbFunctionsCb(functions, status, + mRequest, mFunctions, mChargingFunctions); + } + + @Override + public void getCurrentUsbFunctionsCb(long functions, + int status) { + mDeviceManager.getCurrentUsbFunctionsCb(functions, status); + } + + @Override + public void getUsbSpeedCb(int speed) { + mDeviceManager.getUsbSpeedCb(speed); + } + } +} + diff --git a/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java b/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java index d133f6fbdd87..e2099e652c49 100644 --- a/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java +++ b/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java @@ -24,12 +24,15 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.hardware.usb.UsbManager; +import android.os.Binder; import android.os.RemoteException; import android.util.Log; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.concurrent.atomic.AtomicInteger; + /** * Unit tests lib for {@link android.hardware.usb.UsbManager}. */ @@ -42,6 +45,11 @@ public class UsbManagerTestLib { private UsbManager mUsbManagerMock; @Mock private android.hardware.usb.IUsbManager mMockUsbService; + /** + * Counter for tracking UsbOperation operations. + */ + private static final AtomicInteger sUsbOperationCount = new AtomicInteger(); + public UsbManagerTestLib(Context context) { MockitoAnnotations.initMocks(this); mContext = context; @@ -82,10 +90,11 @@ public class UsbManagerTestLib { } private void testSetCurrentFunctionsMock_Matched(long functions) { + int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid(); try { setCurrentFunctions(functions); - verify(mMockUsbService).setCurrentFunctions(eq(functions)); + verify(mMockUsbService).setCurrentFunctions(eq(functions), operationId); } catch (RemoteException remEx) { Log.w(TAG, "RemoteException"); } @@ -106,9 +115,10 @@ public class UsbManagerTestLib { } public void testSetCurrentFunctionsEx(long functions) throws Exception { + int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid(); setCurrentFunctions(functions); - verify(mMockUsbService).setCurrentFunctions(eq(functions)); + verify(mMockUsbService).setCurrentFunctions(eq(functions), operationId); } public void testGetCurrentFunctions_shouldMatched() { diff --git a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java index 86bcb7290d95..4103ca7c8ca8 100644 --- a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java +++ b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java @@ -98,7 +98,7 @@ public class UsbHandlerTest { } @Override - protected void setEnabledFunctions(long functions, boolean force) { + protected void setEnabledFunctions(long functions, boolean force, int operationId) { mCurrentFunctions = functions; } @@ -134,6 +134,20 @@ public class UsbHandlerTest { protected void sendStickyBroadcast(Intent intent) { mBroadcastedIntent = intent; } + + @Override + public void handlerInitDone(int operationId) { + } + + @Override + public void setCurrentUsbFunctionsCb(long functions, + int status, int mRequest, long mFunctions, boolean mChargingFunctions){ + } + + @Override + public void getUsbSpeedCb(int speed){ + } + } @Before |