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