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