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