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