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 android.Manifest;
21 import android.annotation.Nullable;
22 import android.annotation.RequiresFeature;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SdkConstant;
25 import android.annotation.SdkConstant.SdkConstantType;
26 import android.annotation.SystemApi;
27 import android.annotation.SystemService;
28 import android.app.PendingIntent;
29 import android.content.ComponentName;
30 import android.content.Context;
31 import android.content.pm.PackageManager;
32 import android.content.pm.PackageManager.NameNotFoundException;
33 import android.hardware.usb.gadget.V1_0.GadgetFunction;
34 import android.os.Bundle;
35 import android.os.ParcelFileDescriptor;
36 import android.os.Process;
37 import android.os.RemoteException;
38 import android.util.Log;
39 
40 import com.android.internal.util.Preconditions;
41 
42 import java.util.HashMap;
43 import java.util.Map;
44 import java.util.StringJoiner;
45 
46 /**
47  * This class allows you to access the state of USB and communicate with USB devices.
48  * Currently only host mode is supported in the public API.
49  *
50  * <div class="special reference">
51  * <h3>Developer Guides</h3>
52  * <p>For more information about communicating with USB hardware, read the
53  * <a href="{@docRoot}guide/topics/connectivity/usb/index.html">USB developer guide</a>.</p>
54  * </div>
55  */
56 @SystemService(Context.USB_SERVICE)
57 public class UsbManager {
58     private static final String TAG = "UsbManager";
59 
60    /**
61      * Broadcast Action:  A sticky broadcast for USB state change events when in device mode.
62      *
63      * This is a sticky broadcast for clients that includes USB connected/disconnected state,
64      * <ul>
65      * <li> {@link #USB_CONNECTED} boolean indicating whether USB is connected or disconnected.
66      * <li> {@link #USB_HOST_CONNECTED} boolean indicating whether USB is connected or
67      *     disconnected as host.
68      * <li> {@link #USB_CONFIGURED} boolean indicating whether USB is configured.
69      * currently zero if not configured, one for configured.
70      * <li> {@link #USB_FUNCTION_ADB} boolean extra indicating whether the
71      * adb function is enabled
72      * <li> {@link #USB_FUNCTION_RNDIS} boolean extra indicating whether the
73      * RNDIS ethernet function is enabled
74      * <li> {@link #USB_FUNCTION_MTP} boolean extra indicating whether the
75      * MTP function is enabled
76      * <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
77      * PTP function is enabled
78      * <li> {@link #USB_FUNCTION_ACCESSORY} boolean extra indicating whether the
79      * accessory function is enabled
80      * <li> {@link #USB_FUNCTION_AUDIO_SOURCE} boolean extra indicating whether the
81      * audio source function is enabled
82      * <li> {@link #USB_FUNCTION_MIDI} boolean extra indicating whether the
83      * MIDI function is enabled
84      * </ul>
85      * If the sticky intent has not been found, that indicates USB is disconnected,
86      * USB is not configued, MTP function is enabled, and all the other functions are disabled.
87      *
88      * {@hide}
89      */
90     public static final String ACTION_USB_STATE =
91             "android.hardware.usb.action.USB_STATE";
92 
93     /**
94      * Broadcast Action: A broadcast for USB port changes.
95      *
96      * This intent is sent when a USB port is added, removed, or changes state.
97      * <ul>
98      * <li> {@link #EXTRA_PORT} containing the {@link android.hardware.usb.UsbPort}
99      * for the port.
100      * <li> {@link #EXTRA_PORT_STATUS} containing the {@link android.hardware.usb.UsbPortStatus}
101      * for the port, or null if the port has been removed
102      * </ul>
103      *
104      * @hide
105      */
106     public static final String ACTION_USB_PORT_CHANGED =
107             "android.hardware.usb.action.USB_PORT_CHANGED";
108 
109    /**
110      * Activity intent sent when user attaches a USB device.
111      *
112      * This intent is sent when a USB device is attached to the USB bus when in host mode.
113      * <ul>
114      * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
115      * for the attached device
116      * </ul>
117      */
118     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
119     public static final String ACTION_USB_DEVICE_ATTACHED =
120             "android.hardware.usb.action.USB_DEVICE_ATTACHED";
121 
122    /**
123      * Broadcast Action:  A broadcast for USB device detached event.
124      *
125      * This intent is sent when a USB device is detached from the USB bus when in host mode.
126      * <ul>
127      * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.usb.UsbDevice}
128      * for the detached device
129      * </ul>
130      */
131     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
132     public static final String ACTION_USB_DEVICE_DETACHED =
133             "android.hardware.usb.action.USB_DEVICE_DETACHED";
134 
135    /**
136      * Activity intent sent when user attaches a USB accessory.
137      *
138      * <ul>
139      * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.usb.UsbAccessory}
140      * for the attached accessory
141      * </ul>
142      */
143     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
144     public static final String ACTION_USB_ACCESSORY_ATTACHED =
145             "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
146 
147    /**
148      * Broadcast Action:  A broadcast for USB accessory detached event.
149      *
150      * This intent is sent when a USB accessory is detached.
151      * <ul>
152      * <li> {@link #EXTRA_ACCESSORY} containing the {@link UsbAccessory}
153      * for the attached accessory that was detached
154      * </ul>
155      */
156     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
157     public static final String ACTION_USB_ACCESSORY_DETACHED =
158             "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
159 
160     /**
161      * Boolean extra indicating whether USB is connected or disconnected.
162      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
163      *
164      * {@hide}
165      */
166     public static final String USB_CONNECTED = "connected";
167 
168     /**
169      * Boolean extra indicating whether USB is connected or disconnected as host.
170      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
171      *
172      * {@hide}
173      */
174     public static final String USB_HOST_CONNECTED = "host_connected";
175 
176     /**
177      * Boolean extra indicating whether USB is configured.
178      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
179      *
180      * {@hide}
181      */
182     public static final String USB_CONFIGURED = "configured";
183 
184     /**
185      * Boolean extra indicating whether confidential user data, such as photos, should be
186      * made available on the USB connection. This variable will only be set when the user
187      * has explicitly asked for this data to be unlocked.
188      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
189      *
190      * {@hide}
191      */
192     public static final String USB_DATA_UNLOCKED = "unlocked";
193 
194     /**
195      * A placeholder indicating that no USB function is being specified.
196      * Used for compatibility with old init scripts to indicate no functions vs. charging function.
197      *
198      * {@hide}
199      */
200     public static final String USB_FUNCTION_NONE = "none";
201 
202     /**
203      * Name of the adb USB function.
204      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
205      *
206      * {@hide}
207      */
208     public static final String USB_FUNCTION_ADB = "adb";
209 
210     /**
211      * Name of the RNDIS ethernet USB function.
212      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
213      *
214      * {@hide}
215      */
216     public static final String USB_FUNCTION_RNDIS = "rndis";
217 
218     /**
219      * Name of the MTP USB function.
220      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
221      *
222      * {@hide}
223      */
224     public static final String USB_FUNCTION_MTP = "mtp";
225 
226     /**
227      * Name of the PTP USB function.
228      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
229      *
230      * {@hide}
231      */
232     public static final String USB_FUNCTION_PTP = "ptp";
233 
234     /**
235      * Name of the audio source USB function.
236      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
237      *
238      * {@hide}
239      */
240     public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
241 
242     /**
243      * Name of the MIDI USB function.
244      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
245      *
246      * {@hide}
247      */
248     public static final String USB_FUNCTION_MIDI = "midi";
249 
250     /**
251      * Name of the Accessory USB function.
252      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
253      *
254      * {@hide}
255      */
256     public static final String USB_FUNCTION_ACCESSORY = "accessory";
257 
258     /**
259      * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
260      * containing the {@link UsbPort} object for the port.
261      *
262      * @hide
263      */
264     public static final String EXTRA_PORT = "port";
265 
266     /**
267      * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
268      * containing the {@link UsbPortStatus} object for the port, or null if the port
269      * was removed.
270      *
271      * @hide
272      */
273     public static final String EXTRA_PORT_STATUS = "portStatus";
274 
275     /**
276      * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} and
277      * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts
278      * containing the {@link UsbDevice} object for the device.
279      */
280     public static final String EXTRA_DEVICE = "device";
281 
282     /**
283      * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} and
284      * {@link #ACTION_USB_ACCESSORY_DETACHED} broadcasts
285      * containing the {@link UsbAccessory} object for the accessory.
286      */
287     public static final String EXTRA_ACCESSORY = "accessory";
288 
289     /**
290      * Name of extra added to the {@link android.app.PendingIntent}
291      * passed into {@link #requestPermission(UsbDevice, PendingIntent)}
292      * or {@link #requestPermission(UsbAccessory, PendingIntent)}
293      * containing a boolean value indicating whether the user granted permission or not.
294      */
295     public static final String EXTRA_PERMISSION_GRANTED = "permission";
296 
297     /**
298      * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)}
299      * {@hide}
300      */
301     public static final long FUNCTION_NONE = 0;
302 
303     /**
304      * Code for the mtp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
305      * {@hide}
306      */
307     public static final long FUNCTION_MTP = GadgetFunction.MTP;
308 
309     /**
310      * Code for the ptp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
311      * {@hide}
312      */
313     public static final long FUNCTION_PTP = GadgetFunction.PTP;
314 
315     /**
316      * Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
317      * {@hide}
318      */
319     public static final long FUNCTION_RNDIS = GadgetFunction.RNDIS;
320 
321     /**
322      * Code for the midi usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
323      * {@hide}
324      */
325     public static final long FUNCTION_MIDI = GadgetFunction.MIDI;
326 
327     /**
328      * Code for the accessory usb function.
329      * {@hide}
330      */
331     public static final long FUNCTION_ACCESSORY = GadgetFunction.ACCESSORY;
332 
333     /**
334      * Code for the audio source usb function.
335      * {@hide}
336      */
337     public static final long FUNCTION_AUDIO_SOURCE = GadgetFunction.AUDIO_SOURCE;
338 
339     /**
340      * Code for the adb usb function.
341      * {@hide}
342      */
343     public static final long FUNCTION_ADB = GadgetFunction.ADB;
344 
345     private static final long SETTABLE_FUNCTIONS = FUNCTION_MTP | FUNCTION_PTP | FUNCTION_RNDIS
346             | FUNCTION_MIDI;
347 
348     private static final Map<String, Long> FUNCTION_NAME_TO_CODE = new HashMap<>();
349 
350     static {
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP)351         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_PTP, FUNCTION_PTP)352         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_PTP, FUNCTION_PTP);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_RNDIS, FUNCTION_RNDIS)353         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_RNDIS, FUNCTION_RNDIS);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MIDI, FUNCTION_MIDI)354         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MIDI, FUNCTION_MIDI);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ACCESSORY, FUNCTION_ACCESSORY)355         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ACCESSORY, FUNCTION_ACCESSORY);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_AUDIO_SOURCE, FUNCTION_AUDIO_SOURCE)356         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_AUDIO_SOURCE, FUNCTION_AUDIO_SOURCE);
FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ADB, FUNCTION_ADB)357         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ADB, FUNCTION_ADB);
358     }
359 
360     private final Context mContext;
361     private final IUsbManager mService;
362 
363     /**
364      * {@hide}
365      */
UsbManager(Context context, IUsbManager service)366     public UsbManager(Context context, IUsbManager service) {
367         mContext = context;
368         mService = service;
369     }
370 
371     /**
372      * Returns a HashMap containing all USB devices currently attached.
373      * USB device name is the key for the returned HashMap.
374      * The result will be empty if no devices are attached, or if
375      * USB host mode is inactive or unsupported.
376      *
377      * @return HashMap containing all connected USB devices.
378      */
379     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
getDeviceList()380     public HashMap<String,UsbDevice> getDeviceList() {
381         HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
382         if (mService == null) {
383             return result;
384         }
385         Bundle bundle = new Bundle();
386         try {
387             mService.getDeviceList(bundle);
388             for (String name : bundle.keySet()) {
389                 result.put(name, (UsbDevice)bundle.get(name));
390             }
391             return result;
392         } catch (RemoteException e) {
393             throw e.rethrowFromSystemServer();
394         }
395     }
396 
397     /**
398      * Opens the device so it can be used to send and receive
399      * data using {@link android.hardware.usb.UsbRequest}.
400      *
401      * @param device the device to open
402      * @return a {@link UsbDeviceConnection}, or {@code null} if open failed
403      */
404     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
openDevice(UsbDevice device)405     public UsbDeviceConnection openDevice(UsbDevice device) {
406         try {
407             String deviceName = device.getDeviceName();
408             ParcelFileDescriptor pfd = mService.openDevice(deviceName, mContext.getPackageName());
409             if (pfd != null) {
410                 UsbDeviceConnection connection = new UsbDeviceConnection(device);
411                 boolean result = connection.open(deviceName, pfd, mContext);
412                 pfd.close();
413                 if (result) {
414                     return connection;
415                 }
416             }
417         } catch (Exception e) {
418             Log.e(TAG, "exception in UsbManager.openDevice", e);
419         }
420         return null;
421     }
422 
423     /**
424      * Returns a list of currently attached USB accessories.
425      * (in the current implementation there can be at most one)
426      *
427      * @return list of USB accessories, or null if none are attached.
428      */
429     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
getAccessoryList()430     public UsbAccessory[] getAccessoryList() {
431         if (mService == null) {
432             return null;
433         }
434         try {
435             UsbAccessory accessory = mService.getCurrentAccessory();
436             if (accessory == null) {
437                 return null;
438             } else {
439                 return new UsbAccessory[] { accessory };
440             }
441         } catch (RemoteException e) {
442             throw e.rethrowFromSystemServer();
443         }
444     }
445 
446     /**
447      * Opens a file descriptor for reading and writing data to the USB accessory.
448      *
449      * <p>If data is read from the {@link java.io.InputStream} created from this file descriptor all
450      * data of a USB transfer should be read at once. If only a partial request is read the rest of
451      * the transfer is dropped.
452      *
453      * @param accessory the USB accessory to open
454      * @return file descriptor, or null if the accessory could not be opened.
455      */
456     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
openAccessory(UsbAccessory accessory)457     public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
458         try {
459             return mService.openAccessory(accessory);
460         } catch (RemoteException e) {
461             throw e.rethrowFromSystemServer();
462         }
463     }
464 
465     /**
466      * Gets the functionfs control file descriptor for the given function, with
467      * the usb descriptors and strings already written. The file descriptor is used
468      * by the function implementation to handle events and control requests.
469      *
470      * @param function to get control fd for. Currently {@link #FUNCTION_MTP} and
471      * {@link #FUNCTION_PTP} are supported.
472      * @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found.
473      *
474      * {@hide}
475      */
getControlFd(long function)476     public ParcelFileDescriptor getControlFd(long function) {
477         try {
478             return mService.getControlFd(function);
479         } catch (RemoteException e) {
480             throw e.rethrowFromSystemServer();
481         }
482     }
483 
484     /**
485      * Returns true if the caller has permission to access the device.
486      * Permission might have been granted temporarily via
487      * {@link #requestPermission(UsbDevice, PendingIntent)} or
488      * by the user choosing the caller as the default application for the device.
489      * Permission for USB devices of class {@link UsbConstants#USB_CLASS_VIDEO} for clients that
490      * target SDK {@link android.os.Build.VERSION_CODES#P} and above can be granted only if they
491      * have additionally the {@link android.Manifest.permission#CAMERA} permission.
492      *
493      * @param device to check permissions for
494      * @return true if caller has permission
495      */
496     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
hasPermission(UsbDevice device)497     public boolean hasPermission(UsbDevice device) {
498         if (mService == null) {
499             return false;
500         }
501         try {
502             return mService.hasDevicePermission(device, mContext.getPackageName());
503         } catch (RemoteException e) {
504             throw e.rethrowFromSystemServer();
505         }
506     }
507 
508     /**
509      * Returns true if the caller has permission to access the accessory.
510      * Permission might have been granted temporarily via
511      * {@link #requestPermission(UsbAccessory, PendingIntent)} or
512      * by the user choosing the caller as the default application for the accessory.
513      *
514      * @param accessory to check permissions for
515      * @return true if caller has permission
516      */
517     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
hasPermission(UsbAccessory accessory)518     public boolean hasPermission(UsbAccessory accessory) {
519         if (mService == null) {
520             return false;
521         }
522         try {
523             return mService.hasAccessoryPermission(accessory);
524         } catch (RemoteException e) {
525             throw e.rethrowFromSystemServer();
526         }
527     }
528 
529     /**
530      * Requests temporary permission for the given package to access the device.
531      * This may result in a system dialog being displayed to the user
532      * if permission had not already been granted.
533      * Success or failure is returned via the {@link android.app.PendingIntent} pi.
534      * If successful, this grants the caller permission to access the device only
535      * until the device is disconnected.
536      *
537      * The following extras will be added to pi:
538      * <ul>
539      * <li> {@link #EXTRA_DEVICE} containing the device passed into this call
540      * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
541      * permission was granted by the user
542      * </ul>
543      *
544      * Permission for USB devices of class {@link UsbConstants#USB_CLASS_VIDEO} for clients that
545      * target SDK {@link android.os.Build.VERSION_CODES#P} and above can be granted only if they
546      * have additionally the {@link android.Manifest.permission#CAMERA} permission.
547      *
548      * @param device to request permissions for
549      * @param pi PendingIntent for returning result
550      */
551     @RequiresFeature(PackageManager.FEATURE_USB_HOST)
requestPermission(UsbDevice device, PendingIntent pi)552     public void requestPermission(UsbDevice device, PendingIntent pi) {
553         try {
554             mService.requestDevicePermission(device, mContext.getPackageName(), pi);
555         } catch (RemoteException e) {
556             throw e.rethrowFromSystemServer();
557         }
558     }
559 
560     /**
561      * Requests temporary permission for the given package to access the accessory.
562      * This may result in a system dialog being displayed to the user
563      * if permission had not already been granted.
564      * Success or failure is returned via the {@link android.app.PendingIntent} pi.
565      * If successful, this grants the caller permission to access the accessory only
566      * until the device is disconnected.
567      *
568      * The following extras will be added to pi:
569      * <ul>
570      * <li> {@link #EXTRA_ACCESSORY} containing the accessory passed into this call
571      * <li> {@link #EXTRA_PERMISSION_GRANTED} containing boolean indicating whether
572      * permission was granted by the user
573      * </ul>
574      *
575      * @param accessory to request permissions for
576      * @param pi PendingIntent for returning result
577      */
578     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
requestPermission(UsbAccessory accessory, PendingIntent pi)579     public void requestPermission(UsbAccessory accessory, PendingIntent pi) {
580         try {
581             mService.requestAccessoryPermission(accessory, mContext.getPackageName(), pi);
582         } catch (RemoteException e) {
583             throw e.rethrowFromSystemServer();
584         }
585     }
586 
587     /**
588      * Grants permission for USB device without showing system dialog.
589      * Only system components can call this function.
590      * @param device to request permissions for
591      *
592      * {@hide}
593      */
grantPermission(UsbDevice device)594     public void grantPermission(UsbDevice device) {
595         grantPermission(device, Process.myUid());
596     }
597 
598     /**
599      * Grants permission for USB device to given uid without showing system dialog.
600      * Only system components can call this function.
601      * @param device to request permissions for
602      * @uid uid to give permission
603      *
604      * {@hide}
605      */
grantPermission(UsbDevice device, int uid)606     public void grantPermission(UsbDevice device, int uid) {
607         try {
608             mService.grantDevicePermission(device, uid);
609         } catch (RemoteException e) {
610             throw e.rethrowFromSystemServer();
611         }
612     }
613 
614     /**
615      * Grants permission to specified package for USB device without showing system dialog.
616      * Only system components can call this function, as it requires the MANAGE_USB permission.
617      * @param device to request permissions for
618      * @param packageName of package to grant permissions
619      *
620      * {@hide}
621      */
622     @SystemApi
623     @RequiresPermission(Manifest.permission.MANAGE_USB)
grantPermission(UsbDevice device, String packageName)624     public void grantPermission(UsbDevice device, String packageName) {
625         try {
626             int uid = mContext.getPackageManager()
627                 .getPackageUidAsUser(packageName, mContext.getUserId());
628             grantPermission(device, uid);
629         } catch (NameNotFoundException e) {
630             Log.e(TAG, "Package " + packageName + " not found.", e);
631         }
632     }
633 
634     /**
635      * Returns true if the specified USB function is currently enabled when in device mode.
636      * <p>
637      * USB functions represent interfaces which are published to the host to access
638      * services offered by the device.
639      * </p>
640      *
641      * @deprecated use getCurrentFunctions() instead.
642      * @param function name of the USB function
643      * @return true if the USB function is enabled
644      *
645      * {@hide}
646      */
647     @Deprecated
isFunctionEnabled(String function)648     public boolean isFunctionEnabled(String function) {
649         try {
650             return mService.isFunctionEnabled(function);
651         } catch (RemoteException e) {
652             throw e.rethrowFromSystemServer();
653         }
654     }
655 
656     /**
657      * Sets the current USB functions when in device mode.
658      * <p>
659      * USB functions represent interfaces which are published to the host to access
660      * services offered by the device.
661      * </p><p>
662      * This method is intended to select among primary USB functions.  The system may
663      * automatically activate additional functions such as {@link #USB_FUNCTION_ADB}
664      * or {@link #USB_FUNCTION_ACCESSORY} based on other settings and states.
665      * </p><p>
666      * An argument of 0 indicates that the device is charging, and can pick any
667      * appropriate function for that purpose.
668      * </p><p>
669      * Note: This function is asynchronous and may fail silently without applying
670      * the requested changes.
671      * </p>
672      *
673      * @param functions the USB function(s) to set, as a bitwise mask.
674      *                  Must satisfy {@link UsbManager#areSettableFunctions}
675      *
676      * {@hide}
677      */
setCurrentFunctions(long functions)678     public void setCurrentFunctions(long functions) {
679         try {
680             mService.setCurrentFunctions(functions);
681         } catch (RemoteException e) {
682             throw e.rethrowFromSystemServer();
683         }
684     }
685 
686     /**
687      * Sets the current USB functions when in device mode.
688      *
689      * @deprecated use setCurrentFunctions(long) instead.
690      * @param functions the USB function(s) to set.
691      * @param usbDataUnlocked unused
692 
693      * {@hide}
694      */
695     @Deprecated
setCurrentFunction(String functions, boolean usbDataUnlocked)696     public void setCurrentFunction(String functions, boolean usbDataUnlocked) {
697         try {
698             mService.setCurrentFunction(functions, usbDataUnlocked);
699         } catch (RemoteException e) {
700             throw e.rethrowFromSystemServer();
701         }
702     }
703 
704     /**
705      * Returns the current USB functions in device mode.
706      * <p>
707      * This function returns the state of primary USB functions and can return a
708      * mask containing any usb function(s) except for ADB.
709      * </p>
710      *
711      * @return The currently enabled functions, in a bitwise mask.
712      * A zero mask indicates that the current function is the charging function.
713      *
714      * {@hide}
715      */
getCurrentFunctions()716     public long getCurrentFunctions() {
717         try {
718             return mService.getCurrentFunctions();
719         } catch (RemoteException e) {
720             throw e.rethrowFromSystemServer();
721         }
722     }
723 
724     /**
725      * Sets the screen unlocked functions, which are persisted and set as the current functions
726      * whenever the screen is unlocked.
727      * <p>
728      * A zero mask has the effect of switching off this feature, so functions
729      * no longer change on screen unlock.
730      * </p><p>
731      * Note: When the screen is on, this method will apply given functions as current functions,
732      * which is asynchronous and may fail silently without applying the requested changes.
733      * </p>
734      *
735      * @param functions functions to set, in a bitwise mask.
736      *                  Must satisfy {@link UsbManager#areSettableFunctions}
737      *
738      * {@hide}
739      */
setScreenUnlockedFunctions(long functions)740     public void setScreenUnlockedFunctions(long functions) {
741         try {
742             mService.setScreenUnlockedFunctions(functions);
743         } catch (RemoteException e) {
744             throw e.rethrowFromSystemServer();
745         }
746     }
747 
748     /**
749      * Gets the current screen unlocked functions.
750      *
751      * @return The currently set screen enabled functions.
752      * A zero mask indicates that the screen unlocked functions feature is not enabled.
753      *
754      * {@hide}
755      */
getScreenUnlockedFunctions()756     public long getScreenUnlockedFunctions() {
757         try {
758             return mService.getScreenUnlockedFunctions();
759         } catch (RemoteException e) {
760             throw e.rethrowFromSystemServer();
761         }
762     }
763 
764     /**
765      * Returns a list of physical USB ports on the device.
766      * <p>
767      * This list is guaranteed to contain all dual-role USB Type C ports but it might
768      * be missing other ports depending on whether the kernel USB drivers have been
769      * updated to publish all of the device's ports through the new "dual_role_usb"
770      * device class (which supports all types of ports despite its name).
771      * </p>
772      *
773      * @return The list of USB ports, or null if none.
774      *
775      * @hide
776      */
getPorts()777     public UsbPort[] getPorts() {
778         if (mService == null) {
779             return null;
780         }
781         try {
782             return mService.getPorts();
783         } catch (RemoteException e) {
784             throw e.rethrowFromSystemServer();
785         }
786     }
787 
788     /**
789      * Gets the status of the specified USB port.
790      *
791      * @param port The port to query.
792      * @return The status of the specified USB port, or null if unknown.
793      *
794      * @hide
795      */
getPortStatus(UsbPort port)796     public UsbPortStatus getPortStatus(UsbPort port) {
797         Preconditions.checkNotNull(port, "port must not be null");
798 
799         try {
800             return mService.getPortStatus(port.getId());
801         } catch (RemoteException e) {
802             throw e.rethrowFromSystemServer();
803         }
804     }
805 
806     /**
807      * Sets the desired role combination of the port.
808      * <p>
809      * The supported role combinations depend on what is connected to the port and may be
810      * determined by consulting
811      * {@link UsbPortStatus#isRoleCombinationSupported UsbPortStatus.isRoleCombinationSupported}.
812      * </p><p>
813      * Note: This function is asynchronous and may fail silently without applying
814      * the requested changes.  If this function does cause a status change to occur then
815      * a {@link #ACTION_USB_PORT_CHANGED} broadcast will be sent.
816      * </p>
817      *
818      * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
819      * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
820      * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST}
821      * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
822      *
823      * @hide
824      */
setPortRoles(UsbPort port, int powerRole, int dataRole)825     public void setPortRoles(UsbPort port, int powerRole, int dataRole) {
826         Preconditions.checkNotNull(port, "port must not be null");
827         UsbPort.checkRoles(powerRole, dataRole);
828 
829         Log.d(TAG, "setPortRoles Package:" + mContext.getPackageName());
830         try {
831             mService.setPortRoles(port.getId(), powerRole, dataRole);
832         } catch (RemoteException e) {
833             throw e.rethrowFromSystemServer();
834         }
835     }
836 
837     /**
838      * Sets the component that will handle USB device connection.
839      * <p>
840      * Setting component allows to specify external USB host manager to handle use cases, where
841      * selection dialog for an activity that will handle USB device is undesirable.
842      * Only system components can call this function, as it requires the MANAGE_USB permission.
843      *
844      * @param usbDeviceConnectionHandler The component to handle usb connections,
845      * {@code null} to unset.
846      *
847      * {@hide}
848      */
setUsbDeviceConnectionHandler(@ullable ComponentName usbDeviceConnectionHandler)849     public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) {
850         try {
851             mService.setUsbDeviceConnectionHandler(usbDeviceConnectionHandler);
852         } catch (RemoteException e) {
853             throw e.rethrowFromSystemServer();
854         }
855     }
856 
857     /**
858      * Returns whether the given functions are valid inputs to UsbManager.
859      * Currently the empty functions or any of MTP, PTP, RNDIS, MIDI are accepted.
860      *
861      * @return Whether the mask is settable.
862      *
863      * {@hide}
864      */
areSettableFunctions(long functions)865     public static boolean areSettableFunctions(long functions) {
866         return functions == FUNCTION_NONE
867                 || ((~SETTABLE_FUNCTIONS & functions) == 0 && Long.bitCount(functions) == 1);
868     }
869 
870     /**
871      * Converts the given function mask to string. Maintains ordering with respect to init scripts.
872      *
873      * @return String representation of given mask
874      *
875      * {@hide}
876      */
usbFunctionsToString(long functions)877     public static String usbFunctionsToString(long functions) {
878         StringJoiner joiner = new StringJoiner(",");
879         if ((functions & FUNCTION_MTP) != 0) {
880             joiner.add(UsbManager.USB_FUNCTION_MTP);
881         }
882         if ((functions & FUNCTION_PTP) != 0) {
883             joiner.add(UsbManager.USB_FUNCTION_PTP);
884         }
885         if ((functions & FUNCTION_RNDIS) != 0) {
886             joiner.add(UsbManager.USB_FUNCTION_RNDIS);
887         }
888         if ((functions & FUNCTION_MIDI) != 0) {
889             joiner.add(UsbManager.USB_FUNCTION_MIDI);
890         }
891         if ((functions & FUNCTION_ACCESSORY) != 0) {
892             joiner.add(UsbManager.USB_FUNCTION_ACCESSORY);
893         }
894         if ((functions & FUNCTION_AUDIO_SOURCE) != 0) {
895             joiner.add(UsbManager.USB_FUNCTION_AUDIO_SOURCE);
896         }
897         if ((functions & FUNCTION_ADB) != 0) {
898             joiner.add(UsbManager.USB_FUNCTION_ADB);
899         }
900         return joiner.toString();
901     }
902 
903     /**
904      * Parses a string of usb functions that are comma separated.
905      *
906      * @return A mask of all valid functions in the string
907      *
908      * {@hide}
909      */
usbFunctionsFromString(String functions)910     public static long usbFunctionsFromString(String functions) {
911         if (functions == null || functions.equals(USB_FUNCTION_NONE)) {
912             return FUNCTION_NONE;
913         }
914         long ret = 0;
915         for (String function : functions.split(",")) {
916             if (FUNCTION_NAME_TO_CODE.containsKey(function)) {
917                 ret |= FUNCTION_NAME_TO_CODE.get(function);
918             } else if (function.length() > 0) {
919                 throw new IllegalArgumentException("Invalid usb function " + functions);
920             }
921         }
922         return ret;
923     }
924 }
925