• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 package android.hardware.usb;
19 
20 import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE;
21 
22 import android.Manifest;
23 import android.annotation.CallbackExecutor;
24 import android.annotation.FlaggedApi;
25 import android.annotation.IntDef;
26 import android.annotation.LongDef;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.annotation.RequiresFeature;
30 import android.annotation.RequiresPermission;
31 import android.annotation.SdkConstant;
32 import android.annotation.SdkConstant.SdkConstantType;
33 import android.annotation.SuppressLint;
34 import android.annotation.SystemApi;
35 import android.annotation.SystemService;
36 import android.annotation.TestApi;
37 import android.app.PendingIntent;
38 import android.compat.annotation.UnsupportedAppUsage;
39 import android.content.ComponentName;
40 import android.content.Context;
41 import android.content.pm.PackageManager;
42 import android.content.pm.PackageManager.NameNotFoundException;
43 import android.hardware.usb.flags.Flags;
44 import android.hardware.usb.gadget.GadgetFunction;
45 import android.hardware.usb.gadget.UsbSpeed;
46 import android.os.Binder;
47 import android.os.Build;
48 import android.os.Bundle;
49 import android.os.ParcelFileDescriptor;
50 import android.os.Process;
51 import android.os.RemoteException;
52 import android.os.SystemProperties;
53 import android.util.ArrayMap;
54 import android.util.Log;
55 import android.util.Slog;
56 
57 import com.android.internal.annotations.GuardedBy;
58 
59 import java.io.FileInputStream;
60 import java.io.FileOutputStream;
61 import java.io.IOException;
62 import java.io.InputStream;
63 import java.io.OutputStream;
64 import java.lang.annotation.Retention;
65 import java.lang.annotation.RetentionPolicy;
66 import java.util.ArrayList;
67 import java.util.Collections;
68 import java.util.HashMap;
69 import java.util.List;
70 import java.util.Map;
71 import java.util.Objects;
72 import java.util.StringJoiner;
73 import java.util.concurrent.Executor;
74 import java.util.concurrent.atomic.AtomicInteger;
75 
76 /**
77  * This class allows you to access the state of USB and communicate with USB devices.
78  * Currently only host mode is supported in the public API.
79  *
80  * <div class="special reference">
81  * <h3>Developer Guides</h3>
82  * <p>For more information about communicating with USB hardware, read the
83  * <a href="{@docRoot}guide/topics/connectivity/usb/index.html">USB developer guide</a>.</p>
84  * </div>
85  */
86 @SystemService(Context.USB_SERVICE)
87 public class UsbManager {
88     private static final String TAG = "UsbManager";
89 
90     /**
91      * Broadcast Action:  A sticky broadcast for USB state change events when in device mode.
92      *
93      * This is a sticky broadcast for clients that includes USB connected/disconnected state,
94      * <ul>
95      * <li> {@link #USB_CONNECTED} boolean indicating whether USB is connected or disconnected.
96      * <li> {@link #USB_HOST_CONNECTED} boolean indicating whether USB is connected or
97      *     disconnected as host.
98      * <li> {@link #USB_CONFIGURED} boolean indicating whether USB is configured.
99      * currently zero if not configured, one for configured.
100      * <li> {@link #USB_FUNCTION_ADB} boolean extra indicating whether the
101      * adb function is enabled
102      * <li> {@link #USB_FUNCTION_RNDIS} boolean extra indicating whether the
103      * RNDIS ethernet function is enabled
104      * <li> {@link #USB_FUNCTION_MTP} boolean extra indicating whether the
105      * MTP function is enabled
106      * <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
107      * PTP function is enabled
108      * <li> {@link #USB_FUNCTION_ACCESSORY} boolean extra indicating whether the
109      * accessory function is enabled
110      * <li> {@link #USB_FUNCTION_AUDIO_SOURCE} boolean extra indicating whether the
111      * audio source function is enabled
112      * <li> {@link #USB_FUNCTION_MIDI} boolean extra indicating whether the
113      * MIDI function is enabled
114      * <li> {@link #USB_FUNCTION_UVC} boolean extra indicating whether the
115      * UVC function is enabled
116      * </ul>
117      * If the sticky intent has not been found, that indicates USB is disconnected,
118      * USB is not configured, MTP function is enabled, and all the other functions are disabled.
119      *
120      * @hide
121      */
122     @SystemApi
123     public static final String ACTION_USB_STATE =
124             "android.hardware.usb.action.USB_STATE";
125 
126     /**
127      * Broadcast Action: A broadcast for USB port changes.
128      *
129      * This intent is sent when a USB port is added, removed, or changes state.
130      *
131      * @hide
132      */
133     @SystemApi
134     @RequiresPermission(Manifest.permission.MANAGE_USB)
135     public static final String ACTION_USB_PORT_CHANGED =
136             "android.hardware.usb.action.USB_PORT_CHANGED";
137 
138     /**
139      * Broadcast Action: A broadcast for USB compliance warning changes.
140      *
141      * This intent is sent when a port partner's
142      * (USB power source/cable/accessory) compliance warnings change state.
143      *
144      * @hide
145      */
146     @SystemApi
147     @RequiresPermission(Manifest.permission.MANAGE_USB)
148     public static final String ACTION_USB_PORT_COMPLIANCE_CHANGED =
149             "android.hardware.usb.action.USB_PORT_COMPLIANCE_CHANGED";
150 
151     /**
152      * Activity intent sent when user attaches a USB device.
153      *
154      * This intent is sent when a USB device is attached to the USB bus when in host mode.
155      * <ul>
156      * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
157      * for the attached device
158      * </ul>
159      */
160     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
161     public static final String ACTION_USB_DEVICE_ATTACHED =
162             "android.hardware.usb.action.USB_DEVICE_ATTACHED";
163 
164     /**
165      * Broadcast Action:  A broadcast for USB device detached event.
166      *
167      * This intent is sent when a USB device is detached from the USB bus when in host mode.
168      * <ul>
169      * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
170      * for the detached device
171      * </ul>
172      */
173     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
174     public static final String ACTION_USB_DEVICE_DETACHED =
175             "android.hardware.usb.action.USB_DEVICE_DETACHED";
176 
177     /**
178      * Activity intent sent when user attaches a USB accessory.
179      *
180      * <ul>
181      * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory}
182      * for the attached accessory
183      * </ul>
184      */
185     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
186     public static final String ACTION_USB_ACCESSORY_ATTACHED =
187             "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
188 
189     /**
190      * Broadcast Action:  A broadcast for USB accessory detached event.
191      *
192      * This intent is sent when a USB accessory is detached.
193      * <ul>
194      * <li> {@link #EXTRA_ACCESSORY} containing the {@link UsbAccessory}
195      * for the attached accessory that was detached
196      * </ul>
197      */
198     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
199     public static final String ACTION_USB_ACCESSORY_DETACHED =
200             "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
201 
202     /**
203      * Broadcast Action:  A broadcast for USB accessory handshaking information delivery
204      *
205      * This intent is sent when a USB accessory connect attempt
206      *
207      * <p>For more information about communicating with USB accessory handshake, refer to
208      * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p>
209      *
210      * @hide
211      */
212     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
213     @SystemApi
214     @RequiresPermission(Manifest.permission.MANAGE_USB)
215     public static final String ACTION_USB_ACCESSORY_HANDSHAKE =
216             "android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE";
217 
218     /**
219      * Boolean extra indicating whether USB is connected or disconnected.
220      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
221      *
222      * @hide
223      */
224     @SystemApi
225     public static final String USB_CONNECTED = "connected";
226 
227     /**
228      * Boolean extra indicating whether USB is connected or disconnected as host.
229      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
230      *
231      * @hide
232      */
233     public static final String USB_HOST_CONNECTED = "host_connected";
234 
235     /**
236      * Boolean extra indicating whether USB is configured.
237      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
238      *
239      * @hide
240      */
241     @SystemApi
242     public static final String USB_CONFIGURED = "configured";
243 
244     /**
245      * Boolean extra indicating whether confidential user data, such as photos, should be
246      * made available on the USB connection. This variable will only be set when the user
247      * has explicitly asked for this data to be unlocked.
248      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
249      *
250      * @hide
251      */
252     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
253     public static final String USB_DATA_UNLOCKED = "unlocked";
254 
255     /**
256      * A placeholder indicating that no USB function is being specified.
257      * Used for compatibility with old init scripts to indicate no functions vs. charging function.
258      *
259      * @hide
260      */
261     @UnsupportedAppUsage
262     public static final String USB_FUNCTION_NONE = "none";
263 
264     /**
265      * Name of the adb USB function.
266      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
267      *
268      * @hide
269      */
270     public static final String USB_FUNCTION_ADB = "adb";
271 
272     /**
273      * Name of the RNDIS ethernet USB function.
274      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
275      *
276      * @hide
277      */
278     @SystemApi
279     public static final String USB_FUNCTION_RNDIS = "rndis";
280 
281     /**
282      * Name of the MTP USB function.
283      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
284      *
285      * @hide
286      */
287     public static final String USB_FUNCTION_MTP = "mtp";
288 
289     /**
290      * Name of the PTP USB function.
291      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
292      *
293      * @hide
294      */
295     public static final String USB_FUNCTION_PTP = "ptp";
296 
297     /**
298      * Name of the audio source USB function.
299      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
300      *
301      * @hide
302      */
303     public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
304 
305     /**
306      * Name of the MIDI USB function.
307      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
308      *
309      * @hide
310      */
311     public static final String USB_FUNCTION_MIDI = "midi";
312 
313     /**
314      * Name of the Accessory USB function.
315      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
316      *
317      * @hide
318      */
319     public static final String USB_FUNCTION_ACCESSORY = "accessory";
320 
321     /**
322      * Name of the NCM USB function.
323      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
324      *
325      * @hide
326      */
327     @SystemApi
328     public static final String USB_FUNCTION_NCM = "ncm";
329 
330     /**
331      * Name of the UVC USB function.
332      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
333      *
334      * @hide
335      */
336     public static final String USB_FUNCTION_UVC = "uvc";
337 
338     /**
339      * Name of Gadget Hal Not Present;
340      *
341      * @hide
342      */
343     public static final String GADGET_HAL_UNKNOWN = "unknown";
344 
345     /**
346      * Name of the USB Gadget Hal Version v1.0;
347      *
348      * @hide
349      */
350     public static final String GADGET_HAL_VERSION_1_0 = "V1_0";
351 
352     /**
353      * Name of the USB Gadget Hal Version v1.1;
354      *
355      * @hide
356      */
357     public static final String GADGET_HAL_VERSION_1_1 = "V1_1";
358 
359     /**
360      * Name of the USB Gadget Hal Version v1.2;
361      *
362      * @hide
363      */
364     public static final String GADGET_HAL_VERSION_1_2 = "V1_2";
365 
366     /**
367      * Name of the USB Gadget Hal Version v2.0;
368      *
369      * @hide
370      */
371     public static final String GADGET_HAL_VERSION_2_0 = "V2_0";
372 
373     /**
374      * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
375      * containing the {@link UsbPort} object for the port.
376      *
377      * @hide
378      */
379     public static final String EXTRA_PORT = "port";
380 
381     /**
382      * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
383      * containing the {@link UsbPortStatus} object for the port, or null if the port
384      * was removed.
385      *
386      * @hide
387      */
388     public static final String EXTRA_PORT_STATUS = "portStatus";
389 
390     /**
391      * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} and
392      * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts
393      * containing the {@link UsbDevice} object for the device.
394      */
395     public static final String EXTRA_DEVICE = "device";
396 
397     /**
398      * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} and
399      * {@link #ACTION_USB_ACCESSORY_DETACHED} broadcasts
400      * containing the {@link UsbAccessory} object for the accessory.
401      */
402     public static final String EXTRA_ACCESSORY = "accessory";
403 
404     /**
405      * A long extra indicating ms from boot to get get_protocol UEvent
406      * This is obtained with SystemClock.elapsedRealtime()
407      * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
408      *
409      * @hide
410      */
411     @SystemApi
412     public static final String EXTRA_ACCESSORY_UEVENT_TIME =
413             "android.hardware.usb.extra.ACCESSORY_UEVENT_TIME";
414 
415     /**
416      * An integer extra indicating numbers of send string during handshake
417      * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts
418      *
419      * <p>For more information about control request with identifying string information
420      * between communicating with USB accessory handshake, refer to
421      * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p>
422      *
423      * @hide
424      */
425     @SystemApi
426     public static final String EXTRA_ACCESSORY_STRING_COUNT =
427             "android.hardware.usb.extra.ACCESSORY_STRING_COUNT";
428 
429     /**
430      * Boolean extra indicating whether got start accessory or not
431      * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
432      *
433      * @hide
434      */
435     @SystemApi
436     public static final String EXTRA_ACCESSORY_START =
437             "android.hardware.usb.extra.ACCESSORY_START";
438 
439     /**
440 
441      * A long extra indicating the timestamp just before
442      * sending {@link #ACTION_USB_ACCESSORY_HANDSHAKE}.
443      * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
444      *
445      * @hide
446      */
447     @SystemApi
448     public static final String EXTRA_ACCESSORY_HANDSHAKE_END =
449             "android.hardware.usb.extra.ACCESSORY_HANDSHAKE_END";
450 
451     /**
452      * Name of extra added to the {@link android.app.PendingIntent}
453      * passed into {@link #requestPermission(UsbDevice, PendingIntent)}
454      * or {@link #requestPermission(UsbAccessory, PendingIntent)}
455      * containing a boolean value indicating whether the user granted permission or not.
456      */
457     public static final String EXTRA_PERMISSION_GRANTED = "permission";
458 
459     /**
460      * Name of extra added to start systemui.usb.UsbPermissionActivity
461      * containing package name of the app which requests USB permission.
462      *
463      * @hide
464      */
465     public static final String EXTRA_PACKAGE = "android.hardware.usb.extra.PACKAGE";
466 
467     /**
468      * Name of extra added to start systemui.usb.UsbPermissionActivity
469      * containing the whether the app which requests USB permission can be set as default handler
470      * for USB device attach event or USB accessory attach event or not.
471      *
472      * @hide
473      */
474     public static final String EXTRA_CAN_BE_DEFAULT = "android.hardware.usb.extra.CAN_BE_DEFAULT";
475 
476     /**
477      * The Value for USB gadget hal is not presented.
478      *
479      * @hide
480      */
481     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
482     public static final int GADGET_HAL_NOT_SUPPORTED = -1;
483 
484     /**
485      * Value for Gadget Hal Version v1.0.
486      *
487      * @hide
488      */
489     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
490     public static final int GADGET_HAL_V1_0 = 10;
491 
492     /**
493      * Value for Gadget Hal Version v1.1.
494      *
495      * @hide
496      */
497     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
498     public static final int GADGET_HAL_V1_1 = 11;
499 
500     /**
501      * Value for Gadget Hal Version v1.2.
502      *
503      * @hide
504      */
505     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
506     public static final int GADGET_HAL_V1_2 = 12;
507 
508     /**
509      * Value for Gadget Hal Version v2.0.
510      *
511      * @hide
512      */
513     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
514     public static final int GADGET_HAL_V2_0 = 20;
515 
516     /**
517      * Value for USB_STATE is not configured.
518      *
519      * @hide
520      */
521     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
522     @SystemApi
523     public static final int USB_DATA_TRANSFER_RATE_UNKNOWN = -1;
524 
525     /**
526      * Value for USB Transfer Rate of Low Speed in Mbps (real value is 1.5Mbps).
527      *
528      * @hide
529      */
530     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
531     @SystemApi
532     public static final int USB_DATA_TRANSFER_RATE_LOW_SPEED = 2;
533 
534     /**
535      * Value for USB Transfer Rate of Full Speed in Mbps.
536      *
537      * @hide
538      */
539     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
540     @SystemApi
541     public static final int USB_DATA_TRANSFER_RATE_FULL_SPEED = 12;
542 
543     /**
544      * Value for USB Transfer Rate of High Speed in Mbps.
545      *
546      * @hide
547      */
548     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
549     @SystemApi
550     public static final int USB_DATA_TRANSFER_RATE_HIGH_SPEED = 480;
551 
552     /**
553      * Value for USB Transfer Rate of Super Speed in Mbps.
554      *
555      * @hide
556      */
557     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
558     @SystemApi
559     public static final int USB_DATA_TRANSFER_RATE_5G = 5 * 1024;
560 
561     /**
562      * Value for USB Transfer Rate of 10G.
563      *
564      * @hide
565      */
566     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
567     @SystemApi
568     public static final int USB_DATA_TRANSFER_RATE_10G = 10 * 1024;
569 
570     /**
571      * Value for USB Transfer Rate of 20G.
572      *
573      * @hide
574      */
575     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
576     @SystemApi
577     public static final int USB_DATA_TRANSFER_RATE_20G = 20 * 1024;
578 
579     /**
580      * Value for USB Transfer Rate of 40G.
581      *
582      * @hide
583      */
584     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
585     @SystemApi
586     public static final int USB_DATA_TRANSFER_RATE_40G = 40 * 1024;
587 
588     /**
589      * Returned when the client has to retry querying the version.
590      *
591      * @hide
592      */
593     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
594     public static final int USB_HAL_RETRY = -2;
595 
596     /**
597      * The Value for USB hal is not presented.
598      *
599      * @hide
600      */
601     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
602     public static final int USB_HAL_NOT_SUPPORTED = -1;
603 
604     /**
605      * Value for USB Hal Version v1.0.
606      *
607      * @hide
608      */
609     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
610     public static final int USB_HAL_V1_0 = 10;
611 
612     /**
613      * Value for USB Hal Version v1.1.
614      *
615      * @hide
616      */
617     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
618     public static final int USB_HAL_V1_1 = 11;
619 
620     /**
621      * Value for USB Hal Version v1.2.
622      *
623      * @hide
624      */
625     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
626     public static final int USB_HAL_V1_2 = 12;
627 
628     /**
629      * Value for USB Hal Version v1.3.
630      *
631      * @hide
632      */
633     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
634     public static final int USB_HAL_V1_3 = 13;
635 
636     /**
637      * Value for USB Hal Version v2.0.
638      *
639      * @hide
640      */
641     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
642     public static final int USB_HAL_V2_0 = 20;
643 
644     /**
645      * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)}
646      * Must be equal to {@link GadgetFunction#NONE}
647      * @hide
648      */
649     @SystemApi
650     public static final long FUNCTION_NONE = 0;
651 
652     /**
653      * Code for the mtp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
654      * Must be equal to {@link GadgetFunction#MTP}
655      * @hide
656      */
657     @SystemApi
658     public static final long FUNCTION_MTP = 1 << 2;
659 
660     /**
661      * Code for the ptp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
662      * Must be equal to {@link GadgetFunction#PTP}
663      * @hide
664      */
665     @SystemApi
666     public static final long FUNCTION_PTP = 1 << 4;
667 
668     /**
669      * Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
670      * Must be equal to {@link GadgetFunction#RNDIS}
671      * @hide
672      */
673     @SystemApi
674     public static final long FUNCTION_RNDIS = 1 << 5;
675 
676     /**
677      * Code for the midi usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
678      * Must be equal to {@link GadgetFunction#MIDI}
679      * @hide
680      */
681     @SystemApi
682     public static final long FUNCTION_MIDI = 1 << 3;
683 
684     /**
685      * Code for the accessory usb function.
686      * Must be equal to {@link GadgetFunction#ACCESSORY}
687      * @hide
688      */
689     @SystemApi
690     public static final long FUNCTION_ACCESSORY = 1 << 1;
691 
692     /**
693      * Code for the audio source usb function.
694      * Must be equal to {@link GadgetFunction#AUDIO_SOURCE}
695      * @hide
696      */
697     @SystemApi
698     public static final long FUNCTION_AUDIO_SOURCE = 1 << 6;
699 
700     /**
701      * Code for the adb usb function.
702      * Must be equal to {@link GadgetFunction#ADB}
703      * @hide
704      */
705     @SystemApi
706     public static final long FUNCTION_ADB = 1;
707 
708     /**
709      * Code for the ncm source usb function.
710      * Must be equal to {@link GadgetFunction#NCM}
711      * @hide
712      */
713     @SystemApi
714     public static final long FUNCTION_NCM = 1 << 10;
715 
716     /**
717      * Code for the uvc usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
718      * Only supported if {@link #isUvcSupportEnabled()} returns true.
719      * Must be equal to {@link GadgetFunction#UVC}
720      * @hide
721      */
722     @SystemApi
723     public static final long FUNCTION_UVC = 1 << 7;
724 
725     private static final long SETTABLE_FUNCTIONS = FUNCTION_MTP | FUNCTION_PTP | FUNCTION_RNDIS
726             | FUNCTION_MIDI | FUNCTION_NCM | FUNCTION_UVC;
727 
728     private static final Map<String, Long> FUNCTION_NAME_TO_CODE = new HashMap<>();
729 
730     /**
731      * Counter for tracking UsbOperation operations.
732      */
733     private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
734 
735     static {
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP)736         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_PTP, FUNCTION_PTP)737         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_PTP, FUNCTION_PTP);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_RNDIS, FUNCTION_RNDIS)738         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_RNDIS, FUNCTION_RNDIS);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MIDI, FUNCTION_MIDI)739         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MIDI, FUNCTION_MIDI);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ACCESSORY, FUNCTION_ACCESSORY)740         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ACCESSORY, FUNCTION_ACCESSORY);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_AUDIO_SOURCE, FUNCTION_AUDIO_SOURCE)741         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_AUDIO_SOURCE, FUNCTION_AUDIO_SOURCE);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ADB, FUNCTION_ADB)742         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ADB, FUNCTION_ADB);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_NCM, FUNCTION_NCM)743         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_NCM, FUNCTION_NCM);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_UVC, FUNCTION_UVC)744         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_UVC, FUNCTION_UVC);
745     }
746 
747     /** @hide */
748     @LongDef(flag = true, prefix = { "FUNCTION_" }, value = {
749             FUNCTION_NONE,
750             FUNCTION_MTP,
751             FUNCTION_PTP,
752             FUNCTION_RNDIS,
753             FUNCTION_MIDI,
754             FUNCTION_ACCESSORY,
755             FUNCTION_AUDIO_SOURCE,
756             FUNCTION_ADB,
757             FUNCTION_NCM,
758             FUNCTION_UVC,
759     })
760     @Retention(RetentionPolicy.SOURCE)
761     public @interface UsbFunctionMode {}
762 
763     /** @hide */
764     @IntDef(prefix = { "GADGET_HAL_" }, value = {
765             GADGET_HAL_NOT_SUPPORTED,
766             GADGET_HAL_V1_0,
767             GADGET_HAL_V1_1,
768             GADGET_HAL_V1_2,
769             GADGET_HAL_V2_0,
770     })
771     @Retention(RetentionPolicy.SOURCE)
772     public @interface UsbGadgetHalVersion {}
773 
774     /** @hide */
775     @IntDef(prefix = { "USB_HAL_" }, value = {
776             USB_HAL_NOT_SUPPORTED,
777             USB_HAL_V1_0,
778             USB_HAL_V1_1,
779             USB_HAL_V1_2,
780             USB_HAL_V1_3,
781             USB_HAL_V2_0,
782     })
783     @Retention(RetentionPolicy.SOURCE)
784     public @interface UsbHalVersion {}
785 
786     /**
787      * Listener to register for when the {@link DisplayPortAltModeInfo} changes on a
788      * {@link UsbPort}.
789      *
790      * @hide
791      */
792     @SystemApi
793     public interface DisplayPortAltModeInfoListener {
794         /**
795          * Callback to be executed when the {@link DisplayPortAltModeInfo} changes on a
796          * {@link UsbPort}.
797          *
798          * @param portId    String describing the {@link UsbPort} that was changed.
799          * @param info      New {@link DisplayPortAltModeInfo} for the corresponding portId.
800          */
onDisplayPortAltModeInfoChanged(@onNull String portId, @NonNull DisplayPortAltModeInfo info)801         public void onDisplayPortAltModeInfoChanged(@NonNull String portId,
802                 @NonNull DisplayPortAltModeInfo info);
803     }
804 
805     /**
806      * Holds callback and executor data to be passed across UsbService.
807      */
808     private class DisplayPortAltModeInfoDispatchingListener extends
809             IDisplayPortAltModeInfoListener.Stub {
810 
onDisplayPortAltModeInfoChanged(String portId, DisplayPortAltModeInfo displayPortAltModeInfo)811         public void onDisplayPortAltModeInfoChanged(String portId,
812                 DisplayPortAltModeInfo displayPortAltModeInfo) {
813             synchronized (mDisplayPortListenersLock) {
814                 for (Map.Entry<DisplayPortAltModeInfoListener, Executor> entry :
815                         mDisplayPortListeners.entrySet()) {
816                     Executor executor = entry.getValue();
817                     DisplayPortAltModeInfoListener callback = entry.getKey();
818                     final long token = Binder.clearCallingIdentity();
819                     try {
820                         executor.execute(() -> callback.onDisplayPortAltModeInfoChanged(portId,
821                                 displayPortAltModeInfo));
822                     } catch (Exception e) {
823                         Slog.e(TAG, "Exception during onDisplayPortAltModeInfoChanged from "
824                                 + "executor: " + executor, e);
825                     } finally {
826                         Binder.restoreCallingIdentity(token);
827                     }
828                 }
829             }
830         }
831     }
832 
833     /**
834      * Opens the handle for accessory, marks it as input or output, and adds it to the map
835      * if it is the first time the accessory has had an I/O stream associated with it.
836      */
openHandleForAccessory(UsbAccessory accessory, boolean openingInputStream)837     private AccessoryHandle openHandleForAccessory(UsbAccessory accessory,
838             boolean openingInputStream)
839             throws RemoteException {
840         synchronized (mAccessoryHandleMapLock) {
841             if (mAccessoryHandleMap == null) {
842                 mAccessoryHandleMap = new ArrayMap<>();
843             }
844 
845             // If accessory isn't available in map
846             if (!mAccessoryHandleMap.containsKey(accessory)) {
847                 // open accessory and store associated AccessoryHandle in map
848                 ParcelFileDescriptor pfd = mService.openAccessory(accessory);
849                 AccessoryHandle newHandle = new AccessoryHandle(pfd, openingInputStream,
850                         !openingInputStream);
851                 mAccessoryHandleMap.put(accessory, newHandle);
852 
853                 return newHandle;
854             }
855 
856             // if accessory is already in map, get modified handle
857             AccessoryHandle currentHandle = mAccessoryHandleMap.get(accessory);
858             if (currentHandle == null) {
859                 throw new IllegalStateException("Accessory doesn't have an associated handle yet!");
860             }
861 
862             AccessoryHandle modifiedHandle = getModifiedHandleForOpeningStream(
863                     openingInputStream, currentHandle);
864 
865             mAccessoryHandleMap.put(accessory, modifiedHandle);
866 
867             return modifiedHandle;
868         }
869     }
870 
getModifiedHandleForOpeningStream(boolean openingInputStream, @NonNull AccessoryHandle currentHandle)871     private AccessoryHandle getModifiedHandleForOpeningStream(boolean openingInputStream,
872             @NonNull AccessoryHandle currentHandle) {
873         if (currentHandle.isInputStreamOpened() && openingInputStream) {
874             throw new IllegalStateException("Input stream already open for this accessory! "
875                     + "Please close the existing input stream before opening a new one.");
876         }
877 
878         if (currentHandle.isOutputStreamOpened() && !openingInputStream) {
879             throw new IllegalStateException("Output stream already open for this accessory! "
880                     + "Please close the existing output stream before opening a new one.");
881         }
882 
883         boolean isInputStreamOpened = openingInputStream || currentHandle.isInputStreamOpened();
884         boolean isOutputStreamOpened = !openingInputStream || currentHandle.isOutputStreamOpened();
885 
886         return new AccessoryHandle(
887                 currentHandle.getPfd(), isInputStreamOpened, isOutputStreamOpened);
888     }
889 
890     /**
891      * Marks the handle for the given accessory closed for input or output, and closes the handle
892      * and removes it from the map if there are no more I/O streams associated with the handle.
893      */
closeHandleForAccessory(UsbAccessory accessory, boolean closingInputStream)894     private void closeHandleForAccessory(UsbAccessory accessory, boolean closingInputStream)
895             throws IOException {
896         synchronized (mAccessoryHandleMapLock) {
897             AccessoryHandle currentHandle = mAccessoryHandleMap.get(accessory);
898 
899             if (currentHandle == null) {
900                 throw new IllegalStateException(
901                         "No handle has been initialised for this accessory!");
902             }
903 
904             AccessoryHandle modifiedHandle = getModifiedHandleForClosingStream(
905                     closingInputStream, currentHandle);
906             if (!modifiedHandle.isOpen()) {
907                 //close handle and remove accessory handle pair from map
908                 modifiedHandle.getPfd().close();
909                 mAccessoryHandleMap.remove(accessory);
910             } else {
911                 mAccessoryHandleMap.put(accessory, modifiedHandle);
912             }
913         }
914     }
915 
getModifiedHandleForClosingStream(boolean closingInputStream, @NonNull AccessoryHandle currentHandle)916     private AccessoryHandle getModifiedHandleForClosingStream(boolean closingInputStream,
917             @NonNull AccessoryHandle currentHandle) {
918         if (!currentHandle.isInputStreamOpened() && closingInputStream) {
919             throw new IllegalStateException(
920                     "Attempting to close an input stream that has not been opened "
921                             + "for this accessory!");
922         }
923 
924         if (!currentHandle.isOutputStreamOpened() && !closingInputStream) {
925             throw new IllegalStateException(
926                     "Attempting to close an output stream that has not been opened "
927                             + "for this accessory!");
928         }
929 
930         boolean isInputStreamOpened = !closingInputStream && currentHandle.isInputStreamOpened();
931         boolean isOutputStreamOpened = closingInputStream && currentHandle.isOutputStreamOpened();
932 
933         return new AccessoryHandle(
934                 currentHandle.getPfd(), isInputStreamOpened, isOutputStreamOpened);
935     }
936 
937     /**
938      * An InputStream you can create on a UsbAccessory, which will
939      * take care of calling {@link ParcelFileDescriptor#close
940      * ParcelFileDescriptor.close()} for you when the stream is closed.
941      */
942     private class AccessoryAutoCloseInputStream extends FileInputStream {
943 
944         private final ParcelFileDescriptor mPfd;
945         private final UsbAccessory mAccessory;
946 
AccessoryAutoCloseInputStream(UsbAccessory accessory, ParcelFileDescriptor pfd)947         AccessoryAutoCloseInputStream(UsbAccessory accessory, ParcelFileDescriptor pfd) {
948             super(pfd.getFileDescriptor());
949             this.mAccessory = accessory;
950             this.mPfd = pfd;
951         }
952 
953         @Override
close()954         public void close() throws IOException {
955             /* TODO(b/377850642) : Ensure the stream is closed even if client does not
956                 explicitly close the stream to avoid corrupt FDs*/
957             super.close();
958             closeHandleForAccessory(mAccessory, true);
959         }
960 
961 
962         @Override
read()963         public int read() throws IOException {
964             final int result = super.read();
965             checkError(result);
966             return result;
967         }
968 
969         @Override
read(byte[] b)970         public int read(byte[] b) throws IOException {
971             final int result = super.read(b);
972             checkError(result);
973             return result;
974         }
975 
976         @Override
read(byte[] b, int off, int len)977         public int read(byte[] b, int off, int len) throws IOException {
978             final int result = super.read(b, off, len);
979             checkError(result);
980             return result;
981         }
982 
checkError(int result)983         private void checkError(int result) throws IOException {
984             if (result == -1 && mPfd.canDetectErrors()) {
985                 mPfd.checkError();
986             }
987         }
988     }
989 
990     /**
991      * An OutputStream you can create on a UsbAccessory, which will
992      * take care of calling {@link ParcelFileDescriptor#close
993      * ParcelFileDescriptor.close()} for you when the stream is closed.
994      */
995     private class AccessoryAutoCloseOutputStream extends FileOutputStream {
996         private final UsbAccessory mAccessory;
997 
AccessoryAutoCloseOutputStream(UsbAccessory accessory, ParcelFileDescriptor pfd)998         AccessoryAutoCloseOutputStream(UsbAccessory accessory, ParcelFileDescriptor pfd) {
999             super(pfd.getFileDescriptor());
1000             mAccessory = accessory;
1001         }
1002 
1003         @Override
close()1004         public void close() throws IOException {
1005             /* TODO(b/377850642) : Ensure the stream is closed even if client does not
1006                 explicitly close the stream to avoid corrupt FDs*/
1007             super.close();
1008             closeHandleForAccessory(mAccessory, false);
1009         }
1010     }
1011 
1012     /**
1013      * Holds file descriptor and marks whether input and output streams have been opened for it.
1014      */
1015     private static class AccessoryHandle {
1016         private final ParcelFileDescriptor mPfd;
1017         private final boolean mInputStreamOpened;
1018         private final boolean mOutputStreamOpened;
AccessoryHandle(ParcelFileDescriptor parcelFileDescriptor, boolean inputStreamOpened, boolean outputStreamOpened)1019         AccessoryHandle(ParcelFileDescriptor parcelFileDescriptor,
1020                 boolean inputStreamOpened, boolean outputStreamOpened) {
1021             mPfd = parcelFileDescriptor;
1022             mInputStreamOpened = inputStreamOpened;
1023             mOutputStreamOpened = outputStreamOpened;
1024         }
1025 
getPfd()1026         public ParcelFileDescriptor getPfd() {
1027             return mPfd;
1028         }
1029 
isInputStreamOpened()1030         public boolean isInputStreamOpened() {
1031             return mInputStreamOpened;
1032         }
1033 
isOutputStreamOpened()1034         public boolean isOutputStreamOpened() {
1035             return mOutputStreamOpened;
1036         }
1037 
isOpen()1038         public boolean isOpen() {
1039             return (mInputStreamOpened || mOutputStreamOpened);
1040         }
1041     }
1042 
1043     private final Context mContext;
1044     private final IUsbManager mService;
1045     private final Object mDisplayPortListenersLock = new Object();
1046     @GuardedBy("mDisplayPortListenersLock")
1047     private ArrayMap<DisplayPortAltModeInfoListener, Executor> mDisplayPortListeners;
1048     @GuardedBy("mDisplayPortListenersLock")
1049     private DisplayPortAltModeInfoDispatchingListener mDisplayPortServiceListener;
1050 
1051     private final Object mAccessoryHandleMapLock = new Object();
1052     @GuardedBy("mAccessoryHandleMapLock")
1053     private ArrayMap<UsbAccessory, AccessoryHandle> mAccessoryHandleMap;
1054 
1055 
1056     /**
1057      * @hide
1058      */
1059     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
UsbManager(Context context, IUsbManager service)1060     public UsbManager(Context context, IUsbManager service) {
1061         mContext = context;
1062         mService = service;
1063     }
1064 
1065     /**
1066      * Returns a HashMap containing all USB devices currently attached.
1067      * USB device name is the key for the returned HashMap.
1068      * The result will be empty if no devices are attached, or if
1069      * USB host mode is inactive or unsupported.
1070      *
1071      * @return HashMap containing all connected USB devices.
1072      */
1073     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
getDeviceList()1074     public HashMap<String,UsbDevice> getDeviceList() {
1075         HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
1076         if (mService == null) {
1077             return result;
1078         }
1079         Bundle bundle = new Bundle();
1080         try {
1081             mService.getDeviceList(bundle);
1082             for (String name : bundle.keySet()) {
1083                 result.put(name, (UsbDevice)bundle.get(name));
1084             }
1085             return result;
1086         } catch (RemoteException e) {
1087             throw e.rethrowFromSystemServer();
1088         }
1089     }
1090 
1091     /**
1092      * Opens the device so it can be used to send and receive
1093      * data using {@link android.hardware.usb.UsbRequest}.
1094      *
1095      * @param device the device to open
1096      * @return a {@link UsbDeviceConnection}, or {@code null} if open failed
1097      */
1098     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
openDevice(UsbDevice device)1099     public UsbDeviceConnection openDevice(UsbDevice device) {
1100         try {
1101             String deviceName = device.getDeviceName();
1102             ParcelFileDescriptor pfd = mService.openDevice(deviceName, mContext.getPackageName());
1103             if (pfd != null) {
1104                 UsbDeviceConnection connection = new UsbDeviceConnection(device);
1105                 boolean result = connection.open(deviceName, pfd, mContext);
1106                 pfd.close();
1107                 if (result) {
1108                     return connection;
1109                 }
1110             }
1111         } catch (Exception e) {
1112             Log.e(TAG, "exception in UsbManager.openDevice", e);
1113         }
1114         return null;
1115     }
1116 
1117     /**
1118      * Returns a list of currently attached USB accessories.
1119      * (in the current implementation there can be at most one)
1120      *
1121      * @return list of USB accessories, or null if none are attached.
1122      */
1123     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
getAccessoryList()1124     public UsbAccessory[] getAccessoryList() {
1125         if (mService == null) {
1126             return null;
1127         }
1128         try {
1129             UsbAccessory accessory = mService.getCurrentAccessory();
1130             if (accessory == null) {
1131                 return null;
1132             } else {
1133                 return new UsbAccessory[] { accessory };
1134             }
1135         } catch (RemoteException e) {
1136             throw e.rethrowFromSystemServer();
1137         }
1138     }
1139 
1140     /**
1141      * Opens a file descriptor for reading and writing data to the USB accessory.
1142      *
1143      * <p>If data is read from the {@link java.io.InputStream} created from this file descriptor all
1144      * data of a USB transfer should be read at once. If only a partial request is read the rest of
1145      * the transfer is dropped.
1146      *
1147      * <p>It is strongly recommended to use newer methods instead of this method,
1148      * since this method may provide sub-optimal performance on some devices.
1149      * This method could potentially face interim performance degradation as well.
1150      *
1151      * @param accessory the USB accessory to open
1152      * @return file descriptor, or null if the accessory could not be opened.
1153      */
1154     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
openAccessory(UsbAccessory accessory)1155     public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
1156         try {
1157             return mService.openAccessory(accessory);
1158         } catch (RemoteException e) {
1159             throw e.rethrowFromSystemServer();
1160         }
1161     }
1162 
1163     /**
1164      * Opens an input stream for reading from the USB accessory.
1165      * If accessory is not open at this point, accessory will first be opened.
1166      * <p>If data is read from the created {@link java.io.InputStream} all
1167      * data of a USB transfer should be read at once. If only a partial request is read, the rest of
1168      * the transfer is dropped.
1169      * <p>The caller is responsible for ensuring that the returned stream is closed.
1170      *
1171      * @param accessory the USB accessory to open an input stream for
1172      * @return input stream to read from given USB accessory
1173      */
1174     @FlaggedApi(Flags.FLAG_ENABLE_ACCESSORY_STREAM_API)
1175     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
openAccessoryInputStream(@onNull UsbAccessory accessory)1176     public @NonNull InputStream openAccessoryInputStream(@NonNull UsbAccessory accessory) {
1177         try {
1178             return new AccessoryAutoCloseInputStream(accessory,
1179                     openHandleForAccessory(accessory, true).getPfd());
1180 
1181         } catch (RemoteException e) {
1182             throw e.rethrowFromSystemServer();
1183         }
1184     }
1185 
1186     /**
1187      * Opens an output stream for writing to the USB accessory.
1188      * If accessory is not open at this point, accessory will first be opened.
1189      * <p>The caller is responsible for ensuring that the returned stream is closed.
1190      *
1191      * @param accessory the USB accessory to open an output stream for
1192      * @return output stream to write to given USB accessory
1193      */
1194     @FlaggedApi(Flags.FLAG_ENABLE_ACCESSORY_STREAM_API)
1195     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
openAccessoryOutputStream(@onNull UsbAccessory accessory)1196     public @NonNull OutputStream openAccessoryOutputStream(@NonNull UsbAccessory accessory) {
1197         try {
1198             return new AccessoryAutoCloseOutputStream(accessory,
1199                     openHandleForAccessory(accessory, false).getPfd());
1200         } catch (RemoteException e) {
1201             throw e.rethrowFromSystemServer();
1202         }
1203 
1204     }
1205 
1206     /**
1207      * Gets the functionfs control file descriptor for the given function, with
1208      * the usb descriptors and strings already written. The file descriptor is used
1209      * by the function implementation to handle events and control requests.
1210      *
1211      * @param function to get control fd for. Currently {@link #FUNCTION_MTP} and
1212      * {@link #FUNCTION_PTP} are supported.
1213      * @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found.
1214      *
1215      * @hide
1216      */
getControlFd(long function)1217     public ParcelFileDescriptor getControlFd(long function) {
1218         try {
1219             return mService.getControlFd(function);
1220         } catch (RemoteException e) {
1221             throw e.rethrowFromSystemServer();
1222         }
1223     }
1224 
1225     /**
1226      * Returns true if the caller has permission to access the device.
1227      * Permission might have been granted temporarily via
1228      * {@link #requestPermission(UsbDevice, PendingIntent)} or
1229      * by the user choosing the caller as the default application for the device.
1230      * Permission for USB devices of class {@link UsbConstants#USB_CLASS_VIDEO} for clients that
1231      * target SDK {@link android.os.Build.VERSION_CODES#P} and above can be granted only if they
1232      * have additionally the {@link android.Manifest.permission#CAMERA} permission.
1233      *
1234      * @param device to check permissions for
1235      * @return true if caller has permission
1236      */
1237     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
hasPermission(UsbDevice device)1238     public boolean hasPermission(UsbDevice device) {
1239         if (mService == null) {
1240             return false;
1241         }
1242         try {
1243             return mService.hasDevicePermission(device, mContext.getPackageName());
1244         } catch (RemoteException e) {
1245             throw e.rethrowFromSystemServer();
1246         }
1247     }
1248 
1249     /**
1250      * Returns true if the caller has permission to access the device. It's similar to the
1251      * {@link #hasPermission(UsbDevice)} but allows to specify a different package/uid/pid.
1252      *
1253      * <p>Not for third-party apps.</p>
1254      *
1255      * @hide
1256      */
1257     @RequiresPermission(Manifest.permission.MANAGE_USB)
1258     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
hasPermission(@onNull UsbDevice device, @NonNull String packageName, int pid, int uid)1259     public boolean hasPermission(@NonNull UsbDevice device, @NonNull String packageName,
1260             int pid, int uid) {
1261         if (mService == null) {
1262             return false;
1263         }
1264         try {
1265             return mService.hasDevicePermissionWithIdentity(device, packageName, pid, uid);
1266         } catch (RemoteException e) {
1267             throw e.rethrowFromSystemServer();
1268         }
1269     }
1270 
1271     /**
1272      * Returns true if the caller has permission to access the accessory.
1273      * Permission might have been granted temporarily via
1274      * {@link #requestPermission(UsbAccessory, PendingIntent)} or
1275      * by the user choosing the caller as the default application for the accessory.
1276      *
1277      * @param accessory to check permissions for
1278      * @return true if caller has permission
1279      */
1280     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
hasPermission(UsbAccessory accessory)1281     public boolean hasPermission(UsbAccessory accessory) {
1282         if (mService == null) {
1283             return false;
1284         }
1285         try {
1286             return mService.hasAccessoryPermission(accessory);
1287         } catch (RemoteException e) {
1288             throw e.rethrowFromSystemServer();
1289         }
1290     }
1291 
1292     /**
1293      * Returns true if the caller has permission to access the accessory. It's similar to the
1294      * {@link #hasPermission(UsbAccessory)} but allows to specify a different uid/pid.
1295      *
1296      * <p>Not for third-party apps.</p>
1297      *
1298      * @hide
1299      */
1300     @RequiresPermission(Manifest.permission.MANAGE_USB)
1301     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
hasPermission(@onNull UsbAccessory accessory, int pid, int uid)1302     public boolean hasPermission(@NonNull UsbAccessory accessory, int pid, int uid) {
1303         if (mService == null) {
1304             return false;
1305         }
1306         try {
1307             return mService.hasAccessoryPermissionWithIdentity(accessory, pid, uid);
1308         } catch (RemoteException e) {
1309             throw e.rethrowFromSystemServer();
1310         }
1311     }
1312 
1313     /**
1314      * Requests temporary permission for the given package to access the device.
1315      * This may result in a system dialog being displayed to the user
1316      * if permission had not already been granted.
1317      * Success or failure is returned via the {@link android.app.PendingIntent} pi.
1318      * If successful, this grants the caller permission to access the device only
1319      * until the device is disconnected.
1320      *
1321      * The following extras will be added to pi:
1322      * <ul>
1323      * <li> {@link #EXTRA_DEVICE} containing the device passed into this call
1324      * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
1325      * permission was granted by the user
1326      * </ul>
1327      *
1328      * Permission for USB devices of class {@link UsbConstants#USB_CLASS_VIDEO} for clients that
1329      * target SDK {@link android.os.Build.VERSION_CODES#P} and above can be granted only if they
1330      * have additionally the {@link android.Manifest.permission#CAMERA} permission.
1331      *
1332      * @param device to request permissions for
1333      * @param pi PendingIntent for returning result
1334      */
1335     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
requestPermission(UsbDevice device, PendingIntent pi)1336     public void requestPermission(UsbDevice device, PendingIntent pi) {
1337         try {
1338             mService.requestDevicePermission(device, mContext.getPackageName(), pi);
1339         } catch (RemoteException e) {
1340             throw e.rethrowFromSystemServer();
1341         }
1342     }
1343 
1344     /**
1345      * Requests temporary permission for the given package to access the accessory.
1346      * This may result in a system dialog being displayed to the user
1347      * if permission had not already been granted.
1348      * Success or failure is returned via the {@link android.app.PendingIntent} pi.
1349      * If successful, this grants the caller permission to access the accessory only
1350      * until the device is disconnected.
1351      *
1352      * The following extras will be added to pi:
1353      * <ul>
1354      * <li> {@link #EXTRA_ACCESSORY} containing the accessory passed into this call
1355      * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
1356      * permission was granted by the user
1357      * </ul>
1358      *
1359      * @param accessory to request permissions for
1360      * @param pi PendingIntent for returning result
1361      */
1362     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
requestPermission(UsbAccessory accessory, PendingIntent pi)1363     public void requestPermission(UsbAccessory accessory, PendingIntent pi) {
1364         try {
1365             mService.requestAccessoryPermission(accessory, mContext.getPackageName(), pi);
1366         } catch (RemoteException e) {
1367             throw e.rethrowFromSystemServer();
1368         }
1369     }
1370 
1371     /**
1372      * Grants permission for USB device without showing system dialog.
1373      * Only system components can call this function.
1374      * @param device to request permissions for
1375      *
1376      * @hide
1377      */
grantPermission(UsbDevice device)1378     public void grantPermission(UsbDevice device) {
1379         grantPermission(device, Process.myUid());
1380     }
1381 
1382     /**
1383      * Grants permission for USB device to given uid without showing system dialog.
1384      * Only system components can call this function.
1385      * @param device to request permissions for
1386      * @uid uid to give permission
1387      *
1388      * @hide
1389      */
grantPermission(UsbDevice device, int uid)1390     public void grantPermission(UsbDevice device, int uid) {
1391         try {
1392             mService.grantDevicePermission(device, uid);
1393         } catch (RemoteException e) {
1394             throw e.rethrowFromSystemServer();
1395         }
1396     }
1397 
1398     /**
1399      * Grants permission to specified package for USB device without showing system dialog.
1400      * Only system components can call this function, as it requires the MANAGE_USB permission.
1401      * @param device to request permissions for
1402      * @param packageName of package to grant permissions
1403      *
1404      * @hide
1405      */
1406     @SystemApi
1407     @RequiresPermission(Manifest.permission.MANAGE_USB)
grantPermission(UsbDevice device, String packageName)1408     public void grantPermission(UsbDevice device, String packageName) {
1409         try {
1410             int uid = mContext.getPackageManager()
1411                 .getPackageUidAsUser(packageName, mContext.getUserId());
1412             grantPermission(device, uid);
1413         } catch (NameNotFoundException e) {
1414             Log.e(TAG, "Package " + packageName + " not found.", e);
1415         }
1416     }
1417 
1418     /**
1419      * Returns true if the specified USB function is currently enabled when in device mode.
1420      * <p>
1421      * USB functions represent interfaces which are published to the host to access
1422      * services offered by the device.
1423      * </p>
1424      *
1425      * @deprecated use getCurrentFunctions() instead.
1426      * @param function name of the USB function
1427      * @return true if the USB function is enabled
1428      *
1429      * @hide
1430      */
1431     @Deprecated
1432     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
isFunctionEnabled(String function)1433     public boolean isFunctionEnabled(String function) {
1434         try {
1435             return mService.isFunctionEnabled(function);
1436         } catch (RemoteException e) {
1437             throw e.rethrowFromSystemServer();
1438         }
1439     }
1440 
1441     /**
1442      * Returns true if the specified UVC gadget function support is enabled.
1443      * <p>
1444      * @hide
1445      */
1446     @TestApi
1447     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
isUvcGadgetSupportEnabled()1448     public boolean isUvcGadgetSupportEnabled() {
1449         try {
1450             return mService.isUvcGadgetSupportEnabled();
1451         } catch (RemoteException e) {
1452             throw e.rethrowFromSystemServer();
1453         }
1454     }
1455 
1456     /**
1457      * Sets the current USB functions when in device mode.
1458      * <p>
1459      * USB functions represent interfaces which are published to the host to access
1460      * services offered by the device.
1461      * </p><p>
1462      * This method is intended to select among primary USB functions.  The system may
1463      * automatically activate additional functions such as {@link #USB_FUNCTION_ADB}
1464      * or {@link #USB_FUNCTION_ACCESSORY} based on other settings and states.
1465      * </p><p>
1466      * An argument of 0 indicates that the device is charging, and can pick any
1467      * appropriate function for that purpose.
1468      * </p><p>
1469      * Note: This function is asynchronous and may fail silently without applying
1470      * the requested changes.
1471      * </p>
1472      *
1473      * @param functions the USB function(s) to set, as a bitwise mask.
1474      *                  Must satisfy {@link UsbManager#areSettableFunctions}
1475      *
1476      * @hide
1477      */
1478     @SystemApi
1479     @RequiresPermission(Manifest.permission.MANAGE_USB)
setCurrentFunctions(@sbFunctionMode long functions)1480     public void setCurrentFunctions(@UsbFunctionMode long functions) {
1481         int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
1482         try {
1483             mService.setCurrentFunctions(functions, operationId);
1484         } catch (RemoteException e) {
1485             Log.e(TAG, "setCurrentFunctions: failed to call setCurrentFunctions. functions:"
1486                         + functions + ", opId:" + operationId, e);
1487             throw e.rethrowFromSystemServer();
1488         }
1489     }
1490 
1491     /**
1492      * Sets the current USB functions when in device mode.
1493      *
1494      * @deprecated use setCurrentFunctions(long) instead.
1495      * @param functions the USB function(s) to set.
1496      * @param usbDataUnlocked unused
1497 
1498      * @hide
1499      */
1500     @Deprecated
1501     @UnsupportedAppUsage
setCurrentFunction(String functions, boolean usbDataUnlocked)1502     public void setCurrentFunction(String functions, boolean usbDataUnlocked) {
1503         int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
1504         try {
1505             mService.setCurrentFunction(functions, usbDataUnlocked, operationId);
1506         } catch (RemoteException e) {
1507             Log.e(TAG, "setCurrentFunction: failed to call setCurrentFunction. functions:"
1508                         + functions + ", opId:" + operationId, e);
1509             throw e.rethrowFromSystemServer();
1510         }
1511     }
1512 
1513     /**
1514      * Returns the current USB functions in device mode.
1515      * <p>
1516      * This function returns the state of primary USB functions and can return a
1517      * mask containing any usb function(s) except for ADB.
1518      * </p>
1519      *
1520      * @return The currently enabled functions, in a bitwise mask.
1521      * A zero mask indicates that the current function is the charging function.
1522      *
1523      * @hide
1524      */
1525     @SystemApi
1526     @RequiresPermission(Manifest.permission.MANAGE_USB)
getCurrentFunctions()1527     public long getCurrentFunctions() {
1528         try {
1529             return mService.getCurrentFunctions();
1530         } catch (RemoteException e) {
1531             throw e.rethrowFromSystemServer();
1532         }
1533     }
1534 
1535     /**
1536      * Sets the screen unlocked functions, which are persisted and set as the current functions
1537      * whenever the screen is unlocked.
1538      * <p>
1539      * A zero mask has the effect of switching off this feature, so functions
1540      * no longer change on screen unlock.
1541      * </p><p>
1542      * Note: When the screen is on, this method will apply given functions as current functions,
1543      * which is asynchronous and may fail silently without applying the requested changes.
1544      * </p>
1545      *
1546      * @param functions functions to set, in a bitwise mask.
1547      *                  Must satisfy {@link UsbManager#areSettableFunctions}
1548      *
1549      * @hide
1550      */
setScreenUnlockedFunctions(long functions)1551     public void setScreenUnlockedFunctions(long functions) {
1552         try {
1553             mService.setScreenUnlockedFunctions(functions);
1554         } catch (RemoteException e) {
1555             throw e.rethrowFromSystemServer();
1556         }
1557     }
1558 
1559     /**
1560      * Gets the current screen unlocked functions.
1561      *
1562      * @return The currently set screen enabled functions.
1563      * A zero mask indicates that the screen unlocked functions feature is not enabled.
1564      *
1565      * @hide
1566      */
getScreenUnlockedFunctions()1567     public long getScreenUnlockedFunctions() {
1568         try {
1569             return mService.getScreenUnlockedFunctions();
1570         } catch (RemoteException e) {
1571             throw e.rethrowFromSystemServer();
1572         }
1573     }
1574 
1575     /**
1576      * Get the Current USB Bandwidth.
1577      * <p>
1578      * This function returns the current USB bandwidth through USB Gadget HAL.
1579      * It should be used when Android device is in USB peripheral mode and
1580      * connects to a USB host. If USB state is not configured, API will return
1581      * {@value #USB_DATA_TRANSFER_RATE_UNKNOWN}. In addition, the unit of the
1582      * return value is Mbps.
1583      * </p>
1584      *
1585      * @return The value of currently USB Bandwidth.
1586      *
1587      * @hide
1588      */
1589     @FlaggedApi(Flags.FLAG_EXPOSE_USB_SPEED_SYSTEM_API)
1590     @SystemApi
1591     @RequiresPermission(Manifest.permission.MANAGE_USB)
getUsbBandwidthMbps()1592     public int getUsbBandwidthMbps() {
1593         int usbSpeed;
1594         try {
1595             usbSpeed = mService.getCurrentUsbSpeed();
1596         } catch (RemoteException e) {
1597             throw e.rethrowFromSystemServer();
1598         }
1599         return usbSpeedToBandwidth(usbSpeed);
1600     }
1601 
1602     /**
1603      * Get the Current Gadget Hal Version.
1604      * <p>
1605      * This function returns the current Gadget Hal Version.
1606      * </p>
1607      *
1608      * @return a integer {@code GADGET_HAL_*} represent hal version.
1609      *
1610      * @hide
1611      */
1612     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
1613     @RequiresPermission(Manifest.permission.MANAGE_USB)
getGadgetHalVersion()1614     public @UsbGadgetHalVersion int getGadgetHalVersion() {
1615         try {
1616             return mService.getGadgetHalVersion();
1617         } catch (RemoteException e) {
1618             throw e.rethrowFromSystemServer();
1619         }
1620     }
1621 
1622     /**
1623      * Get the Current USB Hal Version.
1624      * <p>
1625      * This function returns the current USB Hal Version.
1626      * </p>
1627      *
1628      * @return a integer {@code USB_HAL_*} represent hal version.
1629      *
1630      * @hide
1631      */
1632     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
1633     @RequiresPermission(Manifest.permission.MANAGE_USB)
getUsbHalVersion()1634     public @UsbHalVersion int getUsbHalVersion() {
1635         try {
1636             return mService.getUsbHalVersion();
1637         } catch (RemoteException e) {
1638             throw e.rethrowFromSystemServer();
1639         }
1640     }
1641 
1642     /**
1643      * Resets the USB Gadget.
1644      * <p>
1645      * Performs USB data stack reset through USB Gadget HAL.
1646      * It will force USB data connection reset. The connection will disconnect and reconnect.
1647      * </p>
1648      *
1649      * @hide
1650      */
1651     @SystemApi
1652     @RequiresPermission(Manifest.permission.MANAGE_USB)
resetUsbGadget()1653     public void resetUsbGadget() {
1654         try {
1655             mService.resetUsbGadget();
1656         } catch (RemoteException e) {
1657             throw e.rethrowFromSystemServer();
1658         }
1659     }
1660 
1661     // TODO: b/396680593 Deprecate to de-dup with isUvcGadgetSupportEnabled()
1662     /**
1663      * Returns whether UVC is advertised to be supported or not. SELinux
1664      * enforces that this function returns {@code false} when called from a
1665      * process that doesn't belong either to a system app, or the
1666      * DeviceAsWebcam Service.
1667      *
1668      * @return true if UVC is supported, false if UVC is not supported or if
1669      *         called from a non-system app that isn't DeviceAsWebcam Service.
1670      * @hide
1671      */
1672     @SystemApi
isUvcSupportEnabled()1673     public static boolean isUvcSupportEnabled() {
1674         return SystemProperties.getBoolean("ro.usb.uvc.enabled", false);
1675     }
1676 
1677     /**
1678      * Enable/Disable the USB data signaling.
1679      * <p>
1680      * Enables/Disables USB data path of all USB ports.
1681      * It will force to stop or restore USB data signaling.
1682      * </p>
1683      *
1684      * @param enable enable or disable USB data signaling
1685      * @return true enable or disable USB data successfully
1686      *         false if something wrong
1687      *
1688      * @hide
1689      */
1690     @RequiresPermission(Manifest.permission.MANAGE_USB)
enableUsbDataSignal(boolean enable)1691     public boolean enableUsbDataSignal(boolean enable) {
1692         return setUsbDataSignal(getPorts(), !enable, /* revertOnFailure= */ true);
1693     }
1694 
setUsbDataSignal(List<UsbPort> usbPorts, boolean disable, boolean revertOnFailure)1695     private boolean setUsbDataSignal(List<UsbPort> usbPorts, boolean disable,
1696             boolean revertOnFailure) {
1697         List<UsbPort> changedPorts = new ArrayList<>();
1698         for (int i = 0; i < usbPorts.size(); i++) {
1699             UsbPort port = usbPorts.get(i);
1700             if (isPortDisabled(port) != disable) {
1701                 changedPorts.add(port);
1702                 if (port.enableUsbData(!disable) != UsbPort.ENABLE_USB_DATA_SUCCESS
1703                         && revertOnFailure) {
1704                     Log.e(TAG, "Failed to set usb data signal for portID(" + port.getId() + ")");
1705                     setUsbDataSignal(changedPorts, !disable, /* revertOnFailure= */ false);
1706                     return false;
1707                 }
1708             }
1709         }
1710         return true;
1711     }
1712 
isPortDisabled(UsbPort usbPort)1713     private boolean isPortDisabled(UsbPort usbPort) {
1714         return (getPortStatus(usbPort).getUsbDataStatus() & DATA_STATUS_DISABLED_FORCE)
1715                 == DATA_STATUS_DISABLED_FORCE;
1716     }
1717 
1718     /**
1719      * Returns a list of physical USB ports on the device.
1720      * <p>
1721      * This list is guaranteed to contain all dual-role USB Type C ports but it might
1722      * be missing other ports depending on whether the kernel USB drivers have been
1723      * updated to publish all of the device's ports through the new "dual_role_usb"
1724      * device class (which supports all types of ports despite its name).
1725      * </p>
1726      *
1727      * @return The list of USB ports
1728      *
1729      * @hide
1730      */
1731     @SystemApi
1732     @RequiresPermission(Manifest.permission.MANAGE_USB)
getPorts()1733     public @NonNull List<UsbPort> getPorts() {
1734         if (mService == null) {
1735             return Collections.emptyList();
1736         }
1737 
1738         List<ParcelableUsbPort> parcelablePorts;
1739         try {
1740             parcelablePorts = mService.getPorts();
1741         } catch (RemoteException e) {
1742             throw e.rethrowFromSystemServer();
1743         }
1744 
1745         if (parcelablePorts == null) {
1746             return Collections.emptyList();
1747         } else {
1748             int numPorts = parcelablePorts.size();
1749 
1750             ArrayList<UsbPort> ports = new ArrayList<>(numPorts);
1751             for (int i = 0; i < numPorts; i++) {
1752                 ports.add(parcelablePorts.get(i).getUsbPort(this));
1753             }
1754 
1755             return ports;
1756         }
1757     }
1758 
1759     /**
1760      * Should only be called by {@link UsbPort#getStatus}.
1761      *
1762      * @hide
1763      */
getPortStatus(UsbPort port)1764     UsbPortStatus getPortStatus(UsbPort port) {
1765         try {
1766             return mService.getPortStatus(port.getId());
1767         } catch (RemoteException e) {
1768             throw e.rethrowFromSystemServer();
1769         }
1770     }
1771 
1772     /**
1773      * Checks if the given port supports mode change. Should only be called by
1774      * {@link UsbPort#isModeChangeSupported}.
1775      *
1776      * @hide
1777      */
1778     @RequiresPermission(Manifest.permission.MANAGE_USB)
isModeChangeSupported(UsbPort port)1779     boolean isModeChangeSupported(UsbPort port) {
1780         try {
1781             return mService.isModeChangeSupported(port.getId());
1782         } catch (RemoteException e) {
1783             throw e.rethrowFromSystemServer();
1784         }
1785     }
1786 
1787     /**
1788      * Should only be called by {@link UsbPort#setRoles}.
1789      *
1790      * @hide
1791      */
setPortRoles(UsbPort port, int powerRole, int dataRole)1792     void setPortRoles(UsbPort port, int powerRole, int dataRole) {
1793         Log.d(TAG, "setPortRoles Package:" + mContext.getPackageName());
1794         try {
1795             mService.setPortRoles(port.getId(), powerRole, dataRole);
1796         } catch (RemoteException e) {
1797             throw e.rethrowFromSystemServer();
1798         }
1799     }
1800 
1801     /**
1802      * Enables USB port contaminant detection algorithm.
1803      *
1804      * @hide
1805      */
1806     @RequiresPermission(Manifest.permission.MANAGE_USB)
enableContaminantDetection(@onNull UsbPort port, boolean enable)1807     void enableContaminantDetection(@NonNull UsbPort port, boolean enable) {
1808         try {
1809             mService.enableContaminantDetection(port.getId(), enable);
1810         } catch (RemoteException e) {
1811             throw e.rethrowFromSystemServer();
1812         }
1813     }
1814 
1815     /**
1816      * Should only be called by {@link UsbPort#enableLimitPowerTransfer}.
1817      * <p>
1818      * limits or restores power transfer in and out of USB port.
1819      *
1820      * @param port USB port for which power transfer has to be limited or restored.
1821      * @param limit limit power transfer when true.
1822      *              relax power transfer restrictions when false.
1823      * @param operationId operationId for the request.
1824      * @param callback callback object to be invoked when the operation is complete.
1825      *
1826      * @hide
1827      */
1828     @RequiresPermission(Manifest.permission.MANAGE_USB)
enableLimitPowerTransfer(@onNull UsbPort port, boolean limit, int operationId, IUsbOperationInternal callback)1829     void enableLimitPowerTransfer(@NonNull UsbPort port, boolean limit, int operationId,
1830             IUsbOperationInternal callback) {
1831         Objects.requireNonNull(port, "enableLimitPowerTransfer:port must not be null. opId:"
1832                 + operationId);
1833         try {
1834             mService.enableLimitPowerTransfer(port.getId(), limit, operationId, callback);
1835         } catch (RemoteException e) {
1836             Log.e(TAG, "enableLimitPowerTransfer failed. opId:" + operationId, e);
1837             try {
1838                 callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL);
1839             } catch (RemoteException r) {
1840                 Log.e(TAG, "enableLimitPowerTransfer failed to call onOperationComplete. opId:"
1841                         + operationId, r);
1842             }
1843             throw e.rethrowFromSystemServer();
1844         }
1845     }
1846 
1847     /**
1848      * Should only be called by {@link UsbPort#resetUsbPort}.
1849      * <p>
1850      * Disable and then re-enable USB data signaling.
1851      *
1852      * Reset USB first port..
1853      * It will force to stop and restart USB data signaling.
1854      * Call UsbPort API if the device has more than one UsbPort.
1855      * </p>
1856      *
1857      * @param port reset the USB Port
1858      * @return true enable or disable USB data successfully
1859      *         false if something wrong
1860      *
1861      * Should only be called by {@link UsbPort#resetUsbPort}.
1862      *
1863      * @hide
1864      */
1865     @RequiresPermission(Manifest.permission.MANAGE_USB)
resetUsbPort(@onNull UsbPort port, int operationId, IUsbOperationInternal callback)1866     void resetUsbPort(@NonNull UsbPort port, int operationId,
1867             IUsbOperationInternal callback) {
1868         Objects.requireNonNull(port, "resetUsbPort: port must not be null. opId:" + operationId);
1869         try {
1870             mService.resetUsbPort(port.getId(), operationId, callback);
1871         } catch (RemoteException e) {
1872             Log.e(TAG, "resetUsbPort: failed. ", e);
1873             try {
1874                 callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL);
1875             } catch (RemoteException r) {
1876                 Log.e(TAG, "resetUsbPort: failed to call onOperationComplete. opId:"
1877                         + operationId, r);
1878             }
1879             throw e.rethrowFromSystemServer();
1880         }
1881     }
1882 
1883     /**
1884      * Should only be called by {@link UsbPort#enableUsbData}.
1885      * <p>
1886      * Enables or disables USB data on the specific port.
1887      *
1888      * @param port USB port for which USB data needs to be enabled or disabled.
1889      * @param enable Enable USB data when true.
1890      *               Disable USB data when false.
1891      * @param operationId operationId for the request.
1892      * @param callback callback object to be invoked when the operation is complete.
1893      * @return True when the operation is asynchronous. The caller must therefore call
1894      *         {@link UsbOperationInternal#waitForOperationComplete} for processing
1895      *         the result.
1896      *         False when the operation is synchronous. Caller can proceed reading the result
1897      *         through {@link UsbOperationInternal#getStatus}
1898      * @hide
1899      */
1900     @RequiresPermission(Manifest.permission.MANAGE_USB)
enableUsbData(@onNull UsbPort port, boolean enable, int operationId, IUsbOperationInternal callback)1901     boolean enableUsbData(@NonNull UsbPort port, boolean enable, int operationId,
1902             IUsbOperationInternal callback) {
1903         Objects.requireNonNull(port, "enableUsbData: port must not be null. opId:" + operationId);
1904         try {
1905             return mService.enableUsbData(port.getId(), enable, operationId, callback);
1906         } catch (RemoteException e) {
1907             Log.e(TAG, "enableUsbData: failed. opId:" + operationId, e);
1908             try {
1909                 callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL);
1910             } catch (RemoteException r) {
1911                 Log.e(TAG, "enableUsbData: failed to call onOperationComplete. opId:"
1912                         + operationId, r);
1913             }
1914             throw e.rethrowFromSystemServer();
1915         }
1916     }
1917 
1918     /**
1919      * Should only be called by {@link UsbPort#enableUsbDataWhileDocked}.
1920      * <p>
1921      * Enables or disables USB data when disabled due to docking event.
1922      *
1923      * @param port USB port for which USB data needs to be enabled.
1924      * @param operationId operationId for the request.
1925      * @param callback callback object to be invoked when the operation is complete.
1926      * @hide
1927      */
1928     @RequiresPermission(Manifest.permission.MANAGE_USB)
enableUsbDataWhileDocked(@onNull UsbPort port, int operationId, IUsbOperationInternal callback)1929     void enableUsbDataWhileDocked(@NonNull UsbPort port, int operationId,
1930             IUsbOperationInternal callback) {
1931         Objects.requireNonNull(port, "enableUsbDataWhileDocked: port must not be null. opId:"
1932                 + operationId);
1933         try {
1934             mService.enableUsbDataWhileDocked(port.getId(), operationId, callback);
1935         } catch (RemoteException e) {
1936             Log.e(TAG, "enableUsbDataWhileDocked: failed. opId:" + operationId, e);
1937             try {
1938                 callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL);
1939             } catch (RemoteException r) {
1940                 Log.e(TAG, "enableUsbDataWhileDocked: failed to call onOperationComplete. opId:"
1941                         + operationId, r);
1942             }
1943             throw e.rethrowFromSystemServer();
1944         }
1945     }
1946 
1947     @GuardedBy("mDisplayPortListenersLock")
1948     @RequiresPermission(Manifest.permission.MANAGE_USB)
registerDisplayPortAltModeEventsIfNeededLocked()1949     private boolean registerDisplayPortAltModeEventsIfNeededLocked() {
1950         DisplayPortAltModeInfoDispatchingListener displayPortDispatchingListener =
1951                 new DisplayPortAltModeInfoDispatchingListener();
1952         try {
1953             if (mService.registerForDisplayPortEvents(displayPortDispatchingListener)) {
1954                 mDisplayPortServiceListener = displayPortDispatchingListener;
1955                 return true;
1956             }
1957             return false;
1958         } catch (RemoteException e) {
1959             throw e.rethrowFromSystemServer();
1960         }
1961     }
1962 
1963     /**
1964      * Registers the given listener to listen for DisplayPort Alt Mode changes.
1965      * <p>
1966      * If this method returns without Exceptions, the caller should ensure to call
1967      * {@link #unregisterDisplayPortAltModeListener} when it no longer requires updates.
1968      *
1969      * @param executor          Executor on which to run the listener.
1970      * @param listener          DisplayPortAltModeInfoListener invoked on DisplayPortAltModeInfo
1971      *                          changes. See {@link #DisplayPortAltModeInfoListener} for listener
1972      *                          details.
1973      *
1974      * @throws IllegalStateException if listener has already been registered previously but not
1975      * unregistered or an unexpected system failure occurs.
1976      *
1977      * @hide
1978      */
1979     @SystemApi
1980     @RequiresPermission(Manifest.permission.MANAGE_USB)
registerDisplayPortAltModeInfoListener( @onNull @allbackExecutor Executor executor, @NonNull DisplayPortAltModeInfoListener listener)1981     public void registerDisplayPortAltModeInfoListener(
1982             @NonNull @CallbackExecutor Executor executor,
1983             @NonNull DisplayPortAltModeInfoListener listener) {
1984         Objects.requireNonNull(executor, "registerDisplayPortAltModeInfoListener: "
1985                 + "executor must not be null.");
1986         Objects.requireNonNull(listener, "registerDisplayPortAltModeInfoListener: "
1987                 + "listener must not be null.");
1988 
1989         synchronized (mDisplayPortListenersLock) {
1990             if (mDisplayPortListeners == null) {
1991                 mDisplayPortListeners = new ArrayMap<DisplayPortAltModeInfoListener,
1992                         Executor>();
1993             }
1994 
1995             if (mDisplayPortServiceListener == null) {
1996                 if (!registerDisplayPortAltModeEventsIfNeededLocked()) {
1997                     throw new IllegalStateException("Unexpected failure registering service "
1998                             + "listener");
1999                 }
2000             }
2001             if (mDisplayPortListeners.containsKey(listener)) {
2002                 throw new IllegalStateException("Listener has already been registered.");
2003             }
2004 
2005             mDisplayPortListeners.put(listener, executor);
2006         }
2007     }
2008 
2009     @GuardedBy("mDisplayPortListenersLock")
2010     @RequiresPermission(Manifest.permission.MANAGE_USB)
unregisterDisplayPortAltModeEventsLocked()2011     private void unregisterDisplayPortAltModeEventsLocked() {
2012         if (mDisplayPortServiceListener != null) {
2013             try {
2014                 mService.unregisterForDisplayPortEvents(mDisplayPortServiceListener);
2015             } catch (RemoteException e) {
2016                 throw e.rethrowFromSystemServer();
2017             } finally {
2018                 // If there was a RemoteException, the system server may have died,
2019                 // and this listener probably became unregistered, so clear it for re-registration.
2020                 mDisplayPortServiceListener = null;
2021             }
2022         }
2023     }
2024 
2025     /**
2026      * Unregisters the given listener if it was previously passed to
2027      * registerDisplayPortAltModeInfoListener.
2028      *
2029      * @param listener          DisplayPortAltModeInfoListener used to register the listener
2030      *                          in registerDisplayPortAltModeInfoListener.
2031      *
2032      * @hide
2033      */
2034     @SystemApi
2035     @RequiresPermission(Manifest.permission.MANAGE_USB)
unregisterDisplayPortAltModeInfoListener( @onNull DisplayPortAltModeInfoListener listener)2036     public void unregisterDisplayPortAltModeInfoListener(
2037             @NonNull DisplayPortAltModeInfoListener listener) {
2038         synchronized (mDisplayPortListenersLock) {
2039             if (mDisplayPortListeners == null) {
2040                 return;
2041             }
2042             mDisplayPortListeners.remove(listener);
2043             if (mDisplayPortListeners.isEmpty()) {
2044                 unregisterDisplayPortAltModeEventsLocked();
2045             }
2046         }
2047         return;
2048     }
2049 
2050     /**
2051      * Sets the component that will handle USB device connection.
2052      * <p>
2053      * Setting component allows to specify external USB host manager to handle use cases, where
2054      * selection dialog for an activity that will handle USB device is undesirable.
2055      * Only system components can call this function, as it requires the MANAGE_USB permission.
2056      *
2057      * @param usbDeviceConnectionHandler The component to handle usb connections,
2058      * {@code null} to unset.
2059      *
2060      * @hide
2061      */
setUsbDeviceConnectionHandler(@ullable ComponentName usbDeviceConnectionHandler)2062     public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) {
2063         try {
2064             mService.setUsbDeviceConnectionHandler(usbDeviceConnectionHandler);
2065         } catch (RemoteException e) {
2066             throw e.rethrowFromSystemServer();
2067         }
2068     }
2069 
2070     /**
2071      * Returns whether the given functions are valid inputs to UsbManager.
2072      * Currently the empty functions or any of MTP, PTP, RNDIS, MIDI, NCM, UVC are accepted.
2073      *
2074      * Only one function may be set at a time, except for RNDIS and NCM, which can be set together
2075      * because from a user perspective they are the same function (tethering).
2076      *
2077      * @return Whether the mask is settable.
2078      *
2079      * @hide
2080      */
areSettableFunctions(long functions)2081     public static boolean areSettableFunctions(long functions) {
2082         return functions == FUNCTION_NONE
2083                 || ((~SETTABLE_FUNCTIONS & functions) == 0
2084                         && ((Long.bitCount(functions) == 1)
2085                                 || (functions == (FUNCTION_RNDIS | FUNCTION_NCM))));
2086     }
2087 
2088     /**
2089      * Converts the given function mask to string. Maintains ordering with respect to init scripts.
2090      *
2091      * @return String representation of given mask
2092      *
2093      * @hide
2094      */
usbFunctionsToString(long functions)2095     public static String usbFunctionsToString(long functions) {
2096         StringJoiner joiner = new StringJoiner(",");
2097         if ((functions & FUNCTION_MTP) != 0) {
2098             joiner.add(UsbManager.USB_FUNCTION_MTP);
2099         }
2100         if ((functions & FUNCTION_PTP) != 0) {
2101             joiner.add(UsbManager.USB_FUNCTION_PTP);
2102         }
2103         if ((functions & FUNCTION_RNDIS) != 0) {
2104             joiner.add(UsbManager.USB_FUNCTION_RNDIS);
2105         }
2106         if ((functions & FUNCTION_MIDI) != 0) {
2107             joiner.add(UsbManager.USB_FUNCTION_MIDI);
2108         }
2109         if ((functions & FUNCTION_ACCESSORY) != 0) {
2110             joiner.add(UsbManager.USB_FUNCTION_ACCESSORY);
2111         }
2112         if ((functions & FUNCTION_AUDIO_SOURCE) != 0) {
2113             joiner.add(UsbManager.USB_FUNCTION_AUDIO_SOURCE);
2114         }
2115         if ((functions & FUNCTION_NCM) != 0) {
2116             joiner.add(UsbManager.USB_FUNCTION_NCM);
2117         }
2118         if ((functions & FUNCTION_UVC) != 0) {
2119             joiner.add(UsbManager.USB_FUNCTION_UVC);
2120         }
2121         if ((functions & FUNCTION_ADB) != 0) {
2122             joiner.add(UsbManager.USB_FUNCTION_ADB);
2123         }
2124         return joiner.toString();
2125     }
2126 
2127     /**
2128      * Parses a string of usb functions that are comma separated.
2129      *
2130      * @return A mask of all valid functions in the string
2131      *
2132      * @hide
2133      */
usbFunctionsFromString(String functions)2134     public static long usbFunctionsFromString(String functions) {
2135         if (functions == null || functions.equals(USB_FUNCTION_NONE)) {
2136             return FUNCTION_NONE;
2137         }
2138         long ret = 0;
2139         for (String function : functions.split(",")) {
2140             if (FUNCTION_NAME_TO_CODE.containsKey(function)) {
2141                 ret |= FUNCTION_NAME_TO_CODE.get(function);
2142             } else if (function.length() > 0) {
2143                 throw new IllegalArgumentException("Invalid usb function " + functions);
2144             }
2145         }
2146         return ret;
2147     }
2148 
2149     /**
2150      * Converts the given integer of USB speed to corresponding bandwidth.
2151      *
2152      * @return a value of USB bandwidth
2153      *
2154      * @hide
2155      */
usbSpeedToBandwidth(int speed)2156     public static int usbSpeedToBandwidth(int speed) {
2157         switch (speed) {
2158             case UsbSpeed.USB4_GEN3_40Gb:
2159                 return USB_DATA_TRANSFER_RATE_40G;
2160             case UsbSpeed.USB4_GEN3_20Gb:
2161                 return USB_DATA_TRANSFER_RATE_20G;
2162             case UsbSpeed.USB4_GEN2_20Gb:
2163                 return USB_DATA_TRANSFER_RATE_20G;
2164             case UsbSpeed.USB4_GEN2_10Gb:
2165                 return USB_DATA_TRANSFER_RATE_10G;
2166             case UsbSpeed.SUPERSPEED_20Gb:
2167                 return USB_DATA_TRANSFER_RATE_20G;
2168             case UsbSpeed.SUPERSPEED_10Gb:
2169                 return USB_DATA_TRANSFER_RATE_10G;
2170             case UsbSpeed.SUPERSPEED:
2171                 return USB_DATA_TRANSFER_RATE_5G;
2172             case UsbSpeed.HIGHSPEED:
2173                 return USB_DATA_TRANSFER_RATE_HIGH_SPEED;
2174             case UsbSpeed.FULLSPEED:
2175                 return USB_DATA_TRANSFER_RATE_FULL_SPEED;
2176             case UsbSpeed.LOWSPEED:
2177                 return USB_DATA_TRANSFER_RATE_LOW_SPEED;
2178             default:
2179                 return USB_DATA_TRANSFER_RATE_UNKNOWN;
2180         }
2181     }
2182 
2183     /**
2184      * Converts the given usb gadgdet hal version to String
2185      *
2186      * @return String representation of Usb Gadget Hal Version
2187      *
2188      * @hide
2189      */
usbGadgetHalVersionToString(int version)2190     public static @NonNull String usbGadgetHalVersionToString(int version) {
2191         String halVersion;
2192 
2193         if (version == GADGET_HAL_V2_0) {
2194             halVersion = GADGET_HAL_VERSION_2_0;
2195         } else if (version == GADGET_HAL_V1_2) {
2196             halVersion = GADGET_HAL_VERSION_1_2;
2197         } else if (version == GADGET_HAL_V1_1) {
2198             halVersion = GADGET_HAL_VERSION_1_1;
2199         } else if (version == GADGET_HAL_V1_0) {
2200             halVersion = GADGET_HAL_VERSION_1_0;
2201         } else {
2202             halVersion = GADGET_HAL_UNKNOWN;
2203         }
2204 
2205         return halVersion;
2206     }
2207 }
2208