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