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

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

Change-Id: I08010bbef31b7ef8daa67605fb9bde2d6facfdf0
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2023-01-12 06:58:40 +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.function.Consumer;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class UsbCommand extends Svc.Command { public class UsbCommand extends Svc.Command {
public UsbCommand() { public UsbCommand() {
super("usb"); super("usb");
} }
/**
* Counter for tracking UsbOperation operations.
*/
private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
@Override @Override
public String shortHelp() { public String shortHelp() {
return "Control Usb state"; return "Control Usb state";
@@ -92,8 +98,10 @@ public class UsbCommand extends Svc.Command {
if ("setFunctions".equals(args[1])) { if ("setFunctions".equals(args[1])) {
try { try {
int operationId = sUsbOperationCount.incrementAndGet();
System.out.println("setCurrentFunctions opId:" + operationId);
usbMgr.setCurrentFunctions(UsbManager.usbFunctionsFromString( usbMgr.setCurrentFunctions(UsbManager.usbFunctionsFromString(
args.length >= 3 ? args[2] : "")); args.length >= 3 ? args[2] : ""), operationId);
} catch (RemoteException e) { } catch (RemoteException e) {
System.err.println("Error communicating with UsbManager: " + 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_0 = 10; // 0xa
field public static final int GADGET_HAL_V1_1 = 11; // 0xb 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_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_10G = 10240; // 0x2800
field public static final int USB_DATA_TRANSFER_RATE_20G = 20480; // 0x5000 field public static final int USB_DATA_TRANSFER_RATE_20G = 20480; // 0x5000
field public static final int USB_DATA_TRANSFER_RATE_40G = 40960; // 0xa000 field public static final int USB_DATA_TRANSFER_RATE_40G = 40960; // 0xa000

View File

@@ -111,10 +111,10 @@ interface IUsbManager
boolean isFunctionEnabled(String function); boolean isFunctionEnabled(String function);
/* Sets the current USB function. */ /* Sets the current USB function. */
void setCurrentFunctions(long functions); void setCurrentFunctions(long functions, int operationId);
/* Compatibility version of setCurrentFunctions(long). */ /* Compatibility version of setCurrentFunctions(long). */
void setCurrentFunction(String function, boolean usbDataUnlocked); void setCurrentFunction(String function, boolean usbDataUnlocked, int operationId);
/* Gets the current USB functions. */ /* Gets the current USB functions. */
long getCurrentFunctions(); long getCurrentFunctions();

View File

@@ -38,6 +38,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.hardware.usb.gadget.V1_0.GadgetFunction; import android.hardware.usb.gadget.V1_0.GadgetFunction;
import android.hardware.usb.gadget.V1_2.UsbSpeed; import android.hardware.usb.gadget.V1_2.UsbSpeed;
import android.os.Binder;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
@@ -52,6 +53,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.StringJoiner; 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. * 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, * 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. * USB is not configued, MTP function is enabled, and all the other functions are disabled.
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String ACTION_USB_STATE = 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 * <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> * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p>
* *
* {@hide} * @hide
*/ */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@SystemApi @SystemApi
@@ -184,7 +186,7 @@ public class UsbManager {
* Boolean extra indicating whether USB is connected or disconnected. * Boolean extra indicating whether USB is connected or disconnected.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast. * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String USB_CONNECTED = "connected"; 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. * Boolean extra indicating whether USB is connected or disconnected as host.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast. * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
* *
* {@hide} * @hide
*/ */
public static final String USB_HOST_CONNECTED = "host_connected"; public static final String USB_HOST_CONNECTED = "host_connected";
@@ -201,7 +203,7 @@ public class UsbManager {
* Boolean extra indicating whether USB is configured. * Boolean extra indicating whether USB is configured.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast. * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String USB_CONFIGURED = "configured"; public static final String USB_CONFIGURED = "configured";
@@ -212,7 +214,7 @@ public class UsbManager {
* has explicitly asked for this data to be unlocked. * has explicitly asked for this data to be unlocked.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast. * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
* *
* {@hide} * @hide
*/ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final String USB_DATA_UNLOCKED = "unlocked"; 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. * A placeholder indicating that no USB function is being specified.
* Used for compatibility with old init scripts to indicate no functions vs. charging function. * Used for compatibility with old init scripts to indicate no functions vs. charging function.
* *
* {@hide} * @hide
*/ */
@UnsupportedAppUsage @UnsupportedAppUsage
public static final String USB_FUNCTION_NONE = "none"; public static final String USB_FUNCTION_NONE = "none";
@@ -230,7 +232,7 @@ public class UsbManager {
* Name of the adb USB function. * Name of the adb USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast * Used in extras for the {@link #ACTION_USB_STATE} broadcast
* *
* {@hide} * @hide
*/ */
public static final String USB_FUNCTION_ADB = "adb"; public static final String USB_FUNCTION_ADB = "adb";
@@ -238,7 +240,7 @@ public class UsbManager {
* Name of the RNDIS ethernet USB function. * Name of the RNDIS ethernet USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast * Used in extras for the {@link #ACTION_USB_STATE} broadcast
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String USB_FUNCTION_RNDIS = "rndis"; public static final String USB_FUNCTION_RNDIS = "rndis";
@@ -247,7 +249,7 @@ public class UsbManager {
* Name of the MTP USB function. * Name of the MTP USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast * Used in extras for the {@link #ACTION_USB_STATE} broadcast
* *
* {@hide} * @hide
*/ */
public static final String USB_FUNCTION_MTP = "mtp"; public static final String USB_FUNCTION_MTP = "mtp";
@@ -255,7 +257,7 @@ public class UsbManager {
* Name of the PTP USB function. * Name of the PTP USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast * Used in extras for the {@link #ACTION_USB_STATE} broadcast
* *
* {@hide} * @hide
*/ */
public static final String USB_FUNCTION_PTP = "ptp"; public static final String USB_FUNCTION_PTP = "ptp";
@@ -263,7 +265,7 @@ public class UsbManager {
* Name of the audio source USB function. * Name of the audio source USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast * Used in extras for the {@link #ACTION_USB_STATE} broadcast
* *
* {@hide} * @hide
*/ */
public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source"; public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
@@ -271,7 +273,7 @@ public class UsbManager {
* Name of the MIDI USB function. * Name of the MIDI USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast * Used in extras for the {@link #ACTION_USB_STATE} broadcast
* *
* {@hide} * @hide
*/ */
public static final String USB_FUNCTION_MIDI = "midi"; public static final String USB_FUNCTION_MIDI = "midi";
@@ -279,7 +281,7 @@ public class UsbManager {
* Name of the Accessory USB function. * Name of the Accessory USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast * Used in extras for the {@link #ACTION_USB_STATE} broadcast
* *
* {@hide} * @hide
*/ */
public static final String USB_FUNCTION_ACCESSORY = "accessory"; public static final String USB_FUNCTION_ACCESSORY = "accessory";
@@ -287,7 +289,7 @@ public class UsbManager {
* Name of the NCM USB function. * Name of the NCM USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast * Used in extras for the {@link #ACTION_USB_STATE} broadcast
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String USB_FUNCTION_NCM = "ncm"; public static final String USB_FUNCTION_NCM = "ncm";
@@ -295,31 +297,38 @@ public class UsbManager {
/** /**
* Name of Gadget Hal Not Present; * Name of Gadget Hal Not Present;
* *
* {@hide} * @hide
*/ */
public static final String GADGET_HAL_UNKNOWN = "unknown"; public static final String GADGET_HAL_UNKNOWN = "unknown";
/** /**
* Name of the USB Gadget Hal Version v1.0; * Name of the USB Gadget Hal Version v1.0;
* *
* {@hide} * @hide
*/ */
public static final String GADGET_HAL_VERSION_1_0 = "V1_0"; public static final String GADGET_HAL_VERSION_1_0 = "V1_0";
/** /**
* Name of the USB Gadget Hal Version v1.1; * Name of the USB Gadget Hal Version v1.1;
* *
* {@hide} * @hide
*/ */
public static final String GADGET_HAL_VERSION_1_1 = "V1_1"; public static final String GADGET_HAL_VERSION_1_1 = "V1_1";
/** /**
* Name of the USB Gadget Hal Version v1.2; * Name of the USB Gadget Hal Version v1.2;
* *
* {@hide} * @hide
*/ */
public static final String GADGET_HAL_VERSION_1_2 = "V1_2"; 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} * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
* containing the {@link UsbPort} object for the port. * containing the {@link UsbPort} object for the port.
@@ -356,7 +365,7 @@ public class UsbManager {
* This is obtained with SystemClock.elapsedRealtime() * This is obtained with SystemClock.elapsedRealtime()
* Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String EXTRA_ACCESSORY_UEVENT_TIME = public static final String EXTRA_ACCESSORY_UEVENT_TIME =
@@ -370,7 +379,7 @@ public class UsbManager {
* between communicating with USB accessory handshake, refer to * between communicating with USB accessory handshake, refer to
* <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p> * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p>
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String EXTRA_ACCESSORY_STRING_COUNT = public static final String EXTRA_ACCESSORY_STRING_COUNT =
@@ -380,7 +389,7 @@ public class UsbManager {
* Boolean extra indicating whether got start accessory or not * Boolean extra indicating whether got start accessory or not
* Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String EXTRA_ACCESSORY_START = public static final String EXTRA_ACCESSORY_START =
@@ -392,7 +401,7 @@ public class UsbManager {
* sending {@link #ACTION_USB_ACCESSORY_HANDSHAKE}. * sending {@link #ACTION_USB_ACCESSORY_HANDSHAKE}.
* Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final String EXTRA_ACCESSORY_HANDSHAKE_END = public static final String EXTRA_ACCESSORY_HANDSHAKE_END =
@@ -426,7 +435,7 @@ public class UsbManager {
/** /**
* The Value for USB gadget hal is not presented. * The Value for USB gadget hal is not presented.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int GADGET_HAL_NOT_SUPPORTED = -1; public static final int GADGET_HAL_NOT_SUPPORTED = -1;
@@ -434,7 +443,7 @@ public class UsbManager {
/** /**
* Value for Gadget Hal Version v1.0. * Value for Gadget Hal Version v1.0.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int GADGET_HAL_V1_0 = 10; public static final int GADGET_HAL_V1_0 = 10;
@@ -442,7 +451,7 @@ public class UsbManager {
/** /**
* Value for Gadget Hal Version v1.1. * Value for Gadget Hal Version v1.1.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int GADGET_HAL_V1_1 = 11; public static final int GADGET_HAL_V1_1 = 11;
@@ -450,15 +459,23 @@ public class UsbManager {
/** /**
* Value for Gadget Hal Version v1.2. * Value for Gadget Hal Version v1.2.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int GADGET_HAL_V1_2 = 12; 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. * Value for USB_STATE is not configured.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_UNKNOWN = -1; 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). * Value for USB Transfer Rate of Low Speed in Mbps (real value is 1.5Mbps).
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_LOW_SPEED = 2; 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. * Value for USB Transfer Rate of Full Speed in Mbps.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_FULL_SPEED = 12; 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. * Value for USB Transfer Rate of High Speed in Mbps.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_HIGH_SPEED = 480; 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. * Value for USB Transfer Rate of Super Speed in Mbps.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_5G = 5 * 1024; 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. * Value for USB Transfer Rate of 10G.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_10G = 10 * 1024; 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. * Value for USB Transfer Rate of 20G.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_20G = 20 * 1024; 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. * Value for USB Transfer Rate of 40G.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_DATA_TRANSFER_RATE_40G = 40 * 1024; 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. * The Value for USB hal is not presented.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_NOT_SUPPORTED = -1; public static final int USB_HAL_NOT_SUPPORTED = -1;
@@ -538,7 +555,7 @@ public class UsbManager {
/** /**
* Value for USB Hal Version v1.0. * Value for USB Hal Version v1.0.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_V1_0 = 10; public static final int USB_HAL_V1_0 = 10;
@@ -546,7 +563,7 @@ public class UsbManager {
/** /**
* Value for USB Hal Version v1.1. * Value for USB Hal Version v1.1.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_V1_1 = 11; public static final int USB_HAL_V1_1 = 11;
@@ -554,7 +571,7 @@ public class UsbManager {
/** /**
* Value for USB Hal Version v1.2. * Value for USB Hal Version v1.2.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_V1_2 = 12; public static final int USB_HAL_V1_2 = 12;
@@ -562,7 +579,7 @@ public class UsbManager {
/** /**
* Value for USB Hal Version v1.3. * Value for USB Hal Version v1.3.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int USB_HAL_V1_3 = 13; 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)} * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)}
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_NONE = 0; public static final long FUNCTION_NONE = 0;
/** /**
* Code for the mtp usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Code for the mtp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_MTP = GadgetFunction.MTP; public static final long FUNCTION_MTP = GadgetFunction.MTP;
/** /**
* Code for the ptp usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Code for the ptp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_PTP = GadgetFunction.PTP; public static final long FUNCTION_PTP = GadgetFunction.PTP;
/** /**
* Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_RNDIS = GadgetFunction.RNDIS; public static final long FUNCTION_RNDIS = GadgetFunction.RNDIS;
/** /**
* Code for the midi usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Code for the midi usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_MIDI = GadgetFunction.MIDI; public static final long FUNCTION_MIDI = GadgetFunction.MIDI;
/** /**
* Code for the accessory usb function. * Code for the accessory usb function.
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_ACCESSORY = GadgetFunction.ACCESSORY; public static final long FUNCTION_ACCESSORY = GadgetFunction.ACCESSORY;
/** /**
* Code for the audio source usb function. * Code for the audio source usb function.
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_AUDIO_SOURCE = GadgetFunction.AUDIO_SOURCE; public static final long FUNCTION_AUDIO_SOURCE = GadgetFunction.AUDIO_SOURCE;
/** /**
* Code for the adb usb function. * Code for the adb usb function.
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_ADB = GadgetFunction.ADB; public static final long FUNCTION_ADB = GadgetFunction.ADB;
/** /**
* Code for the ncm source usb function. * Code for the ncm source usb function.
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
public static final long FUNCTION_NCM = 1 << 10; 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<>(); 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 { static {
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP); FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_PTP, FUNCTION_PTP); 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_0,
GADGET_HAL_V1_1, GADGET_HAL_V1_1,
GADGET_HAL_V1_2, GADGET_HAL_V1_2,
GADGET_HAL_V2_0,
}) })
public @interface UsbGadgetHalVersion {} public @interface UsbGadgetHalVersion {}
@@ -692,7 +715,7 @@ public class UsbManager {
private final IUsbManager mService; private final IUsbManager mService;
/** /**
* {@hide} * @hide
*/ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public UsbManager(Context context, IUsbManager service) { public UsbManager(Context context, IUsbManager service) {
@@ -803,7 +826,7 @@ public class UsbManager {
* {@link #FUNCTION_PTP} are supported. * {@link #FUNCTION_PTP} are supported.
* @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found. * @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found.
* *
* {@hide} * @hide
*/ */
public ParcelFileDescriptor getControlFd(long function) { public ParcelFileDescriptor getControlFd(long function) {
try { try {
@@ -921,7 +944,7 @@ public class UsbManager {
* Only system components can call this function. * Only system components can call this function.
* @param device to request permissions for * @param device to request permissions for
* *
* {@hide} * @hide
*/ */
public void grantPermission(UsbDevice device) { public void grantPermission(UsbDevice device) {
grantPermission(device, Process.myUid()); grantPermission(device, Process.myUid());
@@ -933,7 +956,7 @@ public class UsbManager {
* @param device to request permissions for * @param device to request permissions for
* @uid uid to give permission * @uid uid to give permission
* *
* {@hide} * @hide
*/ */
public void grantPermission(UsbDevice device, int uid) { public void grantPermission(UsbDevice device, int uid) {
try { try {
@@ -949,7 +972,7 @@ public class UsbManager {
* @param device to request permissions for * @param device to request permissions for
* @param packageName of package to grant permissions * @param packageName of package to grant permissions
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
@RequiresPermission(Manifest.permission.MANAGE_USB) @RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -974,7 +997,7 @@ public class UsbManager {
* @param function name of the USB function * @param function name of the USB function
* @return true if the USB function is enabled * @return true if the USB function is enabled
* *
* {@hide} * @hide
*/ */
@Deprecated @Deprecated
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @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. * @param functions the USB function(s) to set, as a bitwise mask.
* Must satisfy {@link UsbManager#areSettableFunctions} * Must satisfy {@link UsbManager#areSettableFunctions}
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
@RequiresPermission(Manifest.permission.MANAGE_USB) @RequiresPermission(Manifest.permission.MANAGE_USB)
public void setCurrentFunctions(@UsbFunctionMode long functions) { public void setCurrentFunctions(@UsbFunctionMode long functions) {
int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
try { try {
mService.setCurrentFunctions(functions); mService.setCurrentFunctions(functions, operationId);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "setCurrentFunctions: failed to call setCurrentFunctions. functions:"
+ functions + ", opId:" + operationId, e);
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }
} }
@@ -1025,14 +1051,17 @@ public class UsbManager {
* @param functions the USB function(s) to set. * @param functions the USB function(s) to set.
* @param usbDataUnlocked unused * @param usbDataUnlocked unused
* {@hide} * @hide
*/ */
@Deprecated @Deprecated
@UnsupportedAppUsage @UnsupportedAppUsage
public void setCurrentFunction(String functions, boolean usbDataUnlocked) { public void setCurrentFunction(String functions, boolean usbDataUnlocked) {
int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
try { try {
mService.setCurrentFunction(functions, usbDataUnlocked); mService.setCurrentFunction(functions, usbDataUnlocked, operationId);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "setCurrentFunction: failed to call setCurrentFunction. functions:"
+ functions + ", opId:" + operationId, e);
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }
} }
@@ -1047,7 +1076,7 @@ public class UsbManager {
* @return The currently enabled functions, in a bitwise mask. * @return The currently enabled functions, in a bitwise mask.
* A zero mask indicates that the current function is the charging function. * A zero mask indicates that the current function is the charging function.
* *
* {@hide} * @hide
*/ */
@SystemApi @SystemApi
@RequiresPermission(Manifest.permission.MANAGE_USB) @RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1073,7 +1102,7 @@ public class UsbManager {
* @param functions functions to set, in a bitwise mask. * @param functions functions to set, in a bitwise mask.
* Must satisfy {@link UsbManager#areSettableFunctions} * Must satisfy {@link UsbManager#areSettableFunctions}
* *
* {@hide} * @hide
*/ */
public void setScreenUnlockedFunctions(long functions) { public void setScreenUnlockedFunctions(long functions) {
try { try {
@@ -1089,7 +1118,7 @@ public class UsbManager {
* @return The currently set screen enabled functions. * @return The currently set screen enabled functions.
* A zero mask indicates that the screen unlocked functions feature is not enabled. * A zero mask indicates that the screen unlocked functions feature is not enabled.
* *
* {@hide} * @hide
*/ */
public long getScreenUnlockedFunctions() { public long getScreenUnlockedFunctions() {
try { try {
@@ -1111,19 +1140,17 @@ public class UsbManager {
* *
* @return The value of currently USB Bandwidth. * @return The value of currently USB Bandwidth.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(Manifest.permission.MANAGE_USB) @RequiresPermission(Manifest.permission.MANAGE_USB)
public int getUsbBandwidthMbps() { public int getUsbBandwidthMbps() {
int usbSpeed; int usbSpeed;
try { try {
usbSpeed = mService.getCurrentUsbSpeed(); usbSpeed = mService.getCurrentUsbSpeed();
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }
return usbSpeedToBandwidth(usbSpeed); return usbSpeedToBandwidth(usbSpeed);
} }
@@ -1135,7 +1162,7 @@ public class UsbManager {
* *
* @return a integer {@code GADGET_HAL_*} represent hal version. * @return a integer {@code GADGET_HAL_*} represent hal version.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(Manifest.permission.MANAGE_USB) @RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1155,7 +1182,7 @@ public class UsbManager {
* *
* @return a integer {@code USB_HAL_*} represent hal version. * @return a integer {@code USB_HAL_*} represent hal version.
* *
* {@hide} * @hide
*/ */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(Manifest.permission.MANAGE_USB) @RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1451,7 +1478,7 @@ public class UsbManager {
* @param usbDeviceConnectionHandler The component to handle usb connections, * @param usbDeviceConnectionHandler The component to handle usb connections,
* {@code null} to unset. * {@code null} to unset.
* *
* {@hide} * @hide
*/ */
public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) { public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) {
try { try {
@@ -1470,7 +1497,7 @@ public class UsbManager {
* *
* @return Whether the mask is settable. * @return Whether the mask is settable.
* *
* {@hide} * @hide
*/ */
public static boolean areSettableFunctions(long functions) { public static boolean areSettableFunctions(long functions) {
return functions == FUNCTION_NONE return functions == FUNCTION_NONE
@@ -1484,7 +1511,7 @@ public class UsbManager {
* *
* @return String representation of given mask * @return String representation of given mask
* *
* {@hide} * @hide
*/ */
public static String usbFunctionsToString(long functions) { public static String usbFunctionsToString(long functions) {
StringJoiner joiner = new StringJoiner(","); StringJoiner joiner = new StringJoiner(",");
@@ -1520,7 +1547,7 @@ public class UsbManager {
* *
* @return A mask of all valid functions in the string * @return A mask of all valid functions in the string
* *
* {@hide} * @hide
*/ */
public static long usbFunctionsFromString(String functions) { public static long usbFunctionsFromString(String functions) {
if (functions == null || functions.equals(USB_FUNCTION_NONE)) { if (functions == null || functions.equals(USB_FUNCTION_NONE)) {
@@ -1542,7 +1569,7 @@ public class UsbManager {
* *
* @return a value of USB bandwidth * @return a value of USB bandwidth
* *
* {@hide} * @hide
*/ */
public static int usbSpeedToBandwidth(int speed) { public static int usbSpeedToBandwidth(int speed) {
switch (speed) { switch (speed) {
@@ -1576,12 +1603,14 @@ public class UsbManager {
* *
* @return String representation of Usb Gadget Hal Version * @return String representation of Usb Gadget Hal Version
* *
* {@hide} * @hide
*/ */
public static @NonNull String usbGadgetHalVersionToString(int version) { public static @NonNull String usbGadgetHalVersionToString(int version) {
String halVersion; 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; halVersion = GADGET_HAL_VERSION_1_2;
} else if (version == GADGET_HAL_V1_1) { } else if (version == GADGET_HAL_V1_1) {
halVersion = GADGET_HAL_VERSION_1_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.1-java",
"android.hardware.usb-V1.2-java", "android.hardware.usb-V1.2-java",
"android.hardware.usb-V1.3-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.0-java",
"android.hardware.usb.gadget-V1.1-java", "android.hardware.usb.gadget-V1.1-java",
"android.hardware.usb.gadget-V1.2-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.AdbNotifications;
import android.debug.AdbTransportType; import android.debug.AdbTransportType;
import android.debug.IAdbTransport; import android.debug.IAdbTransport;
import android.hardware.usb.IUsbOperationInternal;
import android.hardware.usb.ParcelableUsbPort; import android.hardware.usb.ParcelableUsbPort;
import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbConfiguration; import android.hardware.usb.UsbConfiguration;
@@ -54,9 +55,7 @@ import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus; import android.hardware.usb.UsbPortStatus;
import android.hardware.usb.gadget.V1_0.GadgetFunction; 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_0.Status;
import android.hardware.usb.gadget.V1_2.IUsbGadgetCallback;
import android.hardware.usb.gadget.V1_2.UsbSpeed; import android.hardware.usb.gadget.V1_2.UsbSpeed;
import android.hidl.manager.V1_0.IServiceManager; import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification; 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.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.SomeArgs; import com.android.internal.os.SomeArgs;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.dump.DualDumpOutputStream; import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.server.FgThread; import com.android.server.FgThread;
import com.android.server.LocalServices; 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 com.android.server.wm.ActivityTaskManagerInternal;
import java.io.File; import java.io.File;
@@ -105,6 +107,7 @@ import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Scanner; import java.util.Scanner;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* UsbDeviceManager manages USB state in device mode. * UsbDeviceManager manages USB state in device mode.
@@ -215,6 +218,13 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
private static UsbDeviceLogger sEventLogger; private static UsbDeviceLogger sEventLogger;
private UsbGadgetHal mUsbGadgetHal;
/**
* Counter for tracking UsbOperation operations.
*/
private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
static { static {
sDenyInterfaces = new HashSet<>(); sDenyInterfaces = new HashSet<>();
sDenyInterfaces.add(UsbConstants.USB_CLASS_AUDIO); sDenyInterfaces.add(UsbConstants.USB_CLASS_AUDIO);
@@ -297,15 +307,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
initRndisAddress(); initRndisAddress();
int operationId = sUsbOperationCount.incrementAndGet();
boolean halNotPresent = false; boolean halNotPresent = false;
try {
IUsbGadget.getService(true); mUsbGadgetHal = UsbGadgetHalInstance.getInstance(this, null);
} catch (RemoteException e) { Slog.d(TAG, "getInstance done");
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);
}
mControlFds = new HashMap<>(); mControlFds = new HashMap<>();
FileDescriptor mtpFd = nativeOpenControl(UsbManager.USB_FUNCTION_MTP); FileDescriptor mtpFd = nativeOpenControl(UsbManager.USB_FUNCTION_MTP);
@@ -319,7 +325,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
} }
mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd); mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd);
if (halNotPresent) { if (mUsbGadgetHal == null) {
/** /**
* Initialze the legacy UsbHandler * Initialze the legacy UsbHandler
*/ */
@@ -333,6 +339,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
alsaManager, permissionManager); alsaManager, permissionManager);
} }
mHandler.handlerInitDone(operationId);
if (nativeIsStartRequested()) { if (nativeIsStartRequested()) {
if (DEBUG) Slog.d(TAG, "accessory attached at boot"); if (DEBUG) Slog.d(TAG, "accessory attached at boot");
startAccessoryMode(); startAccessoryMode();
@@ -454,6 +462,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
private void startAccessoryMode() { private void startAccessoryMode() {
if (!mHasUsbAccessory) return; if (!mHasUsbAccessory) return;
int operationId = sUsbOperationCount.incrementAndGet();
mAccessoryStrings = nativeGetAccessoryStrings(); mAccessoryStrings = nativeGetAccessoryStrings();
boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE); boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
// don't start accessory mode if our mandatory strings have not been set // 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); ACCESSORY_REQUEST_TIMEOUT);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT), mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT),
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 { abstract static class UsbHandler extends Handler {
// current USB state // current USB state
@@ -605,6 +629,19 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
sendMessage(m); 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) { public void sendMessage(int what, Object arg) {
removeMessages(what); removeMessages(what);
Message m = Message.obtain(this, what); Message m = Message.obtain(this, what);
@@ -612,6 +649,22 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
sendMessage(m); 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) { public void sendMessage(int what, Object arg, boolean arg1) {
removeMessages(what); removeMessages(what);
Message m = Message.obtain(this, what); Message m = Message.obtain(this, what);
@@ -620,6 +673,15 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
sendMessage(m); 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) { public void sendMessage(int what, boolean arg1, boolean arg2) {
removeMessages(what); removeMessages(what);
Message m = Message.obtain(this, what); Message m = Message.obtain(this, what);
@@ -677,7 +739,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
sendMessageDelayed(msg, HOST_STATE_UPDATE_DELAY); 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 (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
if (enable) { if (enable) {
@@ -686,7 +748,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, ""); setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, "");
} }
setEnabledFunctions(mCurrentFunctions, true); setEnabledFunctions(mCurrentFunctions, true, operationId);
updateAdbNotification(false); updateAdbNotification(false);
} }
@@ -698,6 +760,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
private void updateCurrentAccessory() { private void updateCurrentAccessory() {
// We are entering accessory mode if we have received a request from the host // We are entering accessory mode if we have received a request from the host
// and the request has not timed out yet. // and the request has not timed out yet.
int operationId = sUsbOperationCount.incrementAndGet();
boolean enteringAccessoryMode = hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT); boolean enteringAccessoryMode = hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT);
if (mConfigured && enteringAccessoryMode) { if (mConfigured && enteringAccessoryMode) {
@@ -729,18 +793,18 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
} }
} else { } else {
if (!enteringAccessoryMode) { if (!enteringAccessoryMode) {
notifyAccessoryModeExit(); notifyAccessoryModeExit(operationId);
} else if (DEBUG) { } else if (DEBUG) {
Slog.v(TAG, "Debouncing accessory mode exit"); Slog.v(TAG, "Debouncing accessory mode exit");
} }
} }
} }
private void notifyAccessoryModeExit() { private void notifyAccessoryModeExit(int operationId) {
// make sure accessory mode is off // make sure accessory mode is off
// and restore default functions // and restore default functions
Slog.d(TAG, "exited USB accessory mode"); Slog.d(TAG, "exited USB accessory mode");
setEnabledFunctions(UsbManager.FUNCTION_NONE, false); setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
if (mCurrentAccessory != null) { if (mCurrentAccessory != null) {
if (mBootCompleted) { if (mBootCompleted) {
@@ -866,8 +930,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
mMidiEnabled && mConfigured, mMidiCard, mMidiDevice); mMidiEnabled && mConfigured, mMidiCard, mMidiDevice);
} }
private void setScreenUnlockedFunctions() { private void setScreenUnlockedFunctions(int operationId) {
setEnabledFunctions(mScreenUnlockedFunctions, false); setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
} }
private static class AdbTransport extends IAdbTransport.Stub { private static class AdbTransport extends IAdbTransport.Stub {
@@ -880,7 +944,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
@Override @Override
public void onAdbEnabled(boolean enabled, byte transportType) { public void onAdbEnabled(boolean enabled, byte transportType) {
if (transportType == AdbTransportType.USB) { 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) { public void handleMessage(Message msg) {
switch (msg.what) { switch (msg.what) {
case MSG_UPDATE_STATE: case MSG_UPDATE_STATE:
int operationId = sUsbOperationCount.incrementAndGet();
mConnected = (msg.arg1 == 1); mConnected = (msg.arg1 == 1);
mConfigured = (msg.arg2 == 1); mConfigured = (msg.arg2 == 1);
@@ -920,9 +986,9 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
// restore defaults when USB is disconnected // restore defaults when USB is disconnected
if (!mScreenLocked if (!mScreenLocked
&& mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
setScreenUnlockedFunctions(); setScreenUnlockedFunctions(operationId);
} else { } else {
setEnabledFunctions(UsbManager.FUNCTION_NONE, false); setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
} }
} }
updateUsbFunctions(); updateUsbFunctions();
@@ -1026,13 +1092,15 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
updateUsbNotification(false); updateUsbNotification(false);
break; break;
case MSG_ENABLE_ADB: case MSG_ENABLE_ADB:
setAdbEnabled(msg.arg1 == 1); setAdbEnabled(msg.arg1 == 1, msg.arg2);
break; break;
case MSG_SET_CURRENT_FUNCTIONS: case MSG_SET_CURRENT_FUNCTIONS:
long functions = (Long) msg.obj; long functions = (Long) msg.obj;
setEnabledFunctions(functions, false); operationId = (int) msg.arg1;
setEnabledFunctions(functions, false, operationId);
break; break;
case MSG_SET_SCREEN_UNLOCKED_FUNCTIONS: case MSG_SET_SCREEN_UNLOCKED_FUNCTIONS:
operationId = sUsbOperationCount.incrementAndGet();
mScreenUnlockedFunctions = (Long) msg.obj; mScreenUnlockedFunctions = (Long) msg.obj;
if (mSettings != null) { if (mSettings != null) {
SharedPreferences.Editor editor = mSettings.edit(); SharedPreferences.Editor editor = mSettings.edit();
@@ -1043,12 +1111,13 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
} }
if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
// If the screen is unlocked, also set current functions. // If the screen is unlocked, also set current functions.
setScreenUnlockedFunctions(); setScreenUnlockedFunctions(operationId);
} else { } else {
setEnabledFunctions(UsbManager.FUNCTION_NONE, false); setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
} }
break; break;
case MSG_UPDATE_SCREEN_LOCK: case MSG_UPDATE_SCREEN_LOCK:
operationId = sUsbOperationCount.incrementAndGet();
if (msg.arg1 == 1 == mScreenLocked) { if (msg.arg1 == 1 == mScreenLocked) {
break; break;
} }
@@ -1058,23 +1127,25 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
} }
if (mScreenLocked) { if (mScreenLocked) {
if (!mConnected) { if (!mConnected) {
setEnabledFunctions(UsbManager.FUNCTION_NONE, false); setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
} }
} else { } else {
if (mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE if (mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE
&& mCurrentFunctions == UsbManager.FUNCTION_NONE) { && mCurrentFunctions == UsbManager.FUNCTION_NONE) {
// Set the screen unlocked functions if current function is charging. // Set the screen unlocked functions if current function is charging.
setScreenUnlockedFunctions(); setScreenUnlockedFunctions(operationId);
} }
} }
break; break;
case MSG_UPDATE_USER_RESTRICTIONS: case MSG_UPDATE_USER_RESTRICTIONS:
operationId = sUsbOperationCount.incrementAndGet();
// Restart the USB stack if USB transfer is enabled but no longer allowed. // Restart the USB stack if USB transfer is enabled but no longer allowed.
if (isUsbDataTransferActive(mCurrentFunctions) && !isUsbTransferAllowed()) { if (isUsbDataTransferActive(mCurrentFunctions) && !isUsbTransferAllowed()) {
setEnabledFunctions(UsbManager.FUNCTION_NONE, true); setEnabledFunctions(UsbManager.FUNCTION_NONE, true, operationId);
} }
break; break;
case MSG_SYSTEM_READY: case MSG_SYSTEM_READY:
operationId = sUsbOperationCount.incrementAndGet();
mNotificationManager = (NotificationManager) mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE); mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1092,17 +1163,19 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
NotificationManager.IMPORTANCE_HIGH)); NotificationManager.IMPORTANCE_HIGH));
} }
mSystemReady = true; mSystemReady = true;
finishBoot(); finishBoot(operationId);
break; break;
case MSG_LOCALE_CHANGED: case MSG_LOCALE_CHANGED:
updateAdbNotification(true); updateAdbNotification(true);
updateUsbNotification(true); updateUsbNotification(true);
break; break;
case MSG_BOOT_COMPLETED: case MSG_BOOT_COMPLETED:
operationId = sUsbOperationCount.incrementAndGet();
mBootCompleted = true; mBootCompleted = true;
finishBoot(); finishBoot(operationId);
break; break;
case MSG_USER_SWITCHED: { case MSG_USER_SWITCHED: {
operationId = sUsbOperationCount.incrementAndGet();
if (mCurrentUser != msg.arg1) { if (mCurrentUser != msg.arg1) {
if (DEBUG) { if (DEBUG) {
Slog.v(TAG, "Current user switched to " + msg.arg1); 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, mSettings.getString(String.format(Locale.ENGLISH,
UNLOCKED_CONFIG_PREF, mCurrentUser), "")); UNLOCKED_CONFIG_PREF, mCurrentUser), ""));
} }
setEnabledFunctions(UsbManager.FUNCTION_NONE, false); setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
} }
break; break;
} }
case MSG_ACCESSORY_MODE_ENTER_TIMEOUT: { case MSG_ACCESSORY_MODE_ENTER_TIMEOUT: {
operationId = sUsbOperationCount.incrementAndGet();
if (DEBUG) { 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) { if (!mConnected || (mCurrentFunctions & UsbManager.FUNCTION_ACCESSORY) == 0) {
notifyAccessoryModeExit(); notifyAccessoryModeExit(operationId);
} }
break; 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 (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) {
if (mPendingBootBroadcast) { if (mPendingBootBroadcast) {
updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions)); updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
@@ -1155,9 +1232,9 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
} }
if (!mScreenLocked if (!mScreenLocked
&& mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
setScreenUnlockedFunctions(); setScreenUnlockedFunctions(operationId);
} else { } else {
setEnabledFunctions(UsbManager.FUNCTION_NONE, false); setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
} }
if (mCurrentAccessory != null) { if (mCurrentAccessory != null) {
mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory);
@@ -1491,7 +1568,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
/** /**
* Evaluates USB function policies and applies the change accordingly. * 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) { public void setAccessoryUEventTime(long accessoryConnectionStartTime) {
mAccessoryConnectionStartTime = accessoryConnectionStartTime; mAccessoryConnectionStartTime = accessoryConnectionStartTime;
@@ -1506,6 +1584,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
mSendStringCount = 0; mSendStringCount = 0;
mStartAccessory = false; 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 { private static final class UsbHandlerLegacy extends UsbHandler {
@@ -1524,6 +1607,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
private String mCurrentFunctionsStr; private String mCurrentFunctionsStr;
private boolean mUsbDataUnlocked; private boolean mUsbDataUnlocked;
/**
* Keeps track of the latest setCurrentUsbFunctions request number.
*/
private int mCurrentRequest = 0;
UsbHandlerLegacy(Looper looper, Context context, UsbDeviceManager deviceManager, UsbHandlerLegacy(Looper looper, Context context, UsbDeviceManager deviceManager,
UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) { UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) {
super(looper, context, deviceManager, alsaManager, 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) { private void readOemUsbOverrideConfig(Context context) {
String[] configList = context.getResources().getStringArray( String[] configList = context.getResources().getStringArray(
com.android.internal.R.array.config_oemUsbModeOverride); com.android.internal.R.array.config_oemUsbModeOverride);
@@ -1659,11 +1751,14 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
} }
@Override @Override
protected void setEnabledFunctions(long usbFunctions, boolean forceRestart) { protected void setEnabledFunctions(long usbFunctions,
boolean forceRestart, int operationId) {
boolean usbDataUnlocked = isUsbDataTransferActive(usbFunctions); boolean usbDataUnlocked = isUsbDataTransferActive(usbFunctions);
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions + ", " Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions +
+ "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked); " ,forceRestart=" + forceRestart +
" ,usbDataUnlocked=" + usbDataUnlocked +
" ,operationId=" + operationId);
} }
if (usbDataUnlocked != mUsbDataUnlocked) { if (usbDataUnlocked != mUsbDataUnlocked) {
@@ -1759,7 +1854,6 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
|| !mCurrentFunctionsStr.equals(functions) || !mCurrentFunctionsStr.equals(functions)
|| !mCurrentFunctionsApplied || !mCurrentFunctionsApplied
|| forceRestart) { || forceRestart) {
Slog.i(TAG, "Setting USB config to " + functions);
mCurrentFunctionsStr = functions; mCurrentFunctionsStr = functions;
mCurrentOemFunctions = oemFunctions; mCurrentOemFunctions = oemFunctions;
mCurrentFunctionsApplied = false; mCurrentFunctionsApplied = false;
@@ -1855,15 +1949,18 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false; if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
return true; 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 { private final class UsbHandlerHal extends UsbHandler {
/**
* Proxy object for the usb gadget hal daemon.
*/
@GuardedBy("mGadgetProxyLock")
private IUsbGadget mGadgetProxy;
private final Object mGadgetProxyLock = new Object(); private final Object mGadgetProxyLock = new Object();
@@ -1910,33 +2007,20 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager, UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager,
UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) { UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) {
super(looper, context, deviceManager, alsaManager, permissionManager); super(looper, context, deviceManager, alsaManager, permissionManager);
int operationId = sUsbOperationCount.incrementAndGet();
try { 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) { synchronized (mGadgetProxyLock) {
mGadgetProxy = IUsbGadget.getService(true);
mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
USB_GADGET_HAL_DEATH_COOKIE);
mCurrentFunctions = UsbManager.FUNCTION_NONE; mCurrentFunctions = UsbManager.FUNCTION_NONE;
mCurrentUsbFunctionsRequested = true; mCurrentUsbFunctionsRequested = true;
mUsbSpeed = UsbSpeed.UNKNOWN; mUsbSpeed = UsbSpeed.UNKNOWN;
mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0; mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0;
mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback()); updateUsbGadgetHalVersion();
} }
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
updateState(state); updateState(state);
updateUsbGadgetHalVersion();
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
Slog.e(TAG, "Usb gadget hal not found", 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) { } catch (Exception e) {
Slog.e(TAG, "Error initializing UsbHandler", 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) { if (cookie == USB_GADGET_HAL_DEATH_COOKIE) {
Slog.e(TAG, "Usb Gadget hal service died cookie: " + cookie); Slog.e(TAG, "Usb Gadget hal service died cookie: " + cookie);
synchronized (mGadgetProxyLock) { synchronized (mGadgetProxyLock) {
mGadgetProxy = null; mUsbGadgetHal = null;
} }
} }
} }
@@ -1972,18 +2056,22 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
switch (msg.what) { switch (msg.what) {
case MSG_SET_CHARGING_FUNCTIONS: case MSG_SET_CHARGING_FUNCTIONS:
setEnabledFunctions(UsbManager.FUNCTION_NONE, false); int operationId = sUsbOperationCount.incrementAndGet();
setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
break; break;
case MSG_SET_FUNCTIONS_TIMEOUT: 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) { if (msg.arg1 != 1) {
// Set this since default function may be selected from Developer options // Set this since default function may be selected from Developer options
setEnabledFunctions(mScreenUnlockedFunctions, false); setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
} }
break; break;
case MSG_GET_CURRENT_USB_FUNCTIONS: case MSG_GET_CURRENT_USB_FUNCTIONS:
Slog.i(TAG, "processing MSG_GET_CURRENT_USB_FUNCTIONS"); Slog.i(TAG, "processing MSG_GET_CURRENT_USB_FUNCTIONS");
mCurrentUsbFunctionsReceived = true; mCurrentUsbFunctionsReceived = true;
operationId = msg.arg2;
if (mCurrentUsbFunctionsRequested) { if (mCurrentUsbFunctionsRequested) {
Slog.i(TAG, "updating mCurrentFunctions"); Slog.i(TAG, "updating mCurrentFunctions");
@@ -1993,91 +2081,71 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
"mCurrentFunctions:" + mCurrentFunctions + "applied:" + msg.arg1); "mCurrentFunctions:" + mCurrentFunctions + "applied:" + msg.arg1);
mCurrentFunctionsApplied = msg.arg1 == 1; mCurrentFunctionsApplied = msg.arg1 == 1;
} }
finishBoot(); finishBoot(operationId);
break; break;
case MSG_FUNCTION_SWITCH_TIMEOUT: case MSG_FUNCTION_SWITCH_TIMEOUT:
/** /**
* Dont force to default when the configuration is already set to default. * Dont force to default when the configuration is already set to default.
*/ */
operationId = sUsbOperationCount.incrementAndGet();
if (msg.arg1 != 1) { if (msg.arg1 != 1) {
// Set this since default function may be selected from Developer options // Set this since default function may be selected from Developer options
setEnabledFunctions(mScreenUnlockedFunctions, false); setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
} }
break; break;
case MSG_GADGET_HAL_REGISTERED: case MSG_GADGET_HAL_REGISTERED:
boolean preexisting = msg.arg1 == 1; boolean preexisting = msg.arg1 == 1;
operationId = sUsbOperationCount.incrementAndGet();
synchronized (mGadgetProxyLock) { synchronized (mGadgetProxyLock) {
try { try {
mGadgetProxy = IUsbGadget.getService(); mUsbGadgetHal = UsbGadgetHalInstance.getInstance(mUsbDeviceManager,
mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(), null);
USB_GADGET_HAL_DEATH_COOKIE);
if (!mCurrentFunctionsApplied && !preexisting) { if (!mCurrentFunctionsApplied && !preexisting) {
setEnabledFunctions(mCurrentFunctions, false); setEnabledFunctions(mCurrentFunctions, false, operationId);
} }
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
Slog.e(TAG, "Usb gadget hal not found", e); Slog.e(TAG, "Usb gadget hal not found", e);
} catch (RemoteException e) {
Slog.e(TAG, "Usb Gadget hal not responding", e);
} }
} }
break; break;
case MSG_RESET_USB_GADGET: case MSG_RESET_USB_GADGET:
synchronized (mGadgetProxyLock) { synchronized (mGadgetProxyLock) {
if (mGadgetProxy == null) { if (mUsbGadgetHal == null) {
Slog.e(TAG, "reset Usb Gadget mGadgetProxy is null"); Slog.e(TAG, "reset Usb Gadget mUsbGadgetHal is null");
break; break;
} }
try { try {
android.hardware.usb.gadget.V1_1.IUsbGadget gadgetProxy = mUsbGadgetHal.reset();
android.hardware.usb.gadget.V1_1.IUsbGadget } catch (Exception e) {
.castFrom(mGadgetProxy);
gadgetProxy.reset();
} catch (RemoteException e) {
Slog.e(TAG, "reset Usb Gadget failed", e); Slog.e(TAG, "reset Usb Gadget failed", e);
} }
} }
break; break;
case MSG_UPDATE_USB_SPEED: case MSG_UPDATE_USB_SPEED:
synchronized (mGadgetProxyLock) { operationId = sUsbOperationCount.incrementAndGet();
if (mGadgetProxy == null) { if (mUsbGadgetHal == null) {
Slog.e(TAG, "mGadgetProxy is null"); Slog.e(TAG, "mGadgetHal is null, operationId:" + operationId);
break; break;
} }
try { try {
android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy = mUsbGadgetHal.getUsbSpeed(operationId);
android.hardware.usb.gadget.V1_2.IUsbGadget } catch (Exception e) {
.castFrom(mGadgetProxy); Slog.e(TAG, "get UsbSpeed failed", e);
if (gadgetProxy != null) {
gadgetProxy.getUsbSpeed(new UsbGadgetCallback());
}
} catch (RemoteException e) {
Slog.e(TAG, "get UsbSpeed failed", e);
}
} }
break; break;
case MSG_UPDATE_HAL_VERSION: case MSG_UPDATE_HAL_VERSION:
synchronized (mGadgetProxyLock) { if (mUsbGadgetHal == null) {
if (mGadgetProxy == null) { Slog.e(TAG, "mUsbGadgetHal is null");
Slog.e(TAG, "mGadgetProxy is null"); break;
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; break;
default: default:
@@ -2085,56 +2153,31 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
} }
} }
private class UsbGadgetCallback extends IUsbGadgetCallback.Stub { @Override
int mRequest; public void setCurrentUsbFunctionsCb(long functions,
long mFunctions; int status, int mRequest, long mFunctions, boolean mChargingFunctions) {
boolean mChargingFunctions;
UsbGadgetCallback() { if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT)
|| (mFunctions != functions)) {
return;
} }
UsbGadgetCallback(int request, long functions, removeMessages(MSG_SET_FUNCTIONS_TIMEOUT);
boolean chargingFunctions) { Slog.i(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status);
mRequest = request; if (status == Status.SUCCESS) {
mFunctions = functions; mCurrentFunctionsApplied = true;
mChargingFunctions = chargingFunctions; } else if (!mChargingFunctions) {
} Slog.e(TAG, "Setting default fuctions");
sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS);
@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;
} }
} }
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); if (true) Slog.d(TAG, "setUsbConfig(" + config + ") request:" + ++mCurrentRequest);
/** /**
* Cancel any ongoing requests, if present. * Cancel any ongoing requests, if present.
@@ -2144,8 +2187,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
removeMessages(MSG_SET_CHARGING_FUNCTIONS); removeMessages(MSG_SET_CHARGING_FUNCTIONS);
synchronized (mGadgetProxyLock) { synchronized (mGadgetProxyLock) {
if (mGadgetProxy == null) { if (mUsbGadgetHal == null) {
Slog.e(TAG, "setUsbConfig mGadgetProxy is null"); Slog.e(TAG, "setUsbConfig mUsbGadgetHal is null");
return; return;
} }
try { try {
@@ -2162,10 +2205,9 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
LocalServices.getService(AdbManagerInternal.class) LocalServices.getService(AdbManagerInternal.class)
.stopAdbdForTransport(AdbTransportType.USB); .stopAdbdForTransport(AdbTransportType.USB);
} }
UsbGadgetCallback usbGadgetCallback = new UsbGadgetCallback(mCurrentRequest, mUsbGadgetHal.setCurrentUsbFunctions(mCurrentRequest,
config, chargingFunctions); config, chargingFunctions,
mGadgetProxy.setCurrentUsbFunctions(config, usbGadgetCallback, SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS, operationId);
SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS);
sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions, sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions,
SET_FUNCTIONS_TIMEOUT_MS); SET_FUNCTIONS_TIMEOUT_MS);
if (mConnected) { if (mConnected) {
@@ -2174,17 +2216,19 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS); SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS);
} }
if (DEBUG) Slog.d(TAG, "timeout message queued"); if (DEBUG) Slog.d(TAG, "timeout message queued");
} catch (RemoteException e) { } catch (Exception e) {//RemoteException e) {
Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e); Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e);
} }
} }
} }
@Override @Override
protected void setEnabledFunctions(long functions, boolean forceRestart) { protected void setEnabledFunctions(long functions, boolean forceRestart, int operationId) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", " Slog.d(TAG, "setEnabledFunctionsi " +
+ "forceRestart=" + forceRestart); "functions=" + functions +
", forceRestart=" + forceRestart +
", operationId=" + operationId);
} }
if (mCurrentGadgetHalVersion < UsbManager.GADGET_HAL_V1_2) { if (mCurrentGadgetHalVersion < UsbManager.GADGET_HAL_V1_2) {
if ((functions & UsbManager.FUNCTION_NCM) != 0) { if ((functions & UsbManager.FUNCTION_NCM) != 0) {
@@ -2205,7 +2249,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
functions = getAppliedFunctions(functions); functions = getAppliedFunctions(functions);
// Set the new USB configuration. // Set the new USB configuration.
setUsbConfig(functions, chargingFunctions); setUsbConfig(functions, chargingFunctions, operationId);
if (mBootCompleted && isUsbDataTransferActive(functions)) { if (mBootCompleted && isUsbDataTransferActive(functions)) {
// Start up dependent services. // 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 */ /* returns the currently attached USB accessory */
@@ -2254,6 +2303,21 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
return mHandler.getGadgetHalVersion(); 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. * 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. * @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) { if (DEBUG) {
Slog.d(TAG, "setCurrentFunctions(" + UsbManager.usbFunctionsToString(functions) + ")"); Slog.d(TAG, "setCurrentFunctions(" + UsbManager.usbFunctionsToString(functions) + ")");
} }
@@ -2296,7 +2360,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
} else if (functions == UsbManager.FUNCTION_ACCESSORY) { } else if (functions == UsbManager.FUNCTION_ACCESSORY) {
MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_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) { 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 @Override
public void setCurrentFunctions(long functions) { public void setCurrentFunctions(long functions, int operationId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
Preconditions.checkArgument(UsbManager.areSettableFunctions(functions)); Preconditions.checkArgument(UsbManager.areSettableFunctions(functions));
Preconditions.checkState(mDeviceManager != null); Preconditions.checkState(mDeviceManager != null);
mDeviceManager.setCurrentFunctions(functions); mDeviceManager.setCurrentFunctions(functions, operationId);
} }
@Override @Override
public void setCurrentFunction(String functions, boolean usbDataUnlocked) { public void setCurrentFunction(String functions, boolean usbDataUnlocked, int operationId) {
setCurrentFunctions(UsbManager.usbFunctionsFromString(functions)); setCurrentFunctions(UsbManager.usbFunctionsFromString(functions), operationId);
} }
@Override @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.content.Context;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Unit tests lib for {@link android.hardware.usb.UsbManager}. * Unit tests lib for {@link android.hardware.usb.UsbManager}.
*/ */
@@ -42,6 +45,11 @@ public class UsbManagerTestLib {
private UsbManager mUsbManagerMock; private UsbManager mUsbManagerMock;
@Mock private android.hardware.usb.IUsbManager mMockUsbService; @Mock private android.hardware.usb.IUsbManager mMockUsbService;
/**
* Counter for tracking UsbOperation operations.
*/
private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
public UsbManagerTestLib(Context context) { public UsbManagerTestLib(Context context) {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mContext = context; mContext = context;
@@ -82,10 +90,11 @@ public class UsbManagerTestLib {
} }
private void testSetCurrentFunctionsMock_Matched(long functions) { private void testSetCurrentFunctionsMock_Matched(long functions) {
int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
try { try {
setCurrentFunctions(functions); setCurrentFunctions(functions);
verify(mMockUsbService).setCurrentFunctions(eq(functions)); verify(mMockUsbService).setCurrentFunctions(eq(functions), operationId);
} catch (RemoteException remEx) { } catch (RemoteException remEx) {
Log.w(TAG, "RemoteException"); Log.w(TAG, "RemoteException");
} }
@@ -106,9 +115,10 @@ public class UsbManagerTestLib {
} }
public void testSetCurrentFunctionsEx(long functions) throws Exception { public void testSetCurrentFunctionsEx(long functions) throws Exception {
int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
setCurrentFunctions(functions); setCurrentFunctions(functions);
verify(mMockUsbService).setCurrentFunctions(eq(functions)); verify(mMockUsbService).setCurrentFunctions(eq(functions), operationId);
} }
public void testGetCurrentFunctions_shouldMatched() { public void testGetCurrentFunctions_shouldMatched() {

View File

@@ -98,7 +98,7 @@ public class UsbHandlerTest {
} }
@Override @Override
protected void setEnabledFunctions(long functions, boolean force) { protected void setEnabledFunctions(long functions, boolean force, int operationId) {
mCurrentFunctions = functions; mCurrentFunctions = functions;
} }
@@ -134,6 +134,20 @@ public class UsbHandlerTest {
protected void sendStickyBroadcast(Intent intent) { protected void sendStickyBroadcast(Intent intent) {
mBroadcastedIntent = 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 @Before