/* * Copyright (C) 2010 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 android.hardware.usb; import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.hardware.usb.gadget.GadgetFunction; import android.hardware.usb.gadget.UsbSpeed; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.SystemProperties; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.StringJoiner; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; /** * This class allows you to access the state of USB and communicate with USB devices. * Currently only host mode is supported in the public API. * *
For more information about communicating with USB hardware, read the * USB developer guide.
*For more information about communicating with USB accessory handshake, refer to * AOA developer guide.
* * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @SystemApi @RequiresPermission(Manifest.permission.MANAGE_USB) public static final String ACTION_USB_ACCESSORY_HANDSHAKE = "android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE"; /** * Boolean extra indicating whether USB is connected or disconnected. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * * @hide */ @SystemApi public static final String USB_CONNECTED = "connected"; /** * Boolean extra indicating whether USB is connected or disconnected as host. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * * @hide */ public static final String USB_HOST_CONNECTED = "host_connected"; /** * Boolean extra indicating whether USB is configured. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * * @hide */ @SystemApi public static final String USB_CONFIGURED = "configured"; /** * Boolean extra indicating whether confidential user data, such as photos, should be * made available on the USB connection. This variable will only be set when the user * has explicitly asked for this data to be unlocked. * Used in extras for the {@link #ACTION_USB_STATE} broadcast. * * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String USB_DATA_UNLOCKED = "unlocked"; /** * 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 */ @UnsupportedAppUsage public static final String USB_FUNCTION_NONE = "none"; /** * Name of the adb USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ public static final String USB_FUNCTION_ADB = "adb"; /** * Name of the RNDIS ethernet USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ @SystemApi public static final String USB_FUNCTION_RNDIS = "rndis"; /** * Name of the MTP USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ public static final String USB_FUNCTION_MTP = "mtp"; /** * Name of the PTP USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ public static final String USB_FUNCTION_PTP = "ptp"; /** * Name of the audio source USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source"; /** * Name of the MIDI USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ public static final String USB_FUNCTION_MIDI = "midi"; /** * Name of the Accessory USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ public static final String USB_FUNCTION_ACCESSORY = "accessory"; /** * Name of the NCM USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ @SystemApi public static final String USB_FUNCTION_NCM = "ncm"; /** * Name of the UVC USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * @hide */ public static final String USB_FUNCTION_UVC = "uvc"; /** * Name of Gadget Hal Not Present; * * @hide */ public static final String GADGET_HAL_UNKNOWN = "unknown"; /** * Name of the USB Gadget Hal Version v1.0; * * @hide */ public static final String GADGET_HAL_VERSION_1_0 = "V1_0"; /** * Name of the USB Gadget Hal Version v1.1; * * @hide */ public static final String GADGET_HAL_VERSION_1_1 = "V1_1"; /** * Name of the USB Gadget Hal Version v1.2; * * @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. * * @hide */ public static final String EXTRA_PORT = "port"; /** * Name of extra for {@link #ACTION_USB_PORT_CHANGED} * containing the {@link UsbPortStatus} object for the port, or null if the port * was removed. * * @hide */ public static final String EXTRA_PORT_STATUS = "portStatus"; /** * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} and * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts * containing the {@link UsbDevice} object for the device. */ public static final String EXTRA_DEVICE = "device"; /** * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} and * {@link #ACTION_USB_ACCESSORY_DETACHED} broadcasts * containing the {@link UsbAccessory} object for the accessory. */ public static final String EXTRA_ACCESSORY = "accessory"; /** * A long extra indicating ms from boot to get get_protocol UEvent * This is obtained with SystemClock.elapsedRealtime() * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * * @hide */ @SystemApi public static final String EXTRA_ACCESSORY_UEVENT_TIME = "android.hardware.usb.extra.ACCESSORY_UEVENT_TIME"; /** * An integer extra indicating numbers of send string during handshake * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts * *For more information about control request with identifying string information * between communicating with USB accessory handshake, refer to * AOA developer guide.
* * @hide */ @SystemApi public static final String EXTRA_ACCESSORY_STRING_COUNT = "android.hardware.usb.extra.ACCESSORY_STRING_COUNT"; /** * Boolean extra indicating whether got start accessory or not * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * * @hide */ @SystemApi public static final String EXTRA_ACCESSORY_START = "android.hardware.usb.extra.ACCESSORY_START"; /** * A long extra indicating the timestamp just before * sending {@link #ACTION_USB_ACCESSORY_HANDSHAKE}. * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts. * * @hide */ @SystemApi public static final String EXTRA_ACCESSORY_HANDSHAKE_END = "android.hardware.usb.extra.ACCESSORY_HANDSHAKE_END"; /** * Name of extra added to the {@link android.app.PendingIntent} * passed into {@link #requestPermission(UsbDevice, PendingIntent)} * or {@link #requestPermission(UsbAccessory, PendingIntent)} * containing a boolean value indicating whether the user granted permission or not. */ public static final String EXTRA_PERMISSION_GRANTED = "permission"; /** * Name of extra added to start systemui.usb.UsbPermissionActivity * containing package name of the app which requests USB permission. * * @hide */ public static final String EXTRA_PACKAGE = "android.hardware.usb.extra.PACKAGE"; /** * Name of extra added to start systemui.usb.UsbPermissionActivity * containing the whether the app which requests USB permission can be set as default handler * for USB device attach event or USB accessory attach event or not. * * @hide */ public static final String EXTRA_CAN_BE_DEFAULT = "android.hardware.usb.extra.CAN_BE_DEFAULT"; /** * The Value for USB gadget hal is not presented. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int GADGET_HAL_NOT_SUPPORTED = -1; /** * Value for Gadget Hal Version v1.0. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int GADGET_HAL_V1_0 = 10; /** * Value for Gadget Hal Version v1.1. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int GADGET_HAL_V1_1 = 11; /** * Value for Gadget Hal Version v1.2. * * @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 */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_UNKNOWN = -1; /** * Value for USB Transfer Rate of Low Speed in Mbps (real value is 1.5Mbps). * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_LOW_SPEED = 2; /** * Value for USB Transfer Rate of Full Speed in Mbps. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_FULL_SPEED = 12; /** * Value for USB Transfer Rate of High Speed in Mbps. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_HIGH_SPEED = 480; /** * Value for USB Transfer Rate of Super Speed in Mbps. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_5G = 5 * 1024; /** * Value for USB Transfer Rate of 10G. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_10G = 10 * 1024; /** * Value for USB Transfer Rate of 20G. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_20G = 20 * 1024; /** * Value for USB Transfer Rate of 40G. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_DATA_TRANSFER_RATE_40G = 40 * 1024; /** * Returned when the client has to retry querying the version. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_RETRY = -2; /** * The Value for USB hal is not presented. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_NOT_SUPPORTED = -1; /** * Value for USB Hal Version v1.0. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V1_0 = 10; /** * Value for USB Hal Version v1.1. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V1_1 = 11; /** * Value for USB Hal Version v1.2. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V1_2 = 12; /** * Value for USB Hal Version v1.3. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V1_3 = 13; /** * Value for USB Hal Version v2.0. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int USB_HAL_V2_0 = 20; /** * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)} * Must be equal to {@link GadgetFunction#NONE} * @hide */ @SystemApi public static final long FUNCTION_NONE = 0; /** * Code for the mtp usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Must be equal to {@link GadgetFunction#MTP} * @hide */ @SystemApi public static final long FUNCTION_MTP = 1 << 2; /** * Code for the ptp usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Must be equal to {@link GadgetFunction#PTP} * @hide */ @SystemApi public static final long FUNCTION_PTP = 1 << 4; /** * Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Must be equal to {@link GadgetFunction#RNDIS} * @hide */ @SystemApi public static final long FUNCTION_RNDIS = 1 << 5; /** * Code for the midi usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Must be equal to {@link GadgetFunction#MIDI} * @hide */ @SystemApi public static final long FUNCTION_MIDI = 1 << 3; /** * Code for the accessory usb function. * Must be equal to {@link GadgetFunction#ACCESSORY} * @hide */ @SystemApi public static final long FUNCTION_ACCESSORY = 1 << 1; /** * Code for the audio source usb function. * Must be equal to {@link GadgetFunction#AUDIO_SOURCE} * @hide */ @SystemApi public static final long FUNCTION_AUDIO_SOURCE = 1 << 6; /** * Code for the adb usb function. * Must be equal to {@link GadgetFunction#ADB} * @hide */ @SystemApi public static final long FUNCTION_ADB = 1; /** * Code for the ncm source usb function. * Must be equal to {@link GadgetFunction#NCM} * @hide */ @SystemApi public static final long FUNCTION_NCM = 1 << 10; /** * Code for the uvc usb function. Passed as a mask into {@link #setCurrentFunctions(long)} * Only supported if {@link #isUvcSupportEnabled()} returns true. * Must be equal to {@link GadgetFunction#UVC} * @hide */ @SystemApi public static final long FUNCTION_UVC = 1 << 7; private static final long SETTABLE_FUNCTIONS = FUNCTION_MTP | FUNCTION_PTP | FUNCTION_RNDIS | FUNCTION_MIDI | FUNCTION_NCM | FUNCTION_UVC; private static final MapIf data is read from the {@link java.io.InputStream} created from this file descriptor all * data of a USB transfer should be read at once. If only a partial request is read the rest of * the transfer is dropped. * * @param accessory the USB accessory to open * @return file descriptor, or null if the accessory could not be opened. */ @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { try { return mService.openAccessory(accessory); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Gets the functionfs control file descriptor for the given function, with * the usb descriptors and strings already written. The file descriptor is used * by the function implementation to handle events and control requests. * * @param function to get control fd for. Currently {@link #FUNCTION_MTP} and * {@link #FUNCTION_PTP} are supported. * @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found. * * @hide */ public ParcelFileDescriptor getControlFd(long function) { try { return mService.getControlFd(function); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the caller has permission to access the device. * Permission might have been granted temporarily via * {@link #requestPermission(UsbDevice, PendingIntent)} or * by the user choosing the caller as the default application for the device. * Permission for USB devices of class {@link UsbConstants#USB_CLASS_VIDEO} for clients that * target SDK {@link android.os.Build.VERSION_CODES#P} and above can be granted only if they * have additionally the {@link android.Manifest.permission#CAMERA} permission. * * @param device to check permissions for * @return true if caller has permission */ @RequiresFeature(PackageManager.FEATURE_USB_HOST) public boolean hasPermission(UsbDevice device) { if (mService == null) { return false; } try { return mService.hasDevicePermission(device, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the caller has permission to access the device. It's similar to the * {@link #hasPermission(UsbDevice)} but allows to specify a different package/uid/pid. * *
Not for third-party apps.
* * @hide */ @RequiresPermission(Manifest.permission.MANAGE_USB) @RequiresFeature(PackageManager.FEATURE_USB_HOST) public boolean hasPermission(@NonNull UsbDevice device, @NonNull String packageName, int pid, int uid) { if (mService == null) { return false; } try { return mService.hasDevicePermissionWithIdentity(device, packageName, pid, uid); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the caller has permission to access the accessory. * Permission might have been granted temporarily via * {@link #requestPermission(UsbAccessory, PendingIntent)} or * by the user choosing the caller as the default application for the accessory. * * @param accessory to check permissions for * @return true if caller has permission */ @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public boolean hasPermission(UsbAccessory accessory) { if (mService == null) { return false; } try { return mService.hasAccessoryPermission(accessory); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns true if the caller has permission to access the accessory. It's similar to the * {@link #hasPermission(UsbAccessory)} but allows to specify a different uid/pid. * *Not for third-party apps.
* * @hide */ @RequiresPermission(Manifest.permission.MANAGE_USB) @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY) public boolean hasPermission(@NonNull UsbAccessory accessory, int pid, int uid) { if (mService == null) { return false; } try { return mService.hasAccessoryPermissionWithIdentity(accessory, pid, uid); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Requests temporary permission for the given package to access the device. * This may result in a system dialog being displayed to the user * if permission had not already been granted. * Success or failure is returned via the {@link android.app.PendingIntent} pi. * If successful, this grants the caller permission to access the device only * until the device is disconnected. * * The following extras will be added to pi: ** USB functions represent interfaces which are published to the host to access * services offered by the device. *
* * @deprecated use getCurrentFunctions() instead. * @param function name of the USB function * @return true if the USB function is enabled * * @hide */ @Deprecated @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isFunctionEnabled(String function) { try { return mService.isFunctionEnabled(function); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Sets the current USB functions when in device mode. ** USB functions represent interfaces which are published to the host to access * services offered by the device. *
* This method is intended to select among primary USB functions. The system may * automatically activate additional functions such as {@link #USB_FUNCTION_ADB} * or {@link #USB_FUNCTION_ACCESSORY} based on other settings and states. *
* An argument of 0 indicates that the device is charging, and can pick any * appropriate function for that purpose. *
* Note: This function is asynchronous and may fail silently without applying * the requested changes. *
* * @param functions the USB function(s) to set, as a bitwise mask. * Must satisfy {@link UsbManager#areSettableFunctions} * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_USB) public void setCurrentFunctions(@UsbFunctionMode long functions) { int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid(); try { mService.setCurrentFunctions(functions, operationId); } catch (RemoteException e) { Log.e(TAG, "setCurrentFunctions: failed to call setCurrentFunctions. functions:" + functions + ", opId:" + operationId, e); throw e.rethrowFromSystemServer(); } } /** * Sets the current USB functions when in device mode. * * @deprecated use setCurrentFunctions(long) instead. * @param functions the USB function(s) to set. * @param usbDataUnlocked unused * @hide */ @Deprecated @UnsupportedAppUsage public void setCurrentFunction(String functions, boolean usbDataUnlocked) { int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid(); try { mService.setCurrentFunction(functions, usbDataUnlocked, operationId); } catch (RemoteException e) { Log.e(TAG, "setCurrentFunction: failed to call setCurrentFunction. functions:" + functions + ", opId:" + operationId, e); throw e.rethrowFromSystemServer(); } } /** * Returns the current USB functions in device mode. ** This function returns the state of primary USB functions and can return a * mask containing any usb function(s) except for ADB. *
* * @return The currently enabled functions, in a bitwise mask. * A zero mask indicates that the current function is the charging function. * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_USB) public long getCurrentFunctions() { try { return mService.getCurrentFunctions(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Sets the screen unlocked functions, which are persisted and set as the current functions * whenever the screen is unlocked. ** A zero mask has the effect of switching off this feature, so functions * no longer change on screen unlock. *
* Note: When the screen is on, this method will apply given functions as current functions, * which is asynchronous and may fail silently without applying the requested changes. *
* * @param functions functions to set, in a bitwise mask. * Must satisfy {@link UsbManager#areSettableFunctions} * * @hide */ public void setScreenUnlockedFunctions(long functions) { try { mService.setScreenUnlockedFunctions(functions); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Gets the current screen unlocked functions. * * @return The currently set screen enabled functions. * A zero mask indicates that the screen unlocked functions feature is not enabled. * * @hide */ public long getScreenUnlockedFunctions() { try { return mService.getScreenUnlockedFunctions(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Get the Current USB Bandwidth. ** This function returns the current USB bandwidth through USB Gadget HAL. * It should be used when Android device is in USB peripheral mode and * connects to a USB host. If USB state is not configued, API will return * {@value #USB_DATA_TRANSFER_RATE_UNKNOWN}. In addition, the unit of the * return value is Mbps. *
* * @return The value of currently USB Bandwidth. * * @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); } /** * Get the Current Gadget Hal Version. ** This function returns the current Gadget Hal Version. *
* * @return a integer {@code GADGET_HAL_*} represent hal version. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(Manifest.permission.MANAGE_USB) public @UsbGadgetHalVersion int getGadgetHalVersion() { try { return mService.getGadgetHalVersion(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Get the Current USB Hal Version. ** This function returns the current USB Hal Version. *
* * @return a integer {@code USB_HAL_*} represent hal version. * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @RequiresPermission(Manifest.permission.MANAGE_USB) public @UsbHalVersion int getUsbHalVersion() { try { return mService.getUsbHalVersion(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Resets the USB Gadget. ** Performs USB data stack reset through USB Gadget HAL. * It will force USB data connection reset. The connection will disconnect and reconnect. *
* * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_USB) public void resetUsbGadget() { try { mService.resetUsbGadget(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns whether UVC is advertised to be supported or not. SELinux * enforces that this function returns {@code false} when called from a * process that doesn't belong either to a system app, or the * DeviceAsWebcam Service. * * @return true if UVC is supported, false if UVC is not supported or if * called from a non-system app that isn't DeviceAsWebcam Service. * @hide */ @SystemApi public static boolean isUvcSupportEnabled() { return SystemProperties.getBoolean("ro.usb.uvc.enabled", false); } /** * Enable/Disable the USB data signaling. ** Enables/Disables USB data path of all USB ports. * It will force to stop or restore USB data signaling. *
* * @param enable enable or disable USB data signaling * @return true enable or disable USB data successfully * false if something wrong * * @hide */ @RequiresPermission(Manifest.permission.MANAGE_USB) public boolean enableUsbDataSignal(boolean enable) { return setUsbDataSignal(getPorts(), !enable, /* revertOnFailure= */ true); } private boolean setUsbDataSignal(List* This list is guaranteed to contain all dual-role USB Type C ports but it might * be missing other ports depending on whether the kernel USB drivers have been * updated to publish all of the device's ports through the new "dual_role_usb" * device class (which supports all types of ports despite its name). *
* * @return The list of USB ports * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_USB) public @NonNull List* limits or restores power transfer in and out of USB port. * * @param port USB port for which power transfer has to be limited or restored. * @param limit limit power transfer when true. * relax power transfer restrictions when false. * @param operationId operationId for the request. * @param callback callback object to be invoked when the operation is complete. * * @hide */ @RequiresPermission(Manifest.permission.MANAGE_USB) void enableLimitPowerTransfer(@NonNull UsbPort port, boolean limit, int operationId, IUsbOperationInternal callback) { Objects.requireNonNull(port, "enableLimitPowerTransfer:port must not be null. opId:" + operationId); try { mService.enableLimitPowerTransfer(port.getId(), limit, operationId, callback); } catch (RemoteException e) { Log.e(TAG, "enableLimitPowerTransfer failed. opId:" + operationId, e); try { callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL); } catch (RemoteException r) { Log.e(TAG, "enableLimitPowerTransfer failed to call onOperationComplete. opId:" + operationId, r); } throw e.rethrowFromSystemServer(); } } /** * Should only be called by {@link UsbPort#resetUsbPort}. *
* Disable and then re-enable USB data signaling. * * Reset USB first port.. * It will force to stop and restart USB data signaling. * Call UsbPort API if the device has more than one UsbPort. *
* * @param port reset the USB Port * @return true enable or disable USB data successfully * false if something wrong * * Should only be called by {@link UsbPort#resetUsbPort}. * * @hide */ @RequiresPermission(Manifest.permission.MANAGE_USB) void resetUsbPort(@NonNull UsbPort port, int operationId, IUsbOperationInternal callback) { Objects.requireNonNull(port, "resetUsbPort: port must not be null. opId:" + operationId); try { mService.resetUsbPort(port.getId(), operationId, callback); } catch (RemoteException e) { Log.e(TAG, "resetUsbPort: failed. ", e); try { callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL); } catch (RemoteException r) { Log.e(TAG, "resetUsbPort: failed to call onOperationComplete. opId:" + operationId, r); } throw e.rethrowFromSystemServer(); } } /** * Should only be called by {@link UsbPort#enableUsbData}. ** Enables or disables USB data on the specific port. * * @param port USB port for which USB data needs to be enabled or disabled. * @param enable Enable USB data when true. * Disable USB data when false. * @param operationId operationId for the request. * @param callback callback object to be invoked when the operation is complete. * @return True when the operation is asynchronous. The caller must therefore call * {@link UsbOperationInternal#waitForOperationComplete} for processing * the result. * False when the operation is synchronous. Caller can proceed reading the result * through {@link UsbOperationInternal#getStatus} * @hide */ @RequiresPermission(Manifest.permission.MANAGE_USB) boolean enableUsbData(@NonNull UsbPort port, boolean enable, int operationId, IUsbOperationInternal callback) { Objects.requireNonNull(port, "enableUsbData: port must not be null. opId:" + operationId); try { return mService.enableUsbData(port.getId(), enable, operationId, callback); } catch (RemoteException e) { Log.e(TAG, "enableUsbData: failed. opId:" + operationId, e); try { callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL); } catch (RemoteException r) { Log.e(TAG, "enableUsbData: failed to call onOperationComplete. opId:" + operationId, r); } throw e.rethrowFromSystemServer(); } } /** * Should only be called by {@link UsbPort#enableUsbDataWhileDocked}. *
* Enables or disables USB data when disabled due to docking event. * * @param port USB port for which USB data needs to be enabled. * @param operationId operationId for the request. * @param callback callback object to be invoked when the operation is complete. * @hide */ @RequiresPermission(Manifest.permission.MANAGE_USB) void enableUsbDataWhileDocked(@NonNull UsbPort port, int operationId, IUsbOperationInternal callback) { Objects.requireNonNull(port, "enableUsbDataWhileDocked: port must not be null. opId:" + operationId); try { mService.enableUsbDataWhileDocked(port.getId(), operationId, callback); } catch (RemoteException e) { Log.e(TAG, "enableUsbDataWhileDocked: failed. opId:" + operationId, e); try { callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL); } catch (RemoteException r) { Log.e(TAG, "enableUsbDataWhileDocked: failed to call onOperationComplete. opId:" + operationId, r); } throw e.rethrowFromSystemServer(); } } @GuardedBy("mDisplayPortListenersLock") @RequiresPermission(Manifest.permission.MANAGE_USB) private boolean registerDisplayPortAltModeEventsIfNeededLocked() { DisplayPortAltModeInfoDispatchingListener displayPortDispatchingListener = new DisplayPortAltModeInfoDispatchingListener(); try { if (mService.registerForDisplayPortEvents(displayPortDispatchingListener)) { mDisplayPortServiceListener = displayPortDispatchingListener; return true; } return false; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Registers the given listener to listen for DisplayPort Alt Mode changes. *
* If this method returns without Exceptions, the caller should ensure to call
* {@link #unregisterDisplayPortAltModeListener} when it no longer requires updates.
*
* @param executor Executor on which to run the listener.
* @param listener DisplayPortAltModeInfoListener invoked on DisplayPortAltModeInfo
* changes. See {@link #DisplayPortAltModeInfoListener} for listener
* details.
*
* @throws IllegalStateException if listener has already been registered previously but not
* unregistered or an unexpected system failure occurs.
*
* @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.MANAGE_USB)
public void registerDisplayPortAltModeInfoListener(
@NonNull @CallbackExecutor Executor executor,
@NonNull DisplayPortAltModeInfoListener listener) {
Objects.requireNonNull(executor, "registerDisplayPortAltModeInfoListener: "
+ "executor must not be null.");
Objects.requireNonNull(listener, "registerDisplayPortAltModeInfoListener: "
+ "listener must not be null.");
synchronized (mDisplayPortListenersLock) {
if (mDisplayPortListeners == null) {
mDisplayPortListeners = new ArrayMap
* Setting component allows to specify external USB host manager to handle use cases, where
* selection dialog for an activity that will handle USB device is undesirable.
* Only system components can call this function, as it requires the MANAGE_USB permission.
*
* @param usbDeviceConnectionHandler The component to handle usb connections,
* {@code null} to unset.
*
* @hide
*/
public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) {
try {
mService.setUsbDeviceConnectionHandler(usbDeviceConnectionHandler);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns whether the given functions are valid inputs to UsbManager.
* Currently the empty functions or any of MTP, PTP, RNDIS, MIDI, NCM, UVC are accepted.
*
* Only one function may be set at a time, except for RNDIS and NCM, which can be set together
* because from a user perspective they are the same function (tethering).
*
* @return Whether the mask is settable.
*
* @hide
*/
public static boolean areSettableFunctions(long functions) {
return functions == FUNCTION_NONE
|| ((~SETTABLE_FUNCTIONS & functions) == 0
&& ((Long.bitCount(functions) == 1)
|| (functions == (FUNCTION_RNDIS | FUNCTION_NCM))));
}
/**
* Converts the given function mask to string. Maintains ordering with respect to init scripts.
*
* @return String representation of given mask
*
* @hide
*/
public static String usbFunctionsToString(long functions) {
StringJoiner joiner = new StringJoiner(",");
if ((functions & FUNCTION_MTP) != 0) {
joiner.add(UsbManager.USB_FUNCTION_MTP);
}
if ((functions & FUNCTION_PTP) != 0) {
joiner.add(UsbManager.USB_FUNCTION_PTP);
}
if ((functions & FUNCTION_RNDIS) != 0) {
joiner.add(UsbManager.USB_FUNCTION_RNDIS);
}
if ((functions & FUNCTION_MIDI) != 0) {
joiner.add(UsbManager.USB_FUNCTION_MIDI);
}
if ((functions & FUNCTION_ACCESSORY) != 0) {
joiner.add(UsbManager.USB_FUNCTION_ACCESSORY);
}
if ((functions & FUNCTION_AUDIO_SOURCE) != 0) {
joiner.add(UsbManager.USB_FUNCTION_AUDIO_SOURCE);
}
if ((functions & FUNCTION_NCM) != 0) {
joiner.add(UsbManager.USB_FUNCTION_NCM);
}
if ((functions & FUNCTION_UVC) != 0) {
joiner.add(UsbManager.USB_FUNCTION_UVC);
}
if ((functions & FUNCTION_ADB) != 0) {
joiner.add(UsbManager.USB_FUNCTION_ADB);
}
return joiner.toString();
}
/**
* Parses a string of usb functions that are comma separated.
*
* @return A mask of all valid functions in the string
*
* @hide
*/
public static long usbFunctionsFromString(String functions) {
if (functions == null || functions.equals(USB_FUNCTION_NONE)) {
return FUNCTION_NONE;
}
long ret = 0;
for (String function : functions.split(",")) {
if (FUNCTION_NAME_TO_CODE.containsKey(function)) {
ret |= FUNCTION_NAME_TO_CODE.get(function);
} else if (function.length() > 0) {
throw new IllegalArgumentException("Invalid usb function " + functions);
}
}
return ret;
}
/**
* Converts the given integer of USB speed to corresponding bandwidth.
*
* @return a value of USB bandwidth
*
* @hide
*/
public static int usbSpeedToBandwidth(int speed) {
switch (speed) {
case UsbSpeed.USB4_GEN3_40Gb:
return USB_DATA_TRANSFER_RATE_40G;
case UsbSpeed.USB4_GEN3_20Gb:
return USB_DATA_TRANSFER_RATE_20G;
case UsbSpeed.USB4_GEN2_20Gb:
return USB_DATA_TRANSFER_RATE_20G;
case UsbSpeed.USB4_GEN2_10Gb:
return USB_DATA_TRANSFER_RATE_10G;
case UsbSpeed.SUPERSPEED_20Gb:
return USB_DATA_TRANSFER_RATE_20G;
case UsbSpeed.SUPERSPEED_10Gb:
return USB_DATA_TRANSFER_RATE_10G;
case UsbSpeed.SUPERSPEED:
return USB_DATA_TRANSFER_RATE_5G;
case UsbSpeed.HIGHSPEED:
return USB_DATA_TRANSFER_RATE_HIGH_SPEED;
case UsbSpeed.FULLSPEED:
return USB_DATA_TRANSFER_RATE_FULL_SPEED;
case UsbSpeed.LOWSPEED:
return USB_DATA_TRANSFER_RATE_LOW_SPEED;
default:
return USB_DATA_TRANSFER_RATE_UNKNOWN;
}
}
/**
* Converts the given usb gadgdet hal version to String
*
* @return String representation of Usb Gadget Hal Version
*
* @hide
*/
public static @NonNull String usbGadgetHalVersionToString(int version) {
String halVersion;
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;
} else if (version == GADGET_HAL_V1_0) {
halVersion = GADGET_HAL_VERSION_1_0;
} else {
halVersion = GADGET_HAL_UNKNOWN;
}
return halVersion;
}
}