Merge "usb: Implement the AIDL in framework" am: 1a0ad60b54 am: ea87ce19b3

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2361484

Change-Id: Ife441d5c375459e9d77e0be1b6a1087e861571b0
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2023-01-12 07:50:02 +00:00
committed by Automerger Merge Worker
13 changed files with 1055 additions and 260 deletions

View File

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

View File

@@ -120,6 +120,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

View File

@@ -111,10 +111,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();

View File

@@ -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 =
@@ -172,7 +174,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
@@ -184,7 +186,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";
@@ -193,7 +195,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";
@@ -201,7 +203,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";
@@ -212,7 +214,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";
@@ -221,7 +223,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";
@@ -230,7 +232,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";
@@ -238,7 +240,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";
@@ -247,7 +249,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";
@@ -255,7 +257,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";
@@ -263,7 +265,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";
@@ -271,7 +273,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";
@@ -279,7 +281,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";
@@ -287,7 +289,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";
@@ -295,31 +297,38 @@ 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.
@@ -356,7 +365,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 =
@@ -370,7 +379,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 =
@@ -380,7 +389,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 =
@@ -392,7 +401,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 =
@@ -426,7 +435,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;
@@ -434,7 +443,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;
@@ -442,7 +451,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;
@@ -450,15 +459,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;
@@ -466,7 +483,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;
@@ -474,7 +491,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;
@@ -482,7 +499,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;
@@ -490,7 +507,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;
@@ -498,7 +515,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;
@@ -506,7 +523,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;
@@ -514,7 +531,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;
@@ -530,7 +547,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;
@@ -538,7 +555,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;
@@ -546,7 +563,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;
@@ -554,7 +571,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;
@@ -562,7 +579,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;
@@ -577,63 +594,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;
@@ -643,6 +660,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);
@@ -674,6 +696,7 @@ public class UsbManager {
GADGET_HAL_V1_0,
GADGET_HAL_V1_1,
GADGET_HAL_V1_2,
GADGET_HAL_V2_0,
})
public @interface UsbGadgetHalVersion {}
@@ -692,7 +715,7 @@ public class UsbManager {
private final IUsbManager mService;
/**
* {@hide}
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public UsbManager(Context context, IUsbManager service) {
@@ -803,7 +826,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 {
@@ -921,7 +944,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());
@@ -933,7 +956,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 {
@@ -949,7 +972,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)
@@ -974,7 +997,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)
@@ -1006,14 +1029,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();
}
}
@@ -1025,14 +1051,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();
}
}
@@ -1047,7 +1076,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)
@@ -1073,7 +1102,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 {
@@ -1089,7 +1118,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 {
@@ -1111,19 +1140,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);
}
@@ -1135,7 +1162,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)
@@ -1155,7 +1182,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)
@@ -1451,7 +1478,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 {
@@ -1470,7 +1497,7 @@ public class UsbManager {
*
* @return Whether the mask is settable.
*
* {@hide}
* @hide
*/
public static boolean areSettableFunctions(long functions) {
return functions == FUNCTION_NONE
@@ -1484,7 +1511,7 @@ public class UsbManager {
*
* @return String representation of given mask
*
* {@hide}
* @hide
*/
public static String usbFunctionsToString(long functions) {
StringJoiner joiner = new StringJoiner(",");
@@ -1520,7 +1547,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)) {
@@ -1542,7 +1569,7 @@ public class UsbManager {
*
* @return a value of USB bandwidth
*
* {@hide}
* @hide
*/
public static int usbSpeedToBandwidth(int speed) {
switch (speed) {
@@ -1576,12 +1603,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;

View File

@@ -29,9 +29,10 @@ java_library_static {
"android.hardware.usb-V1.1-java",
"android.hardware.usb-V1.2-java",
"android.hardware.usb-V1.3-java",
"android.hardware.usb-V1-java",
"android.hardware.usb-V1-java",
"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",
],
}

View File

@@ -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.wm.ActivityTaskManagerInternal;
import java.io.File;
@@ -105,6 +107,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.
@@ -215,6 +218,13 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
private static UsbDeviceLogger 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);
@@ -297,15 +307,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);
@@ -319,7 +325,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
}
mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd);
if (halNotPresent) {
if (mUsbGadgetHal == null) {
/**
* Initialze the legacy UsbHandler
*/
@@ -333,6 +339,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
alsaManager, permissionManager);
}
mHandler.handlerInitDone(operationId);
if (nativeIsStartRequested()) {
if (DEBUG) Slog.d(TAG, "accessory attached at boot");
startAccessoryMode();
@@ -454,6 +462,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
@@ -474,7 +484,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);
}
}
@@ -503,6 +513,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
@@ -605,6 +629,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);
@@ -612,6 +649,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);
@@ -620,6 +673,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);
@@ -677,7 +739,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) {
@@ -686,7 +748,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, "");
}
setEnabledFunctions(mCurrentFunctions, true);
setEnabledFunctions(mCurrentFunctions, true, operationId);
updateAdbNotification(false);
}
@@ -698,6 +760,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) {
@@ -729,18 +793,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) {
@@ -866,8 +930,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 {
@@ -880,7 +944,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);
}
}
}
@@ -903,6 +968,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);
@@ -920,9 +986,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();
@@ -1026,13 +1092,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();
@@ -1043,12 +1111,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;
}
@@ -1058,23 +1127,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);
@@ -1092,17 +1163,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);
@@ -1115,16 +1188,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;
}
@@ -1147,7 +1222,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));
@@ -1155,9 +1232,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);
@@ -1491,7 +1568,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;
@@ -1506,6 +1584,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 {
@@ -1524,6 +1607,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);
@@ -1557,6 +1645,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);
@@ -1659,11 +1751,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) {
@@ -1759,7 +1854,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;
@@ -1855,15 +1949,18 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
return true;
}
@Override
public void setCurrentUsbFunctionsCb(long functions,
int status, int mRequest, long mFunctions, boolean mChargingFunctions){
}
@Override
public void getUsbSpeedCb(int speed){
}
}
private static final class UsbHandlerHal extends UsbHandler {
/**
* Proxy object for the usb gadget hal daemon.
*/
@GuardedBy("mGadgetProxyLock")
private IUsbGadget mGadgetProxy;
private final class UsbHandlerHal extends UsbHandler {
private final Object mGadgetProxyLock = new Object();
@@ -1910,33 +2007,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);
}
@@ -1949,7 +2033,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;
}
}
}
@@ -1972,18 +2056,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");
@@ -1993,91 +2081,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;
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);
}
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;
}
mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_2;
}
break;
default:
@@ -2085,56 +2153,31 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
}
}
private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
int mRequest;
long mFunctions;
boolean mChargingFunctions;
@Override
public void setCurrentUsbFunctionsCb(long functions,
int status, int mRequest, long mFunctions, boolean mChargingFunctions) {
UsbGadgetCallback() {
if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT)
|| (mFunctions != functions)) {
return;
}
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;
}
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);
}
}
@Override
public void getCurrentUsbFunctionsCb(long functions,
int status) {
sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions,
status == Status.FUNCTIONS_APPLIED);
}
@Override
public void getUsbSpeedCb(int speed) {
mUsbSpeed = speed;
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);
}
}
private void setUsbConfig(long config, boolean chargingFunctions) {
@Override
public void getUsbSpeedCb(int speed) {
mUsbSpeed = speed;
}
private void setUsbConfig(long config, boolean chargingFunctions, int operationId) {
if (true) Slog.d(TAG, "setUsbConfig(" + config + ") request:" + ++mCurrentRequest);
/**
* Cancel any ongoing requests, if present.
@@ -2144,8 +2187,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 {
@@ -2162,10 +2205,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) {
@@ -2174,17 +2216,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) {
@@ -2205,7 +2249,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.
@@ -2213,6 +2257,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
}
}
}
@Override
public void handlerInitDone(int operationId) {
mUsbGadgetHal.getCurrentUsbFunctions(operationId);
}
}
/* returns the currently attached USB accessory */
@@ -2254,6 +2303,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.
*/
@@ -2279,7 +2343,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) + ")");
}
@@ -2296,7 +2360,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);
}
/**
@@ -2324,7 +2388,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);
}
/**

View File

@@ -605,16 +605,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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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