1 /* 2 * Copyright (C) 2011 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 an 14 * limitations under the License. 15 */ 16 17 package com.android.server.usb; 18 19 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE; 20 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_HOST; 21 import static android.hardware.usb.UsbPortStatus.MODE_AUDIO_ACCESSORY; 22 import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK; 23 import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE; 24 25 import static com.android.internal.usb.DumpUtils.writeAccessory; 26 import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; 27 28 import android.app.ActivityManager; 29 import android.app.KeyguardManager; 30 import android.app.Notification; 31 import android.app.NotificationChannel; 32 import android.app.NotificationManager; 33 import android.app.PendingIntent; 34 import android.content.BroadcastReceiver; 35 import android.content.ComponentName; 36 import android.content.ContentResolver; 37 import android.content.Context; 38 import android.content.Intent; 39 import android.content.IntentFilter; 40 import android.content.ServiceConnection; 41 import android.content.SharedPreferences; 42 import android.content.pm.PackageManager; 43 import android.content.res.Resources; 44 import android.debug.AdbManagerInternal; 45 import android.debug.AdbNotifications; 46 import android.debug.AdbTransportType; 47 import android.debug.IAdbTransport; 48 import android.hardware.usb.ParcelableUsbPort; 49 import android.hardware.usb.UsbAccessory; 50 import android.hardware.usb.UsbConfiguration; 51 import android.hardware.usb.UsbConstants; 52 import android.hardware.usb.UsbDevice; 53 import android.hardware.usb.UsbInterface; 54 import android.hardware.usb.UsbManager; 55 import android.hardware.usb.UsbPort; 56 import android.hardware.usb.UsbPortStatus; 57 import android.hardware.usb.gadget.V1_0.GadgetFunction; 58 import android.hardware.usb.gadget.V1_0.Status; 59 import android.hardware.usb.gadget.V1_2.UsbSpeed; 60 import android.hidl.manager.V1_0.IServiceNotification; 61 import android.os.BatteryManager; 62 import android.os.Environment; 63 import android.os.FileUtils; 64 import android.os.Handler; 65 import android.os.HwBinder; 66 import android.os.IBinder; 67 import android.os.Looper; 68 import android.os.Message; 69 import android.os.ParcelFileDescriptor; 70 import android.os.RemoteException; 71 import android.os.SystemClock; 72 import android.os.SystemProperties; 73 import android.os.UEventObserver; 74 import android.os.UserHandle; 75 import android.os.UserManager; 76 import android.os.storage.StorageManager; 77 import android.os.storage.StorageVolume; 78 import android.provider.Settings; 79 import android.service.usb.UsbDeviceManagerProto; 80 import android.service.usb.UsbHandlerProto; 81 import android.util.Pair; 82 import android.util.Slog; 83 import android.text.TextUtils; 84 85 import com.android.internal.annotations.GuardedBy; 86 import com.android.internal.logging.MetricsLogger; 87 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 88 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 89 import com.android.internal.notification.SystemNotificationChannels; 90 import com.android.internal.os.SomeArgs; 91 import com.android.internal.util.IndentingPrintWriter; 92 import com.android.internal.util.dump.DualDumpOutputStream; 93 import com.android.server.FgThread; 94 import com.android.server.LocalServices; 95 import com.android.server.usb.flags.Flags; 96 import com.android.server.usb.hal.gadget.UsbGadgetHal; 97 import com.android.server.usb.hal.gadget.UsbGadgetHalInstance; 98 import com.android.server.utils.EventLogger; 99 import com.android.server.wm.ActivityTaskManagerInternal; 100 101 import java.io.File; 102 import java.io.FileDescriptor; 103 import java.io.FileNotFoundException; 104 import java.io.IOException; 105 import java.util.HashMap; 106 import java.util.HashSet; 107 import java.util.Iterator; 108 import java.util.Locale; 109 import java.util.Map; 110 import java.util.NoSuchElementException; 111 import java.util.Scanner; 112 import java.util.Set; 113 import java.util.concurrent.atomic.AtomicInteger; 114 import java.util.regex.Matcher; 115 import java.util.regex.Pattern; 116 117 /** 118 * UsbDeviceManager manages USB state in device mode. 119 */ 120 public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObserver { 121 122 private static final String TAG = UsbDeviceManager.class.getSimpleName(); 123 private static final boolean DEBUG = false; 124 125 /** 126 * The name of the xml file in which screen unlocked functions are stored. 127 */ 128 private static final String USB_PREFS_XML = "UsbDeviceManagerPrefs.xml"; 129 130 /** 131 * The SharedPreference setting per user that stores the screen unlocked functions between 132 * sessions. 133 */ 134 static final String UNLOCKED_CONFIG_PREF = "usb-screen-unlocked-config-%d"; 135 136 /** 137 * ro.bootmode value when phone boots into usual Android. 138 */ 139 private static final String NORMAL_BOOT = "normal"; 140 141 /** 142 * UDC controller for the ConfigFS USB Gadgets. 143 */ 144 private static final String USB_CONTROLLER_NAME_PROPERTY = "sys.usb.controller"; 145 146 private static final String USB_STATE_MATCH = 147 "DEVPATH=/devices/virtual/android_usb/android0"; 148 private static final String ACCESSORY_START_MATCH = 149 "DEVPATH=/devices/virtual/misc/usb_accessory"; 150 private static final String FUNCTIONS_PATH = 151 "/sys/class/android_usb/android0/functions"; 152 private static final String STATE_PATH = 153 "/sys/class/android_usb/android0/state"; 154 private static final String RNDIS_ETH_ADDR_PATH = 155 "/sys/class/android_usb/android0/f_rndis/ethaddr"; 156 private static final String MIDI_ALSA_PATH = 157 "/sys/class/android_usb/android0/f_midi/alsa"; 158 159 private static final int MSG_UPDATE_STATE = 0; 160 private static final int MSG_ENABLE_ADB = 1; 161 private static final int MSG_SET_CURRENT_FUNCTIONS = 2; 162 private static final int MSG_SYSTEM_READY = 3; 163 private static final int MSG_BOOT_COMPLETED = 4; 164 private static final int MSG_USER_SWITCHED = 5; 165 private static final int MSG_UPDATE_USER_RESTRICTIONS = 6; 166 private static final int MSG_UPDATE_PORT_STATE = 7; 167 private static final int MSG_ACCESSORY_MODE_ENTER_TIMEOUT = 8; 168 private static final int MSG_UPDATE_CHARGING_STATE = 9; 169 private static final int MSG_UPDATE_HOST_STATE = 10; 170 private static final int MSG_LOCALE_CHANGED = 11; 171 private static final int MSG_SET_SCREEN_UNLOCKED_FUNCTIONS = 12; 172 private static final int MSG_UPDATE_SCREEN_LOCK = 13; 173 private static final int MSG_SET_CHARGING_FUNCTIONS = 14; 174 private static final int MSG_SET_FUNCTIONS_TIMEOUT = 15; 175 private static final int MSG_GET_CURRENT_USB_FUNCTIONS = 16; 176 private static final int MSG_FUNCTION_SWITCH_TIMEOUT = 17; 177 private static final int MSG_GADGET_HAL_REGISTERED = 18; 178 private static final int MSG_RESET_USB_GADGET = 19; 179 private static final int MSG_ACCESSORY_HANDSHAKE_TIMEOUT = 20; 180 private static final int MSG_INCREASE_SENDSTRING_COUNT = 21; 181 private static final int MSG_UPDATE_USB_SPEED = 22; 182 private static final int MSG_UPDATE_HAL_VERSION = 23; 183 184 // Delay for debouncing USB disconnects. 185 // We often get rapid connect/disconnect events when enabling USB functions, 186 // which need debouncing. 187 private static final int DEVICE_STATE_UPDATE_DELAY_EXT = 3000; 188 private static final int DEVICE_STATE_UPDATE_DELAY = 1000; 189 190 // Delay for debouncing USB disconnects on Type-C ports in host mode 191 private static final int HOST_STATE_UPDATE_DELAY = 1000; 192 193 // Timeout for entering USB request mode. 194 // Request is cancelled if host does not configure device within 10 seconds. 195 private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000; 196 197 /** 198 * Timeout for receiving USB accessory request 199 * Reset when receive next control request 200 * Broadcast intent if not receive next control request or enter next step. 201 */ 202 private static final int ACCESSORY_HANDSHAKE_TIMEOUT = 10 * 1000; 203 204 private static final int DUMPSYS_LOG_BUFFER = 200; 205 206 private static final String BOOT_MODE_PROPERTY = "ro.bootmode"; 207 208 private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv"; 209 private UsbHandler mHandler; 210 211 private final Object mLock = new Object(); 212 213 private final Context mContext; 214 private final ContentResolver mContentResolver; 215 @GuardedBy("mLock") 216 private UsbProfileGroupSettingsManager mCurrentSettings; 217 private final boolean mHasUsbAccessory; 218 @GuardedBy("mLock") 219 private String[] mAccessoryStrings; 220 private final UEventObserver mUEventObserver; 221 222 private static Set<Integer> sDenyInterfaces; 223 private HashMap<Long, FileDescriptor> mControlFds; 224 225 private static EventLogger sEventLogger; 226 227 private static UsbGadgetHal mUsbGadgetHal; 228 229 /** 230 * Counter for tracking UsbOperation operations. 231 */ 232 private static final AtomicInteger sUsbOperationCount = new AtomicInteger(); 233 234 static { 235 sDenyInterfaces = new HashSet<>(); 236 sDenyInterfaces.add(UsbConstants.USB_CLASS_AUDIO); 237 sDenyInterfaces.add(UsbConstants.USB_CLASS_COMM); 238 sDenyInterfaces.add(UsbConstants.USB_CLASS_HID); 239 sDenyInterfaces.add(UsbConstants.USB_CLASS_PRINTER); 240 sDenyInterfaces.add(UsbConstants.USB_CLASS_MASS_STORAGE); 241 sDenyInterfaces.add(UsbConstants.USB_CLASS_HUB); 242 sDenyInterfaces.add(UsbConstants.USB_CLASS_CDC_DATA); 243 sDenyInterfaces.add(UsbConstants.USB_CLASS_CSCID); 244 sDenyInterfaces.add(UsbConstants.USB_CLASS_CONTENT_SEC); 245 sDenyInterfaces.add(UsbConstants.USB_CLASS_VIDEO); 246 sDenyInterfaces.add(UsbConstants.USB_CLASS_WIRELESS_CONTROLLER); 247 } 248 249 /* 250 * Listens for uevent messages from the kernel to monitor the USB state 251 */ 252 private final class UsbUEventObserver extends UEventObserver { 253 @Override onUEvent(UEventObserver.UEvent event)254 public void onUEvent(UEventObserver.UEvent event) { 255 if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString()); 256 if (sEventLogger != null) { 257 sEventLogger.enqueue(new EventLogger.StringEvent("USB UEVENT: " 258 + event.toString())); 259 } else { 260 if (DEBUG) Slog.d(TAG, "sEventLogger == null"); 261 } 262 263 String state = event.get("USB_STATE"); 264 String accessory = event.get("ACCESSORY"); 265 266 if (state != null) { 267 mHandler.updateState(state); 268 } else if ("GETPROTOCOL".equals(accessory)) { 269 if (DEBUG) Slog.d(TAG, "got accessory get protocol"); 270 mHandler.setAccessoryUEventTime(SystemClock.elapsedRealtime()); 271 resetAccessoryHandshakeTimeoutHandler(); 272 } else if ("SENDSTRING".equals(accessory)) { 273 if (DEBUG) Slog.d(TAG, "got accessory send string"); 274 mHandler.sendEmptyMessage(MSG_INCREASE_SENDSTRING_COUNT); 275 resetAccessoryHandshakeTimeoutHandler(); 276 } else if ("START".equals(accessory)) { 277 if (DEBUG) Slog.d(TAG, "got accessory start"); 278 mHandler.removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT); 279 mHandler.setStartAccessoryTrue(); 280 startAccessoryMode(); 281 } 282 } 283 } 284 285 @Override onKeyguardStateChanged(boolean isShowing)286 public void onKeyguardStateChanged(boolean isShowing) { 287 int userHandle = ActivityManager.getCurrentUser(); 288 boolean secure = mContext.getSystemService(KeyguardManager.class) 289 .isDeviceSecure(userHandle); 290 if (DEBUG) { 291 Slog.v(TAG, "onKeyguardStateChanged: isShowing:" + isShowing + " secure:" + secure 292 + " user:" + userHandle); 293 } 294 // We are unlocked when the keyguard is down or non-secure. 295 mHandler.sendMessage(MSG_UPDATE_SCREEN_LOCK, (isShowing && secure)); 296 } 297 298 @Override onAwakeStateChanged(boolean isAwake)299 public void onAwakeStateChanged(boolean isAwake) { 300 // ignore 301 } 302 303 /** Called when a user is unlocked. */ onUnlockUser(int userHandle)304 public void onUnlockUser(int userHandle) { 305 onKeyguardStateChanged(false); 306 } 307 UsbDeviceManager(Context context, UsbAlsaManager alsaManager, UsbSettingsManager settingsManager, UsbPermissionManager permissionManager)308 public UsbDeviceManager(Context context, UsbAlsaManager alsaManager, 309 UsbSettingsManager settingsManager, UsbPermissionManager permissionManager) { 310 mContext = context; 311 mContentResolver = context.getContentResolver(); 312 PackageManager pm = mContext.getPackageManager(); 313 mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); 314 initRndisAddress(); 315 316 int operationId = sUsbOperationCount.incrementAndGet(); 317 boolean halNotPresent = false; 318 319 mUsbGadgetHal = UsbGadgetHalInstance.getInstance(this, null); 320 Slog.d(TAG, "getInstance done"); 321 322 mControlFds = new HashMap<>(); 323 FileDescriptor mtpFd = nativeOpenControl(UsbManager.USB_FUNCTION_MTP); 324 if (mtpFd == null) { 325 Slog.e(TAG, "Failed to open control for mtp"); 326 } 327 mControlFds.put(UsbManager.FUNCTION_MTP, mtpFd); 328 FileDescriptor ptpFd = nativeOpenControl(UsbManager.USB_FUNCTION_PTP); 329 if (ptpFd == null) { 330 Slog.e(TAG, "Failed to open control for ptp"); 331 } 332 mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd); 333 334 if (mUsbGadgetHal == null) { 335 /** 336 * Initialze the legacy UsbHandler 337 */ 338 mHandler = new UsbHandlerLegacy(FgThread.get().getLooper(), mContext, this, 339 alsaManager, permissionManager); 340 } else { 341 /** 342 * Initialize HAL based UsbHandler 343 */ 344 mHandler = new UsbHandlerHal(FgThread.get().getLooper(), mContext, this, 345 alsaManager, permissionManager); 346 } 347 348 mHandler.handlerInitDone(operationId); 349 350 if (nativeIsStartRequested()) { 351 if (DEBUG) Slog.d(TAG, "accessory attached at boot"); 352 startAccessoryMode(); 353 } 354 355 BroadcastReceiver portReceiver = new BroadcastReceiver() { 356 @Override 357 public void onReceive(Context context, Intent intent) { 358 ParcelableUsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT, android.hardware.usb.ParcelableUsbPort.class); 359 UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS, android.hardware.usb.UsbPortStatus.class); 360 mHandler.updateHostState( 361 port.getUsbPort(context.getSystemService(UsbManager.class)), status); 362 } 363 }; 364 365 BroadcastReceiver chargingReceiver = new BroadcastReceiver() { 366 @Override 367 public void onReceive(Context context, Intent intent) { 368 int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 369 boolean usbCharging = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; 370 mHandler.sendMessage(MSG_UPDATE_CHARGING_STATE, usbCharging); 371 } 372 }; 373 374 BroadcastReceiver hostReceiver = new BroadcastReceiver() { 375 @Override 376 public void onReceive(Context context, Intent intent) { 377 Iterator devices = ((UsbManager) context.getSystemService(Context.USB_SERVICE)) 378 .getDeviceList().entrySet().iterator(); 379 if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { 380 mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, true); 381 } else { 382 mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, false); 383 } 384 } 385 }; 386 387 BroadcastReceiver languageChangedReceiver = new BroadcastReceiver() { 388 @Override 389 public void onReceive(Context context, Intent intent) { 390 mHandler.sendEmptyMessage(MSG_LOCALE_CHANGED); 391 } 392 }; 393 394 mContext.registerReceiver(portReceiver, 395 new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED)); 396 mContext.registerReceiver(chargingReceiver, 397 new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 398 399 IntentFilter filter = 400 new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED); 401 filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); 402 mContext.registerReceiver(hostReceiver, filter); 403 404 mContext.registerReceiver(languageChangedReceiver, 405 new IntentFilter(Intent.ACTION_LOCALE_CHANGED)); 406 407 // Watch for USB configuration changes 408 mUEventObserver = new UsbUEventObserver(); 409 mUEventObserver.startObserving(USB_STATE_MATCH); 410 mUEventObserver.startObserving(ACCESSORY_START_MATCH); 411 412 sEventLogger = new EventLogger(DUMPSYS_LOG_BUFFER, "UsbDeviceManager activity"); 413 } 414 getCurrentSettings()415 UsbProfileGroupSettingsManager getCurrentSettings() { 416 synchronized (mLock) { 417 return mCurrentSettings; 418 } 419 } 420 getAccessoryStrings()421 String[] getAccessoryStrings() { 422 synchronized (mLock) { 423 return mAccessoryStrings; 424 } 425 } 426 systemReady()427 public void systemReady() { 428 if (DEBUG) Slog.d(TAG, "systemReady"); 429 430 LocalServices.getService(ActivityTaskManagerInternal.class).registerScreenObserver(this); 431 432 mHandler.sendEmptyMessage(MSG_SYSTEM_READY); 433 } 434 bootCompleted()435 public void bootCompleted() { 436 if (DEBUG) Slog.d(TAG, "boot completed"); 437 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); 438 } 439 setCurrentUser(int newCurrentUserId, UsbProfileGroupSettingsManager settings)440 public void setCurrentUser(int newCurrentUserId, UsbProfileGroupSettingsManager settings) { 441 synchronized (mLock) { 442 mCurrentSettings = settings; 443 mHandler.obtainMessage(MSG_USER_SWITCHED, newCurrentUserId, 0).sendToTarget(); 444 } 445 } 446 updateUserRestrictions()447 public void updateUserRestrictions() { 448 mHandler.sendEmptyMessage(MSG_UPDATE_USER_RESTRICTIONS); 449 } 450 451 /* 452 * Start the timeout-timer upon receiving "get_protocol" uevent. 453 * Restart the timer every time if any succeeding uevnet received. 454 * (Only when USB is under accessory mode) 455 * <p>About the details of the related control request and sequence ordering, refer to 456 * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p> 457 */ resetAccessoryHandshakeTimeoutHandler()458 private void resetAccessoryHandshakeTimeoutHandler() { 459 long functions = getCurrentFunctions(); 460 // some accesories send get_protocol after start accessory 461 if ((functions & UsbManager.FUNCTION_ACCESSORY) == 0) { 462 mHandler.removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT); 463 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT), 464 ACCESSORY_HANDSHAKE_TIMEOUT); 465 } 466 } 467 startAccessoryMode()468 private void startAccessoryMode() { 469 if (!mHasUsbAccessory) return; 470 471 int operationId = sUsbOperationCount.incrementAndGet(); 472 473 mAccessoryStrings = nativeGetAccessoryStrings(); 474 // don't start accessory mode if our mandatory strings have not been set 475 boolean enableAccessory = (mAccessoryStrings != null && 476 mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null && 477 mAccessoryStrings[UsbAccessory.MODEL_STRING] != null); 478 479 long functions = UsbManager.FUNCTION_NONE; 480 if (enableAccessory) { 481 functions |= UsbManager.FUNCTION_ACCESSORY; 482 } 483 484 if (functions != UsbManager.FUNCTION_NONE) { 485 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_MODE_ENTER_TIMEOUT), 486 ACCESSORY_REQUEST_TIMEOUT); 487 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT), 488 ACCESSORY_HANDSHAKE_TIMEOUT); 489 setCurrentFunctions(functions, operationId); 490 } 491 } 492 493 //TODO It is not clear that this method serves any purpose (at least on Pixel devices) 494 // consider removing initRndisAddress()495 private static void initRndisAddress() { 496 // configure RNDIS ethernet address based on our serial number using the same algorithm 497 // we had been previously using in kernel board files 498 final int ETH_ALEN = 6; 499 int address[] = new int[ETH_ALEN]; 500 // first byte is 0x02 to signify a locally administered address 501 address[0] = 0x02; 502 503 String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF"); 504 int serialLength = serial.length(); 505 // XOR the USB serial across the remaining 5 bytes 506 for (int i = 0; i < serialLength; i++) { 507 address[i % (ETH_ALEN - 1) + 1] ^= (int) serial.charAt(i); 508 } 509 String addrString = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", 510 address[0], address[1], address[2], address[3], address[4], address[5]); 511 try { 512 FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString); 513 } catch (IOException e) { 514 Slog.i(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH); 515 } 516 } 517 logAndPrint(int priority, IndentingPrintWriter pw, String msg)518 public static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) { 519 Slog.println(priority, TAG, msg); 520 if (pw != null) { 521 pw.println(msg); 522 } 523 } 524 logAndPrintException(IndentingPrintWriter pw, String msg, Exception e)525 public static void logAndPrintException(IndentingPrintWriter pw, String msg, Exception e) { 526 Slog.e(TAG, msg, e); 527 if (pw != null) { 528 pw.println(msg + e); 529 } 530 } 531 532 abstract static class UsbHandler extends Handler { 533 534 // current USB state 535 private boolean mHostConnected; 536 private boolean mUsbAccessoryConnected; 537 private boolean mInHostModeWithNoAccessoryConnected; 538 private boolean mSourcePower; 539 private boolean mSinkPower; 540 private boolean mAudioAccessoryConnected; 541 private boolean mAudioAccessorySupported; 542 private boolean mConnectedToDataDisabledPort; 543 private int mPowerBrickConnectionStatus; 544 545 private UsbAccessory mCurrentAccessory; 546 private int mUsbNotificationId; 547 private boolean mAdbNotificationShown; 548 private boolean mUsbCharging; 549 private boolean mHideUsbNotification; 550 private boolean mSupportsAllCombinations; 551 private boolean mScreenLocked; 552 private boolean mSystemReady; 553 private Intent mBroadcastedIntent; 554 private boolean mPendingBootBroadcast; 555 private boolean mAudioSourceEnabled; 556 private boolean mMidiEnabled; 557 private int mMidiCard; 558 private int mMidiDevice; 559 560 /** 561 * mAccessoryConnectionStartTime record the timing of start_accessory 562 * mSendStringCount count the number of receiving uevent send_string 563 * mStartAccessory record whether start_accessory is received 564 */ 565 private long mAccessoryConnectionStartTime = 0L; 566 private int mSendStringCount = 0; 567 private boolean mStartAccessory = false; 568 569 private final Context mContext; 570 private final UsbAlsaManager mUsbAlsaManager; 571 private final UsbPermissionManager mPermissionManager; 572 private NotificationManager mNotificationManager; 573 574 /** 575 * Do not debounce for the first disconnect after resetUsbGadget. 576 */ 577 protected boolean mResetUsbGadgetDisableDebounce; 578 protected boolean mConnected; 579 protected boolean mConfigured; 580 protected long mScreenUnlockedFunctions; 581 protected boolean mBootCompleted; 582 protected boolean mCurrentFunctionsApplied; 583 protected boolean mUseUsbNotification; 584 protected long mCurrentFunctions; 585 protected final UsbDeviceManager mUsbDeviceManager; 586 protected final ContentResolver mContentResolver; 587 protected SharedPreferences mSettings; 588 protected int mCurrentUser; 589 protected boolean mCurrentUsbFunctionsReceived; 590 protected int mUsbSpeed; 591 protected int mCurrentGadgetHalVersion; 592 protected boolean mPendingBootAccessoryHandshakeBroadcast; 593 594 /** 595 * The persistent property which stores whether adb is enabled or not. 596 * May also contain vendor-specific default functions for testing purposes. 597 */ 598 protected static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config"; 599 600 protected static final String MTP_PACKAGE_NAME = "com.android.mtp"; 601 protected static final String MTP_SERVICE_CLASS_NAME = "com.android.mtp.MtpService"; 602 603 private boolean mIsMtpServiceBound = false; 604 605 /** 606 * {@link ServiceConnection} for {@link MtpService}. 607 */ 608 private ServiceConnection mMtpServiceConnection = new ServiceConnection() { 609 @Override 610 public void onServiceConnected(ComponentName className, IBinder service) {} 611 612 @Override 613 public void onServiceDisconnected(ComponentName arg0) {} 614 }; 615 UsbHandler(Looper looper, Context context, UsbDeviceManager deviceManager, UsbAlsaManager alsaManager, UsbPermissionManager permissionManager)616 UsbHandler(Looper looper, Context context, UsbDeviceManager deviceManager, 617 UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) { 618 super(looper); 619 mContext = context; 620 mUsbDeviceManager = deviceManager; 621 mUsbAlsaManager = alsaManager; 622 mPermissionManager = permissionManager; 623 mContentResolver = context.getContentResolver(); 624 625 mCurrentUser = ActivityManager.getCurrentUser(); 626 mScreenLocked = true; 627 628 mSettings = getPinnedSharedPrefs(mContext); 629 if (mSettings == null) { 630 Slog.e(TAG, "Couldn't load shared preferences"); 631 } else { 632 mScreenUnlockedFunctions = UsbManager.usbFunctionsFromString( 633 mSettings.getString( 634 String.format(Locale.ENGLISH, UNLOCKED_CONFIG_PREF, mCurrentUser), 635 "")); 636 } 637 638 // We do not show the USB notification if the primary volume supports mass storage. 639 // The legacy mass storage UI will be used instead. 640 final StorageManager storageManager = StorageManager.from(mContext); 641 final StorageVolume primary = 642 storageManager != null ? storageManager.getPrimaryVolume() : null; 643 644 boolean massStorageSupported = primary != null && primary.allowMassStorage(); 645 mUseUsbNotification = !massStorageSupported && mContext.getResources().getBoolean( 646 com.android.internal.R.bool.config_usbChargingMessage); 647 } 648 sendMessage(int what, boolean arg)649 public void sendMessage(int what, boolean arg) { 650 removeMessages(what); 651 Message m = Message.obtain(this, what); 652 m.arg1 = (arg ? 1 : 0); 653 sendMessage(m); 654 } 655 sendMessage(int what)656 public boolean sendMessage(int what) { 657 removeMessages(what); 658 Message m = Message.obtain(this, what); 659 return sendMessageDelayed(m,0); 660 } 661 sendMessage(int what, int operationId)662 public void sendMessage(int what, int operationId) { 663 removeMessages(what); 664 Message m = Message.obtain(this, what); 665 m.arg1 = operationId; 666 sendMessage(m); 667 } 668 sendMessage(int what, Object arg)669 public void sendMessage(int what, Object arg) { 670 removeMessages(what); 671 Message m = Message.obtain(this, what); 672 m.obj = arg; 673 sendMessage(m); 674 } 675 sendMessage(int what, Object arg, int operationId)676 public void sendMessage(int what, Object arg, int operationId) { 677 removeMessages(what); 678 Message m = Message.obtain(this, what); 679 m.obj = arg; 680 m.arg1 = operationId; 681 sendMessage(m); 682 } 683 sendMessage(int what, boolean arg, int operationId)684 public void sendMessage(int what, boolean arg, int operationId) { 685 removeMessages(what); 686 Message m = Message.obtain(this, what); 687 m.arg1 = (arg ? 1 : 0); 688 m.arg2 = operationId; 689 sendMessage(m); 690 } 691 sendMessage(int what, Object arg, boolean arg1)692 public void sendMessage(int what, Object arg, boolean arg1) { 693 removeMessages(what); 694 Message m = Message.obtain(this, what); 695 m.obj = arg; 696 m.arg1 = (arg1 ? 1 : 0); 697 sendMessage(m); 698 } 699 sendMessage(int what, long arg, boolean arg1, int operationId)700 public void sendMessage(int what, long arg, boolean arg1, int operationId) { 701 removeMessages(what); 702 Message m = Message.obtain(this, what); 703 m.obj = arg; 704 m.arg1 = (arg1 ? 1 : 0); 705 m.arg2 = operationId; 706 sendMessage(m); 707 } 708 sendMessage(int what, boolean arg1, boolean arg2)709 public void sendMessage(int what, boolean arg1, boolean arg2) { 710 removeMessages(what); 711 Message m = Message.obtain(this, what); 712 m.arg1 = (arg1 ? 1 : 0); 713 m.arg2 = (arg2 ? 1 : 0); 714 sendMessage(m); 715 } 716 sendMessageDelayed(int what, boolean arg, long delayMillis)717 public void sendMessageDelayed(int what, boolean arg, long delayMillis) { 718 removeMessages(what); 719 Message m = Message.obtain(this, what); 720 m.arg1 = (arg ? 1 : 0); 721 sendMessageDelayed(m, delayMillis); 722 } 723 updateState(String state)724 public void updateState(String state) { 725 int connected, configured; 726 727 if ("DISCONNECTED".equals(state)) { 728 connected = 0; 729 configured = 0; 730 } else if ("CONNECTED".equals(state)) { 731 connected = 1; 732 configured = 0; 733 } else if ("CONFIGURED".equals(state)) { 734 connected = 1; 735 configured = 1; 736 } else { 737 Slog.e(TAG, "unknown state " + state); 738 return; 739 } 740 if (connected == 1) removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT); 741 Message msg = Message.obtain(this, MSG_UPDATE_STATE); 742 msg.arg1 = connected; 743 msg.arg2 = configured; 744 if (DEBUG) { 745 Slog.i(TAG, "mResetUsbGadgetDisableDebounce:" + mResetUsbGadgetDisableDebounce 746 + " connected:" + connected + "configured:" + configured); 747 } 748 if (mResetUsbGadgetDisableDebounce) { 749 // Do not debounce disconnect after resetUsbGadget. 750 sendMessage(msg); 751 if (connected == 1) mResetUsbGadgetDisableDebounce = false; 752 } else { 753 if (configured == 0) { 754 removeMessages(MSG_UPDATE_STATE); 755 if (DEBUG) Slog.i(TAG, "removeMessages MSG_UPDATE_STATE"); 756 } 757 if (connected == 1) removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT); 758 // debounce disconnects to avoid problems bringing up USB tethering. 759 sendMessageDelayed(msg, 760 (connected == 0) ? (mScreenLocked ? DEVICE_STATE_UPDATE_DELAY 761 : DEVICE_STATE_UPDATE_DELAY_EXT) : 0); 762 } 763 } 764 updateHostState(UsbPort port, UsbPortStatus status)765 public void updateHostState(UsbPort port, UsbPortStatus status) { 766 if (DEBUG) { 767 Slog.i(TAG, "updateHostState " + port + " status=" + status); 768 } 769 770 SomeArgs args = SomeArgs.obtain(); 771 args.arg1 = port; 772 args.arg2 = status; 773 774 removeMessages(MSG_UPDATE_PORT_STATE); 775 Message msg = obtainMessage(MSG_UPDATE_PORT_STATE, args); 776 // debounce rapid transitions of connect/disconnect on type-c ports 777 sendMessageDelayed(msg, HOST_STATE_UPDATE_DELAY); 778 } 779 setAdbEnabled(boolean enable, int operationId)780 private void setAdbEnabled(boolean enable, int operationId) { 781 if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); 782 783 if (enable) { 784 setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_ADB); 785 } else { 786 setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, ""); 787 } 788 789 setEnabledFunctions(mCurrentFunctions, true, operationId); 790 updateAdbNotification(false); 791 } 792 isUsbTransferAllowed()793 protected boolean isUsbTransferAllowed() { 794 UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 795 return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER); 796 } 797 updateCurrentAccessory()798 private void updateCurrentAccessory() { 799 // We are entering accessory mode if we have received a request from the host 800 // and the request has not timed out yet. 801 int operationId = sUsbOperationCount.incrementAndGet(); 802 803 boolean enteringAccessoryMode = hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT); 804 805 if (mConfigured && enteringAccessoryMode) { 806 // successfully entered accessory mode 807 String[] accessoryStrings = mUsbDeviceManager.getAccessoryStrings(); 808 if (accessoryStrings != null) { 809 UsbSerialReader serialReader = new UsbSerialReader(mContext, mPermissionManager, 810 accessoryStrings[UsbAccessory.SERIAL_STRING]); 811 812 mCurrentAccessory = new UsbAccessory( 813 accessoryStrings[UsbAccessory.MANUFACTURER_STRING], 814 accessoryStrings[UsbAccessory.MODEL_STRING], 815 accessoryStrings[UsbAccessory.DESCRIPTION_STRING], 816 accessoryStrings[UsbAccessory.VERSION_STRING], 817 accessoryStrings[UsbAccessory.URI_STRING], 818 serialReader); 819 820 serialReader.setDevice(mCurrentAccessory); 821 822 Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory); 823 // defer accessoryAttached if system is not ready 824 if (mBootCompleted) { 825 mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); 826 removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT); 827 broadcastUsbAccessoryHandshake(); 828 } // else handle in boot completed 829 } else { 830 Slog.e(TAG, "nativeGetAccessoryStrings failed"); 831 } 832 } else { 833 if (!enteringAccessoryMode) { 834 notifyAccessoryModeExit(operationId); 835 } else if (DEBUG) { 836 Slog.v(TAG, "Debouncing accessory mode exit"); 837 } 838 } 839 } 840 notifyAccessoryModeExit(int operationId)841 private void notifyAccessoryModeExit(int operationId) { 842 // make sure accessory mode is off 843 // and restore default functions 844 Slog.d(TAG, "exited USB accessory mode"); 845 setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); 846 847 if (mCurrentAccessory != null) { 848 if (mBootCompleted) { 849 mPermissionManager.usbAccessoryRemoved(mCurrentAccessory); 850 } 851 mCurrentAccessory = null; 852 } 853 } 854 getPinnedSharedPrefs(Context context)855 protected SharedPreferences getPinnedSharedPrefs(Context context) { 856 final File prefsFile = new File( 857 Environment.getDataSystemDeDirectory(UserHandle.USER_SYSTEM), USB_PREFS_XML); 858 return context.createDeviceProtectedStorageContext() 859 .getSharedPreferences(prefsFile, Context.MODE_PRIVATE); 860 } 861 isUsbStateChanged(Intent intent)862 private boolean isUsbStateChanged(Intent intent) { 863 final Set<String> keySet = intent.getExtras().keySet(); 864 if (mBroadcastedIntent == null) { 865 for (String key : keySet) { 866 if (intent.getBooleanExtra(key, false)) { 867 return true; 868 } 869 } 870 } else { 871 if (!keySet.equals(mBroadcastedIntent.getExtras().keySet())) { 872 return true; 873 } 874 for (String key : keySet) { 875 if (intent.getBooleanExtra(key, false) != 876 mBroadcastedIntent.getBooleanExtra(key, false)) { 877 return true; 878 } 879 } 880 } 881 return false; 882 } 883 broadcastUsbAccessoryHandshake()884 private void broadcastUsbAccessoryHandshake() { 885 // send a sticky broadcast containing USB accessory handshake information 886 Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_HANDSHAKE) 887 .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 888 | Intent.FLAG_RECEIVER_FOREGROUND) 889 .putExtra(UsbManager.EXTRA_ACCESSORY_UEVENT_TIME, 890 mAccessoryConnectionStartTime) 891 .putExtra(UsbManager.EXTRA_ACCESSORY_STRING_COUNT, 892 mSendStringCount) 893 .putExtra(UsbManager.EXTRA_ACCESSORY_START, 894 mStartAccessory) 895 .putExtra(UsbManager.EXTRA_ACCESSORY_HANDSHAKE_END, 896 SystemClock.elapsedRealtime()); 897 898 if (DEBUG) { 899 Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras()); 900 } 901 902 sendStickyBroadcast(intent); 903 resetUsbAccessoryHandshakeDebuggingInfo(); 904 } 905 updateUsbStateBroadcastIfNeeded(long functions)906 protected void updateUsbStateBroadcastIfNeeded(long functions) { 907 // send a sticky broadcast containing current USB state 908 Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 909 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 910 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 911 | Intent.FLAG_RECEIVER_FOREGROUND); 912 intent.putExtra(UsbManager.USB_CONNECTED, mConnected); 913 intent.putExtra(UsbManager.USB_HOST_CONNECTED, mHostConnected); 914 intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); 915 intent.putExtra(UsbManager.USB_DATA_UNLOCKED, 916 isUsbTransferAllowed() && isUsbDataTransferActive(mCurrentFunctions)); 917 918 long remainingFunctions = functions; 919 while (remainingFunctions != 0) { 920 intent.putExtra(UsbManager.usbFunctionsToString( 921 Long.highestOneBit(remainingFunctions)), true); 922 remainingFunctions -= Long.highestOneBit(remainingFunctions); 923 } 924 925 // send broadcast intent only if the USB state has changed 926 if (!isUsbStateChanged(intent)) { 927 if (DEBUG) { 928 Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras()); 929 } 930 return; 931 } 932 933 if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras()); 934 sendStickyBroadcast(intent); 935 mBroadcastedIntent = intent; 936 } 937 sendStickyBroadcast(Intent intent)938 protected void sendStickyBroadcast(Intent intent) { 939 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 940 sEventLogger.enqueue(new EventLogger.StringEvent("USB intent: " + intent)); 941 } 942 getMidiCardDevice()943 private void getMidiCardDevice() throws FileNotFoundException { 944 String controllerName = getSystemProperty(USB_CONTROLLER_NAME_PROPERTY, ""); 945 if (TextUtils.isEmpty(controllerName)) { 946 throw new FileNotFoundException("controller name not found"); 947 } 948 949 File soundDir = new File("/sys/class/udc/" + controllerName + "/gadget/sound"); 950 if (!soundDir.exists()) { 951 throw new FileNotFoundException("sound device not found"); 952 } 953 954 // There should be exactly one sound card 955 File[] cardDirs = FileUtils.listFilesOrEmpty(soundDir, 956 (dir, file) -> file.startsWith("card")); 957 if (cardDirs.length != 1) { 958 throw new FileNotFoundException("sound card not match"); 959 } 960 961 // There should be exactly one midi device 962 File[] midis = FileUtils.listFilesOrEmpty(cardDirs[0], 963 (dir, file) -> file.startsWith("midi")); 964 if (midis.length != 1) { 965 throw new FileNotFoundException("MIDI device not match"); 966 } 967 968 Pattern pattern = Pattern.compile("midiC(\\d+)D(\\d+)"); 969 Matcher matcher = pattern.matcher(midis[0].getName()); 970 if (matcher.matches()) { 971 mMidiCard = Integer.parseInt(matcher.group(1)); 972 mMidiDevice = Integer.parseInt(matcher.group(2)); 973 Slog.i(TAG, "Found MIDI card " + mMidiCard + " device " + mMidiDevice); 974 } else { 975 throw new FileNotFoundException("MIDI name not match"); 976 } 977 } 978 updateUsbFunctions()979 private void updateUsbFunctions() { 980 updateMidiFunction(); 981 updateMtpFunction(); 982 } 983 updateMidiFunction()984 private void updateMidiFunction() { 985 boolean enabled = (mCurrentFunctions & UsbManager.FUNCTION_MIDI) != 0; 986 if (enabled != mMidiEnabled) { 987 if (enabled) { 988 if (android.hardware.usb.flags.Flags.enableUsbSysfsMidiIdentification()) { 989 try { 990 getMidiCardDevice(); 991 } catch (FileNotFoundException e) { 992 Slog.e(TAG, "could not identify MIDI device", e); 993 enabled = false; 994 } 995 } else { 996 Scanner scanner = null; 997 try { 998 scanner = new Scanner(new File(MIDI_ALSA_PATH)); 999 mMidiCard = scanner.nextInt(); 1000 mMidiDevice = scanner.nextInt(); 1001 } catch (FileNotFoundException e) { 1002 Slog.e(TAG, "could not open MIDI file", e); 1003 enabled = false; 1004 } finally { 1005 if (scanner != null) { 1006 scanner.close(); 1007 } 1008 } 1009 } 1010 } 1011 mMidiEnabled = enabled; 1012 } 1013 mUsbAlsaManager.setPeripheralMidiState( 1014 mMidiEnabled && mConfigured, mMidiCard, mMidiDevice); 1015 } 1016 1017 /** 1018 * Bind to MtpService when MTP or PTP is enabled. This is done to prevent activity manager 1019 * from freezing the corresponding process. 1020 */ updateMtpFunction()1021 private void updateMtpFunction() { 1022 if (!Flags.enableBindToMtpService()) { 1023 return; 1024 } 1025 1026 boolean mtpEnabled = ((mCurrentFunctions & UsbManager.FUNCTION_MTP) != 0); 1027 boolean ptpEnabled = ((mCurrentFunctions & UsbManager.FUNCTION_PTP) != 0); 1028 1029 if (DEBUG) { 1030 Slog.d(TAG, "updateMtpFunction " 1031 + ", mtpEnabled: " + mtpEnabled 1032 + ", ptpEnabled: " + ptpEnabled 1033 + ", mIsMtpServiceBound: " + mIsMtpServiceBound 1034 ); 1035 } 1036 1037 if (mConfigured && (mtpEnabled || ptpEnabled)) { 1038 bindToMtpService(); 1039 } else if (mIsMtpServiceBound) { 1040 unbindMtpService(); 1041 } 1042 } 1043 bindToMtpService()1044 private void bindToMtpService() { 1045 Intent intent = new Intent(); 1046 intent.setComponent(new ComponentName(MTP_PACKAGE_NAME, MTP_SERVICE_CLASS_NAME)); 1047 1048 if (DEBUG) Slog.d(TAG, "Binding to MtpService"); 1049 1050 try { 1051 mIsMtpServiceBound = mContext.bindServiceAsUser( 1052 intent, 1053 mMtpServiceConnection, 1054 Context.BIND_AUTO_CREATE, 1055 UserHandle.CURRENT 1056 ); 1057 } catch (SecurityException exception) { 1058 Slog.e(TAG, "Unable to bind to MtpService due to SecurityException", exception); 1059 } 1060 1061 // Unbinding from the service if binding was not successful to release the connection. 1062 // https://developer.android.com/reference/android/content/Context#bindService(android.content.Intent,%20android.content.ServiceConnection,%20int) 1063 if (!mIsMtpServiceBound) { 1064 unbindMtpService(); 1065 Slog.e(TAG, "Binding to MtpService failed"); 1066 } 1067 1068 if (DEBUG && mIsMtpServiceBound) Slog.d(TAG, "Successfully bound to MtpService"); 1069 } 1070 unbindMtpService()1071 private void unbindMtpService() { 1072 if (DEBUG) Slog.d(TAG, "Unbinding from MtpService"); 1073 1074 mContext.unbindService(mMtpServiceConnection); 1075 mIsMtpServiceBound = false; 1076 } 1077 setScreenUnlockedFunctions(int operationId)1078 private void setScreenUnlockedFunctions(int operationId) { 1079 setEnabledFunctions(mScreenUnlockedFunctions, false, operationId); 1080 } 1081 1082 private static class AdbTransport extends IAdbTransport.Stub { 1083 private final UsbHandler mHandler; 1084 AdbTransport(UsbHandler handler)1085 AdbTransport(UsbHandler handler) { 1086 mHandler = handler; 1087 } 1088 1089 @Override onAdbEnabled(boolean enabled, byte transportType)1090 public void onAdbEnabled(boolean enabled, byte transportType) { 1091 if (transportType == AdbTransportType.USB) { 1092 int operationId = sUsbOperationCount.incrementAndGet(); 1093 mHandler.sendMessage(MSG_ENABLE_ADB, enabled, operationId); 1094 } 1095 } 1096 } 1097 1098 /** 1099 * Returns the functions that are passed down to the low level driver once adb and 1100 * charging are accounted for. 1101 */ getAppliedFunctions(long functions)1102 long getAppliedFunctions(long functions) { 1103 if (functions == UsbManager.FUNCTION_NONE) { 1104 return getChargingFunctions(); 1105 } 1106 if (isAdbEnabled()) { 1107 return functions | UsbManager.FUNCTION_ADB; 1108 } 1109 return functions; 1110 } 1111 1112 @Override handleMessage(Message msg)1113 public void handleMessage(Message msg) { 1114 switch (msg.what) { 1115 case MSG_UPDATE_STATE: 1116 int operationId = sUsbOperationCount.incrementAndGet(); 1117 mConnected = (msg.arg1 == 1); 1118 mConfigured = (msg.arg2 == 1); 1119 if (DEBUG) { 1120 Slog.i(TAG, "handleMessage MSG_UPDATE_STATE " + "mConnected:" + mConnected 1121 + " mConfigured:" + mConfigured); 1122 } 1123 updateUsbNotification(false); 1124 updateAdbNotification(false); 1125 if (mBootCompleted) { 1126 updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions)); 1127 } 1128 if ((mCurrentFunctions & UsbManager.FUNCTION_ACCESSORY) != 0) { 1129 updateCurrentAccessory(); 1130 } 1131 if (mBootCompleted) { 1132 if (!mConnected && !hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT) 1133 && !hasMessages(MSG_FUNCTION_SWITCH_TIMEOUT)) { 1134 // restore defaults when USB is disconnected 1135 if (!mScreenLocked 1136 && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { 1137 setScreenUnlockedFunctions(operationId); 1138 } else { 1139 setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); 1140 } 1141 } 1142 updateUsbFunctions(); 1143 } else { 1144 mPendingBootBroadcast = true; 1145 } 1146 updateUsbSpeed(); 1147 break; 1148 case MSG_UPDATE_PORT_STATE: 1149 SomeArgs args = (SomeArgs) msg.obj; 1150 boolean prevHostConnected = mHostConnected; 1151 UsbPort port = (UsbPort) args.arg1; 1152 UsbPortStatus status = (UsbPortStatus) args.arg2; 1153 1154 if (status != null) { 1155 mHostConnected = status.getCurrentDataRole() == DATA_ROLE_HOST; 1156 mSourcePower = status.getCurrentPowerRole() == POWER_ROLE_SOURCE; 1157 mSinkPower = status.getCurrentPowerRole() == POWER_ROLE_SINK; 1158 mAudioAccessoryConnected = (status.getCurrentMode() == MODE_AUDIO_ACCESSORY); 1159 1160 // Ideally we want to see if PR_SWAP and DR_SWAP is supported. 1161 // But, this should be suffice, since, all four combinations are only supported 1162 // when PR_SWAP and DR_SWAP are supported. 1163 mSupportsAllCombinations = status.isRoleCombinationSupported( 1164 POWER_ROLE_SOURCE, DATA_ROLE_HOST) 1165 && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST) 1166 && status.isRoleCombinationSupported(POWER_ROLE_SOURCE, 1167 DATA_ROLE_DEVICE) 1168 && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE); 1169 1170 boolean usbDataDisabled = 1171 status.getUsbDataStatus() != UsbPortStatus.DATA_STATUS_ENABLED; 1172 mConnectedToDataDisabledPort = status.isConnected() && usbDataDisabled; 1173 mPowerBrickConnectionStatus = status.getPowerBrickConnectionStatus(); 1174 } else { 1175 mHostConnected = false; 1176 mSourcePower = false; 1177 mSinkPower = false; 1178 mAudioAccessoryConnected = false; 1179 mSupportsAllCombinations = false; 1180 mConnectedToDataDisabledPort = false; 1181 mPowerBrickConnectionStatus = UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN; 1182 } 1183 1184 if (mHostConnected) { 1185 if (!mUsbAccessoryConnected) { 1186 mInHostModeWithNoAccessoryConnected = true; 1187 } else { 1188 mInHostModeWithNoAccessoryConnected = false; 1189 } 1190 } else { 1191 // if not in host mode, reset value to false 1192 mInHostModeWithNoAccessoryConnected = false; 1193 } 1194 1195 mAudioAccessorySupported = port.isModeSupported(MODE_AUDIO_ACCESSORY); 1196 1197 args.recycle(); 1198 updateUsbNotification(false); 1199 if (mBootCompleted) { 1200 if (mHostConnected || prevHostConnected) { 1201 updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions)); 1202 } 1203 } else { 1204 mPendingBootBroadcast = true; 1205 } 1206 break; 1207 case MSG_UPDATE_CHARGING_STATE: 1208 mUsbCharging = (msg.arg1 == 1); 1209 updateUsbNotification(false); 1210 break; 1211 case MSG_UPDATE_HOST_STATE: 1212 Iterator devices = (Iterator) msg.obj; 1213 mUsbAccessoryConnected = (msg.arg1 == 1); 1214 1215 if (DEBUG) { 1216 Slog.i(TAG, "HOST_STATE connected:" + mUsbAccessoryConnected); 1217 } 1218 1219 if (!devices.hasNext()) { 1220 mInHostModeWithNoAccessoryConnected = true; 1221 } else { 1222 mInHostModeWithNoAccessoryConnected = false; 1223 } 1224 1225 mHideUsbNotification = false; 1226 while (devices.hasNext()) { 1227 Map.Entry pair = (Map.Entry) devices.next(); 1228 if (DEBUG) { 1229 Slog.i(TAG, pair.getKey() + " = " + pair.getValue()); 1230 } 1231 UsbDevice device = (UsbDevice) pair.getValue(); 1232 int configurationCount = device.getConfigurationCount() - 1; 1233 while (configurationCount >= 0) { 1234 UsbConfiguration config = device.getConfiguration(configurationCount); 1235 configurationCount--; 1236 int interfaceCount = config.getInterfaceCount() - 1; 1237 while (interfaceCount >= 0) { 1238 UsbInterface intrface = config.getInterface(interfaceCount); 1239 interfaceCount--; 1240 if (sDenyInterfaces.contains(intrface.getInterfaceClass())) { 1241 mHideUsbNotification = true; 1242 break; 1243 } 1244 } 1245 } 1246 } 1247 updateUsbNotification(false); 1248 break; 1249 case MSG_ENABLE_ADB: 1250 setAdbEnabled(msg.arg1 == 1, msg.arg2); 1251 break; 1252 case MSG_SET_CURRENT_FUNCTIONS: 1253 long functions = (Long) msg.obj; 1254 operationId = (int) msg.arg1; 1255 setEnabledFunctions(functions, false, operationId); 1256 break; 1257 case MSG_SET_SCREEN_UNLOCKED_FUNCTIONS: 1258 operationId = sUsbOperationCount.incrementAndGet(); 1259 mScreenUnlockedFunctions = (Long) msg.obj; 1260 if (mSettings != null) { 1261 SharedPreferences.Editor editor = mSettings.edit(); 1262 editor.putString(String.format(Locale.ENGLISH, UNLOCKED_CONFIG_PREF, 1263 mCurrentUser), 1264 UsbManager.usbFunctionsToString(mScreenUnlockedFunctions)); 1265 editor.commit(); 1266 } 1267 if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { 1268 // If the screen is unlocked, also set current functions. 1269 setScreenUnlockedFunctions(operationId); 1270 } else { 1271 setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); 1272 } 1273 break; 1274 case MSG_UPDATE_SCREEN_LOCK: 1275 operationId = sUsbOperationCount.incrementAndGet(); 1276 if (msg.arg1 == 1 == mScreenLocked) { 1277 break; 1278 } 1279 mScreenLocked = msg.arg1 == 1; 1280 if (!mBootCompleted) { 1281 break; 1282 } 1283 if (mScreenLocked) { 1284 if (!mConnected) { 1285 setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); 1286 } 1287 } else { 1288 if (mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE 1289 && mCurrentFunctions == UsbManager.FUNCTION_NONE) { 1290 // Set the screen unlocked functions if current function is charging. 1291 setScreenUnlockedFunctions(operationId); 1292 } 1293 } 1294 break; 1295 case MSG_UPDATE_USER_RESTRICTIONS: 1296 operationId = sUsbOperationCount.incrementAndGet(); 1297 // Restart the USB stack if USB transfer is enabled but no longer allowed. 1298 if (isUsbDataTransferActive(mCurrentFunctions) && !isUsbTransferAllowed()) { 1299 setEnabledFunctions(UsbManager.FUNCTION_NONE, true, operationId); 1300 } 1301 break; 1302 case MSG_SYSTEM_READY: 1303 operationId = sUsbOperationCount.incrementAndGet(); 1304 mNotificationManager = (NotificationManager) 1305 mContext.getSystemService(Context.NOTIFICATION_SERVICE); 1306 1307 LocalServices.getService( 1308 AdbManagerInternal.class).registerTransport(new AdbTransport(this)); 1309 1310 // Ensure that the notification channels are set up 1311 if (isTv()) { 1312 // TV-specific notification channel 1313 mNotificationManager.createNotificationChannel( 1314 new NotificationChannel(ADB_NOTIFICATION_CHANNEL_ID_TV, 1315 mContext.getString( 1316 com.android.internal.R.string 1317 .adb_debugging_notification_channel_tv), 1318 NotificationManager.IMPORTANCE_HIGH)); 1319 } 1320 mSystemReady = true; 1321 finishBoot(operationId); 1322 break; 1323 case MSG_LOCALE_CHANGED: 1324 updateAdbNotification(true); 1325 updateUsbNotification(true); 1326 break; 1327 case MSG_BOOT_COMPLETED: 1328 operationId = sUsbOperationCount.incrementAndGet(); 1329 mBootCompleted = true; 1330 finishBoot(operationId); 1331 break; 1332 case MSG_USER_SWITCHED: { 1333 operationId = sUsbOperationCount.incrementAndGet(); 1334 if (mCurrentUser != msg.arg1) { 1335 if (DEBUG) { 1336 Slog.v(TAG, "Current user switched to " + msg.arg1); 1337 } 1338 mCurrentUser = msg.arg1; 1339 mScreenLocked = true; 1340 mScreenUnlockedFunctions = UsbManager.FUNCTION_NONE; 1341 if (mSettings != null) { 1342 mScreenUnlockedFunctions = UsbManager.usbFunctionsFromString( 1343 mSettings.getString(String.format(Locale.ENGLISH, 1344 UNLOCKED_CONFIG_PREF, mCurrentUser), "")); 1345 } 1346 setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); 1347 } 1348 break; 1349 } 1350 case MSG_ACCESSORY_MODE_ENTER_TIMEOUT: { 1351 operationId = sUsbOperationCount.incrementAndGet(); 1352 if (DEBUG) { 1353 Slog.v(TAG, "Accessory mode enter timeout: " + mConnected 1354 + " ,operationId: " + operationId); 1355 } 1356 if (!mConnected || (mCurrentFunctions & UsbManager.FUNCTION_ACCESSORY) == 0) { 1357 notifyAccessoryModeExit(operationId); 1358 } 1359 break; 1360 } 1361 case MSG_ACCESSORY_HANDSHAKE_TIMEOUT: { 1362 if (DEBUG) { 1363 Slog.v(TAG, "Accessory handshake timeout"); 1364 } 1365 if (mBootCompleted) { 1366 broadcastUsbAccessoryHandshake(); 1367 } else { 1368 if (DEBUG) Slog.v(TAG, "Pending broadcasting intent as " 1369 + "not boot completed yet."); 1370 mPendingBootAccessoryHandshakeBroadcast = true; 1371 } 1372 break; 1373 } 1374 case MSG_INCREASE_SENDSTRING_COUNT: { 1375 mSendStringCount = mSendStringCount + 1; 1376 } 1377 } 1378 } 1379 handlerInitDone(int operationId)1380 public abstract void handlerInitDone(int operationId); 1381 finishBoot(int operationId)1382 protected void finishBoot(int operationId) { 1383 if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) { 1384 if (mPendingBootBroadcast) { 1385 updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions)); 1386 mPendingBootBroadcast = false; 1387 } 1388 if (!mScreenLocked 1389 && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) { 1390 setScreenUnlockedFunctions(operationId); 1391 } else { 1392 setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); 1393 } 1394 if (mCurrentAccessory != null) { 1395 mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); 1396 broadcastUsbAccessoryHandshake(); 1397 } else if (mPendingBootAccessoryHandshakeBroadcast) { 1398 broadcastUsbAccessoryHandshake(); 1399 } 1400 1401 mPendingBootAccessoryHandshakeBroadcast = false; 1402 updateUsbNotification(false); 1403 updateAdbNotification(false); 1404 updateUsbFunctions(); 1405 } 1406 } 1407 isUsbDataTransferActive(long functions)1408 protected boolean isUsbDataTransferActive(long functions) { 1409 return (functions & UsbManager.FUNCTION_MTP) != 0 1410 || (functions & UsbManager.FUNCTION_PTP) != 0; 1411 } 1412 getCurrentAccessory()1413 public UsbAccessory getCurrentAccessory() { 1414 return mCurrentAccessory; 1415 } 1416 updateUsbGadgetHalVersion()1417 protected void updateUsbGadgetHalVersion() { 1418 sendMessage(MSG_UPDATE_HAL_VERSION, null); 1419 } 1420 updateUsbSpeed()1421 protected void updateUsbSpeed() { 1422 if (mCurrentGadgetHalVersion < UsbManager.GADGET_HAL_V1_0) { 1423 mUsbSpeed = UsbSpeed.UNKNOWN; 1424 return; 1425 } 1426 1427 if (mConnected && mConfigured) { 1428 sendMessage(MSG_UPDATE_USB_SPEED, null); 1429 } else { 1430 // clear USB speed due to disconnected 1431 mUsbSpeed = UsbSpeed.UNKNOWN; 1432 } 1433 1434 return; 1435 } 1436 updateUsbNotification(boolean force)1437 protected void updateUsbNotification(boolean force) { 1438 if (mNotificationManager == null || !mUseUsbNotification 1439 || ("0".equals(getSystemProperty("persist.charging.notify", "")))) { 1440 return; 1441 } 1442 1443 // Dont show the notification when connected to a USB peripheral 1444 // and the link does not support PR_SWAP and DR_SWAP 1445 if ((mHideUsbNotification || mInHostModeWithNoAccessoryConnected) 1446 && !mSupportsAllCombinations) { 1447 if (mUsbNotificationId != 0) { 1448 mNotificationManager.cancelAsUser(null, mUsbNotificationId, 1449 UserHandle.ALL); 1450 mUsbNotificationId = 0; 1451 Slog.d(TAG, "Clear notification"); 1452 } 1453 return; 1454 } 1455 1456 int id = 0; 1457 int titleRes = 0; 1458 Resources r = mContext.getResources(); 1459 CharSequence message = r.getText( 1460 com.android.internal.R.string.usb_notification_message); 1461 if (mAudioAccessoryConnected && !mAudioAccessorySupported) { 1462 titleRes = com.android.internal.R.string.usb_unsupported_audio_accessory_title; 1463 id = SystemMessage.NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED; 1464 } else if (mConnected) { 1465 if (mCurrentFunctions == UsbManager.FUNCTION_MTP) { 1466 titleRes = com.android.internal.R.string.usb_mtp_notification_title; 1467 id = SystemMessage.NOTE_USB_MTP; 1468 } else if (mCurrentFunctions == UsbManager.FUNCTION_PTP) { 1469 titleRes = com.android.internal.R.string.usb_ptp_notification_title; 1470 id = SystemMessage.NOTE_USB_PTP; 1471 } else if (mCurrentFunctions == UsbManager.FUNCTION_MIDI) { 1472 titleRes = com.android.internal.R.string.usb_midi_notification_title; 1473 id = SystemMessage.NOTE_USB_MIDI; 1474 } else if ((mCurrentFunctions == UsbManager.FUNCTION_RNDIS) 1475 || (mCurrentFunctions == UsbManager.FUNCTION_NCM)) { 1476 titleRes = com.android.internal.R.string.usb_tether_notification_title; 1477 id = SystemMessage.NOTE_USB_TETHER; 1478 } else if (mCurrentFunctions == UsbManager.FUNCTION_UVC) { 1479 titleRes = com.android.internal.R.string.usb_uvc_notification_title; 1480 id = SystemMessage.NOTE_USB_UVC; 1481 } else if (mCurrentFunctions == UsbManager.FUNCTION_ACCESSORY) { 1482 titleRes = com.android.internal.R.string.usb_accessory_notification_title; 1483 id = SystemMessage.NOTE_USB_ACCESSORY; 1484 } 1485 if (mSourcePower) { 1486 if (titleRes != 0) { 1487 message = r.getText( 1488 com.android.internal.R.string.usb_power_notification_message); 1489 } else { 1490 titleRes = com.android.internal.R.string.usb_supplying_notification_title; 1491 id = SystemMessage.NOTE_USB_SUPPLYING; 1492 } 1493 } else if (titleRes == 0) { 1494 titleRes = com.android.internal.R.string.usb_charging_notification_title; 1495 id = SystemMessage.NOTE_USB_CHARGING; 1496 } 1497 } else if (mSourcePower) { 1498 titleRes = com.android.internal.R.string.usb_supplying_notification_title; 1499 id = SystemMessage.NOTE_USB_SUPPLYING; 1500 } else if (mHostConnected && mSinkPower && (mUsbCharging || mUsbAccessoryConnected)) { 1501 titleRes = com.android.internal.R.string.usb_charging_notification_title; 1502 id = SystemMessage.NOTE_USB_CHARGING; 1503 } else if (mSinkPower && mConnectedToDataDisabledPort 1504 && mPowerBrickConnectionStatus != UsbPortStatus.POWER_BRICK_STATUS_CONNECTED) { 1505 // Show charging notification when USB Data is disabled on the port, and not 1506 // connected to a wall charger. 1507 titleRes = com.android.internal.R.string.usb_charging_notification_title; 1508 id = SystemMessage.NOTE_USB_CHARGING; 1509 } 1510 if (id != mUsbNotificationId || force) { 1511 // clear notification if title needs changing 1512 if (mUsbNotificationId != 0) { 1513 mNotificationManager.cancelAsUser(null, mUsbNotificationId, 1514 UserHandle.ALL); 1515 Slog.d(TAG, "Clear notification"); 1516 mUsbNotificationId = 0; 1517 } 1518 // Not relevant for automotive and watch. 1519 if ((mContext.getPackageManager().hasSystemFeature( 1520 PackageManager.FEATURE_AUTOMOTIVE) 1521 || mContext.getPackageManager().hasSystemFeature( 1522 PackageManager.FEATURE_WATCH)) 1523 && id == SystemMessage.NOTE_USB_CHARGING) { 1524 mUsbNotificationId = 0; 1525 return; 1526 } 1527 1528 if (id != 0) { 1529 CharSequence title = r.getText(titleRes); 1530 PendingIntent pi; 1531 String channel; 1532 1533 if (titleRes 1534 != com.android.internal.R.string 1535 .usb_unsupported_audio_accessory_title) { 1536 Intent intent = Intent.makeRestartActivityTask( 1537 new ComponentName("com.android.settings", 1538 "com.android.settings.Settings$UsbDetailsActivity")); 1539 // Simple notification clicks are immutable 1540 pi = PendingIntent.getActivityAsUser(mContext, 0, 1541 intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); 1542 channel = SystemNotificationChannels.USB; 1543 } else { 1544 final Intent intent = new Intent(); 1545 intent.setClassName("com.android.settings", 1546 "com.android.settings.HelpTrampoline"); 1547 intent.putExtra(Intent.EXTRA_TEXT, 1548 "help_url_audio_accessory_not_supported"); 1549 1550 if (mContext.getPackageManager().resolveActivity(intent, 0) != null) { 1551 // Simple notification clicks are immutable 1552 pi = PendingIntent.getActivity(mContext, 0, intent, 1553 PendingIntent.FLAG_IMMUTABLE); 1554 } else { 1555 pi = null; 1556 } 1557 1558 channel = SystemNotificationChannels.ALERTS; 1559 message = r.getText( 1560 com.android.internal.R.string 1561 .usb_unsupported_audio_accessory_message); 1562 } 1563 1564 Notification.Builder builder = new Notification.Builder(mContext, channel) 1565 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 1566 .setWhen(0) 1567 .setOngoing(true) 1568 .setTicker(title) 1569 .setDefaults(0) // please be quiet 1570 .setColor(mContext.getColor( 1571 com.android.internal.R.color 1572 .system_notification_accent_color)) 1573 .setContentTitle(title) 1574 .setContentText(message) 1575 .setContentIntent(pi) 1576 .setVisibility(Notification.VISIBILITY_PUBLIC); 1577 1578 if (titleRes 1579 == com.android.internal.R.string 1580 .usb_unsupported_audio_accessory_title) { 1581 builder.setStyle(new Notification.BigTextStyle() 1582 .bigText(message)); 1583 } 1584 Notification notification = builder.build(); 1585 1586 mNotificationManager.notifyAsUser(null, id, notification, 1587 UserHandle.ALL); 1588 Slog.d(TAG, "push notification:" + title); 1589 mUsbNotificationId = id; 1590 } 1591 } 1592 } 1593 isAdbEnabled()1594 protected boolean isAdbEnabled() { 1595 return LocalServices.getService(AdbManagerInternal.class) 1596 .isAdbEnabled(AdbTransportType.USB); 1597 } 1598 updateAdbNotification(boolean force)1599 protected void updateAdbNotification(boolean force) { 1600 if (mNotificationManager == null) return; 1601 final int id = SystemMessage.NOTE_ADB_ACTIVE; 1602 1603 if (isAdbEnabled() && mConnected) { 1604 if ("0".equals(getSystemProperty("persist.adb.notify", ""))) return; 1605 1606 if (force && mAdbNotificationShown) { 1607 mAdbNotificationShown = false; 1608 mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); 1609 } 1610 1611 if (!mAdbNotificationShown) { 1612 Notification notification = AdbNotifications.createNotification(mContext, 1613 AdbTransportType.USB); 1614 mAdbNotificationShown = true; 1615 mNotificationManager.notifyAsUser(null, id, notification, UserHandle.ALL); 1616 } 1617 } else if (mAdbNotificationShown) { 1618 mAdbNotificationShown = false; 1619 mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); 1620 } 1621 } 1622 isTv()1623 private boolean isTv() { 1624 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK); 1625 } 1626 getChargingFunctions()1627 protected long getChargingFunctions() { 1628 // if ADB is enabled, reset functions to ADB 1629 // else enable MTP as usual. 1630 if (isAdbEnabled()) { 1631 return UsbManager.FUNCTION_ADB; 1632 } else { 1633 return UsbManager.FUNCTION_MTP; 1634 } 1635 } 1636 setSystemProperty(String prop, String val)1637 protected void setSystemProperty(String prop, String val) { 1638 SystemProperties.set(prop, val); 1639 } 1640 getSystemProperty(String prop, String def)1641 protected String getSystemProperty(String prop, String def) { 1642 return SystemProperties.get(prop, def); 1643 } 1644 putGlobalSettings(ContentResolver contentResolver, String setting, int val)1645 protected void putGlobalSettings(ContentResolver contentResolver, String setting, int val) { 1646 Settings.Global.putInt(contentResolver, setting, val); 1647 } 1648 getEnabledFunctions()1649 public long getEnabledFunctions() { 1650 return mCurrentFunctions; 1651 } 1652 getScreenUnlockedFunctions()1653 public long getScreenUnlockedFunctions() { 1654 return mScreenUnlockedFunctions; 1655 } 1656 getUsbSpeed()1657 public int getUsbSpeed() { 1658 return mUsbSpeed; 1659 } 1660 getGadgetHalVersion()1661 public int getGadgetHalVersion() { 1662 return mCurrentGadgetHalVersion; 1663 } 1664 1665 /** 1666 * Dump a functions mask either as proto-enums (if dumping to proto) or a string (if dumping 1667 * to a print writer) 1668 */ dumpFunctions(DualDumpOutputStream dump, String idName, long id, long functions)1669 private void dumpFunctions(DualDumpOutputStream dump, String idName, long id, 1670 long functions) { 1671 // UsbHandlerProto.UsbFunction matches GadgetFunction 1672 for (int i = 0; i < 63; i++) { 1673 if ((functions & (1L << i)) != 0) { 1674 if (dump.isProto()) { 1675 dump.write(idName, id, 1L << i); 1676 } else { 1677 dump.write(idName, id, GadgetFunction.toString(1L << i)); 1678 } 1679 } 1680 } 1681 } 1682 dump(DualDumpOutputStream dump, String idName, long id)1683 public void dump(DualDumpOutputStream dump, String idName, long id) { 1684 long token = dump.start(idName, id); 1685 1686 dumpFunctions(dump, "current_functions", UsbHandlerProto.CURRENT_FUNCTIONS, 1687 mCurrentFunctions); 1688 dump.write("current_functions_applied", UsbHandlerProto.CURRENT_FUNCTIONS_APPLIED, 1689 mCurrentFunctionsApplied); 1690 dumpFunctions(dump, "screen_unlocked_functions", 1691 UsbHandlerProto.SCREEN_UNLOCKED_FUNCTIONS, mScreenUnlockedFunctions); 1692 dump.write("screen_locked", UsbHandlerProto.SCREEN_LOCKED, mScreenLocked); 1693 dump.write("connected", UsbHandlerProto.CONNECTED, mConnected); 1694 dump.write("configured", UsbHandlerProto.CONFIGURED, mConfigured); 1695 if (mCurrentAccessory != null) { 1696 writeAccessory(dump, "current_accessory", UsbHandlerProto.CURRENT_ACCESSORY, 1697 mCurrentAccessory); 1698 } 1699 dump.write("host_connected", UsbHandlerProto.HOST_CONNECTED, mHostConnected); 1700 dump.write("source_power", UsbHandlerProto.SOURCE_POWER, mSourcePower); 1701 dump.write("sink_power", UsbHandlerProto.SINK_POWER, mSinkPower); 1702 dump.write("usb_charging", UsbHandlerProto.USB_CHARGING, mUsbCharging); 1703 dump.write("hide_usb_notification", UsbHandlerProto.HIDE_USB_NOTIFICATION, 1704 mHideUsbNotification); 1705 dump.write("audio_accessory_connected", UsbHandlerProto.AUDIO_ACCESSORY_CONNECTED, 1706 mAudioAccessoryConnected); 1707 1708 try { 1709 writeStringIfNotNull(dump, "kernel_state", UsbHandlerProto.KERNEL_STATE, 1710 FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); 1711 } catch (FileNotFoundException exNotFound) { 1712 Slog.w(TAG, "Ignore missing legacy kernel path in bugreport dump: " 1713 + "kernel state:" + STATE_PATH); 1714 } catch (Exception e) { 1715 Slog.e(TAG, "Could not read kernel state", e); 1716 } 1717 1718 try { 1719 writeStringIfNotNull(dump, "kernel_function_list", 1720 UsbHandlerProto.KERNEL_FUNCTION_LIST, 1721 FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); 1722 } catch (FileNotFoundException exNotFound) { 1723 Slog.w(TAG, "Ignore missing legacy kernel path in bugreport dump: " 1724 + "kernel function list:" + FUNCTIONS_PATH); 1725 } catch (Exception e) { 1726 Slog.e(TAG, "Could not read kernel function list", e); 1727 } 1728 1729 dump.end(token); 1730 } 1731 1732 /** 1733 * Evaluates USB function policies and applies the change accordingly. 1734 */ setEnabledFunctions(long functions, boolean forceRestart, int operationId)1735 protected abstract void setEnabledFunctions(long functions, 1736 boolean forceRestart, int operationId); 1737 setAccessoryUEventTime(long accessoryConnectionStartTime)1738 public void setAccessoryUEventTime(long accessoryConnectionStartTime) { 1739 mAccessoryConnectionStartTime = accessoryConnectionStartTime; 1740 } 1741 setStartAccessoryTrue()1742 public void setStartAccessoryTrue() { 1743 mStartAccessory = true; 1744 } 1745 resetUsbAccessoryHandshakeDebuggingInfo()1746 public void resetUsbAccessoryHandshakeDebuggingInfo() { 1747 mAccessoryConnectionStartTime = 0L; 1748 mSendStringCount = 0; 1749 mStartAccessory = false; 1750 } 1751 setCurrentUsbFunctionsCb(long functions, int status, int mRequest, long mFunctions, boolean mChargingFunctions)1752 public abstract void setCurrentUsbFunctionsCb(long functions, 1753 int status, int mRequest, long mFunctions, boolean mChargingFunctions); 1754 getUsbSpeedCb(int speed)1755 public abstract void getUsbSpeedCb(int speed); 1756 resetCb(int status)1757 public abstract void resetCb(int status); 1758 } 1759 1760 private static final class UsbHandlerLegacy extends UsbHandler { 1761 /** 1762 * The non-persistent property which stores the current USB settings. 1763 */ 1764 private static final String USB_CONFIG_PROPERTY = "sys.usb.config"; 1765 1766 /** 1767 * The non-persistent property which stores the current USB actual state. 1768 */ 1769 private static final String USB_STATE_PROPERTY = "sys.usb.state"; 1770 1771 private HashMap<String, HashMap<String, Pair<String, String>>> mOemModeMap; 1772 private String mCurrentOemFunctions; 1773 private String mCurrentFunctionsStr; 1774 private boolean mUsbDataUnlocked; 1775 1776 /** 1777 * Keeps track of the latest setCurrentUsbFunctions request number. 1778 */ 1779 private int mCurrentRequest = 0; 1780 UsbHandlerLegacy(Looper looper, Context context, UsbDeviceManager deviceManager, UsbAlsaManager alsaManager, UsbPermissionManager permissionManager)1781 UsbHandlerLegacy(Looper looper, Context context, UsbDeviceManager deviceManager, 1782 UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) { 1783 super(looper, context, deviceManager, alsaManager, permissionManager); 1784 try { 1785 readOemUsbOverrideConfig(context); 1786 // Restore default functions. 1787 mCurrentOemFunctions = getSystemProperty(getPersistProp(false), 1788 UsbManager.USB_FUNCTION_NONE); 1789 if (isNormalBoot()) { 1790 mCurrentFunctionsStr = getSystemProperty(USB_CONFIG_PROPERTY, 1791 UsbManager.USB_FUNCTION_NONE); 1792 mCurrentFunctionsApplied = mCurrentFunctionsStr.equals( 1793 getSystemProperty(USB_STATE_PROPERTY, UsbManager.USB_FUNCTION_NONE)); 1794 } else { 1795 mCurrentFunctionsStr = getSystemProperty(getPersistProp(true), 1796 UsbManager.USB_FUNCTION_NONE); 1797 mCurrentFunctionsApplied = getSystemProperty(USB_CONFIG_PROPERTY, 1798 UsbManager.USB_FUNCTION_NONE).equals( 1799 getSystemProperty(USB_STATE_PROPERTY, UsbManager.USB_FUNCTION_NONE)); 1800 } 1801 mCurrentFunctions = UsbManager.FUNCTION_NONE; 1802 mCurrentUsbFunctionsReceived = true; 1803 1804 mUsbSpeed = UsbSpeed.UNKNOWN; 1805 mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_NOT_SUPPORTED; 1806 1807 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); 1808 updateState(state); 1809 } catch (Exception e) { 1810 Slog.e(TAG, "Error initializing UsbHandler", e); 1811 } 1812 } 1813 1814 @Override handlerInitDone(int operationId)1815 public void handlerInitDone(int operationId) { 1816 } 1817 readOemUsbOverrideConfig(Context context)1818 private void readOemUsbOverrideConfig(Context context) { 1819 String[] configList = context.getResources().getStringArray( 1820 com.android.internal.R.array.config_oemUsbModeOverride); 1821 1822 if (configList != null) { 1823 for (String config : configList) { 1824 String[] items = config.split(":"); 1825 if (items.length == 3 || items.length == 4) { 1826 if (mOemModeMap == null) { 1827 mOemModeMap = new HashMap<>(); 1828 } 1829 HashMap<String, Pair<String, String>> overrideMap = 1830 mOemModeMap.get(items[0]); 1831 if (overrideMap == null) { 1832 overrideMap = new HashMap<>(); 1833 mOemModeMap.put(items[0], overrideMap); 1834 } 1835 1836 // Favoring the first combination if duplicate exists 1837 if (!overrideMap.containsKey(items[1])) { 1838 if (items.length == 3) { 1839 overrideMap.put(items[1], new Pair<>(items[2], "")); 1840 } else { 1841 overrideMap.put(items[1], new Pair<>(items[2], items[3])); 1842 } 1843 } 1844 } 1845 } 1846 } 1847 } 1848 applyOemOverrideFunction(String usbFunctions)1849 private String applyOemOverrideFunction(String usbFunctions) { 1850 if ((usbFunctions == null) || (mOemModeMap == null)) { 1851 return usbFunctions; 1852 } 1853 1854 String bootMode = getSystemProperty(BOOT_MODE_PROPERTY, "unknown"); 1855 Slog.d(TAG, "applyOemOverride usbfunctions=" + usbFunctions + " bootmode=" + bootMode); 1856 1857 Map<String, Pair<String, String>> overridesMap = 1858 mOemModeMap.get(bootMode); 1859 // Check to ensure that the oem is not overriding in the normal 1860 // boot mode 1861 if (overridesMap != null && !(bootMode.equals(NORMAL_BOOT) 1862 || bootMode.equals("unknown"))) { 1863 Pair<String, String> overrideFunctions = 1864 overridesMap.get(usbFunctions); 1865 if (overrideFunctions != null) { 1866 Slog.d(TAG, "OEM USB override: " + usbFunctions 1867 + " ==> " + overrideFunctions.first 1868 + " persist across reboot " 1869 + overrideFunctions.second); 1870 if (!overrideFunctions.second.equals("")) { 1871 String newFunction; 1872 if (isAdbEnabled()) { 1873 newFunction = addFunction(overrideFunctions.second, 1874 UsbManager.USB_FUNCTION_ADB); 1875 } else { 1876 newFunction = overrideFunctions.second; 1877 } 1878 Slog.d(TAG, "OEM USB override persisting: " + newFunction + "in prop: " 1879 + getPersistProp(false)); 1880 setSystemProperty(getPersistProp(false), newFunction); 1881 } 1882 return overrideFunctions.first; 1883 } else if (isAdbEnabled()) { 1884 String newFunction = addFunction(UsbManager.USB_FUNCTION_NONE, 1885 UsbManager.USB_FUNCTION_ADB); 1886 setSystemProperty(getPersistProp(false), newFunction); 1887 } else { 1888 setSystemProperty(getPersistProp(false), UsbManager.USB_FUNCTION_NONE); 1889 } 1890 } 1891 // return passed in functions as is. 1892 return usbFunctions; 1893 } 1894 waitForState(String state)1895 private boolean waitForState(String state) { 1896 // wait for the transition to complete. 1897 // give up after 1 second. 1898 String value = null; 1899 for (int i = 0; i < 20; i++) { 1900 // State transition is done when sys.usb.state is set to the new configuration 1901 value = getSystemProperty(USB_STATE_PROPERTY, ""); 1902 if (state.equals(value)) return true; 1903 SystemClock.sleep(50); 1904 } 1905 Slog.e(TAG, "waitForState(" + state + ") FAILED: got " + value); 1906 return false; 1907 } 1908 setUsbConfig(String config)1909 private void setUsbConfig(String config) { 1910 if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); 1911 /** 1912 * set the new configuration 1913 * we always set it due to b/23631400, where adbd was getting killed 1914 * and not restarted due to property timeouts on some devices 1915 */ 1916 setSystemProperty(USB_CONFIG_PROPERTY, config); 1917 } 1918 1919 @Override setEnabledFunctions(long usbFunctions, boolean forceRestart, int operationId)1920 protected void setEnabledFunctions(long usbFunctions, 1921 boolean forceRestart, int operationId) { 1922 boolean usbDataUnlocked = isUsbDataTransferActive(usbFunctions); 1923 if (DEBUG) { 1924 Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions + 1925 " ,forceRestart=" + forceRestart + 1926 " ,usbDataUnlocked=" + usbDataUnlocked + 1927 " ,operationId=" + operationId); 1928 } 1929 1930 if (usbDataUnlocked != mUsbDataUnlocked) { 1931 mUsbDataUnlocked = usbDataUnlocked; 1932 updateUsbNotification(false); 1933 forceRestart = true; 1934 } 1935 1936 /** 1937 * Try to set the enabled functions. 1938 */ 1939 final long oldFunctions = mCurrentFunctions; 1940 final boolean oldFunctionsApplied = mCurrentFunctionsApplied; 1941 if (trySetEnabledFunctions(usbFunctions, forceRestart)) { 1942 return; 1943 } 1944 1945 /** 1946 * Didn't work. Try to revert changes. 1947 * We always reapply the policy in case certain constraints changed such as 1948 * user restrictions independently of any other new functions we were 1949 * trying to activate. 1950 */ 1951 if (oldFunctionsApplied && oldFunctions != usbFunctions) { 1952 Slog.e(TAG, "Failsafe 1: Restoring previous USB functions."); 1953 if (trySetEnabledFunctions(oldFunctions, false)) { 1954 return; 1955 } 1956 } 1957 1958 /** 1959 * Still didn't work. Try to restore the default functions. 1960 */ 1961 Slog.e(TAG, "Failsafe 2: Restoring default USB functions."); 1962 if (trySetEnabledFunctions(UsbManager.FUNCTION_NONE, false)) { 1963 return; 1964 } 1965 1966 /** 1967 * Now we're desperate. Ignore the default functions. 1968 * Try to get ADB working if enabled. 1969 */ 1970 Slog.e(TAG, "Failsafe 3: Restoring empty function list (with ADB if enabled)."); 1971 if (trySetEnabledFunctions(UsbManager.FUNCTION_NONE, false)) { 1972 return; 1973 } 1974 1975 /** 1976 * Ouch. 1977 */ 1978 Slog.e(TAG, "Unable to set any USB functions!"); 1979 } 1980 isNormalBoot()1981 private boolean isNormalBoot() { 1982 String bootMode = getSystemProperty(BOOT_MODE_PROPERTY, "unknown"); 1983 return bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown"); 1984 } 1985 applyAdbFunction(String functions)1986 protected String applyAdbFunction(String functions) { 1987 // Do not pass null pointer to the UsbManager. 1988 // There isn't a check there. 1989 if (functions == null) { 1990 functions = ""; 1991 } 1992 if (isAdbEnabled()) { 1993 functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); 1994 } else { 1995 functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); 1996 } 1997 return functions; 1998 } 1999 trySetEnabledFunctions(long usbFunctions, boolean forceRestart)2000 private boolean trySetEnabledFunctions(long usbFunctions, boolean forceRestart) { 2001 String functions = null; 2002 if (usbFunctions != UsbManager.FUNCTION_NONE) { 2003 functions = UsbManager.usbFunctionsToString(usbFunctions); 2004 } 2005 mCurrentFunctions = usbFunctions; 2006 if (functions == null || applyAdbFunction(functions) 2007 .equals(UsbManager.USB_FUNCTION_NONE)) { 2008 functions = UsbManager.usbFunctionsToString(getChargingFunctions()); 2009 } 2010 functions = applyAdbFunction(functions); 2011 2012 String oemFunctions = applyOemOverrideFunction(functions); 2013 2014 if (!isNormalBoot() && !mCurrentFunctionsStr.equals(functions)) { 2015 setSystemProperty(getPersistProp(true), functions); 2016 } 2017 2018 if ((!functions.equals(oemFunctions) 2019 && !mCurrentOemFunctions.equals(oemFunctions)) 2020 || !mCurrentFunctionsStr.equals(functions) 2021 || !mCurrentFunctionsApplied 2022 || forceRestart) { 2023 mCurrentFunctionsStr = functions; 2024 mCurrentOemFunctions = oemFunctions; 2025 mCurrentFunctionsApplied = false; 2026 2027 /** 2028 * Kick the USB stack to close existing connections. 2029 */ 2030 setUsbConfig(UsbManager.USB_FUNCTION_NONE); 2031 2032 if (!waitForState(UsbManager.USB_FUNCTION_NONE)) { 2033 Slog.e(TAG, "Failed to kick USB config"); 2034 return false; 2035 } 2036 2037 /** 2038 * Set the new USB configuration. 2039 */ 2040 setUsbConfig(oemFunctions); 2041 2042 if (mBootCompleted 2043 && (containsFunction(functions, UsbManager.USB_FUNCTION_MTP) 2044 || containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) { 2045 /** 2046 * Start up dependent services. 2047 */ 2048 updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions)); 2049 } 2050 2051 if (!waitForState(oemFunctions)) { 2052 Slog.e(TAG, "Failed to switch USB config to " + functions); 2053 return false; 2054 } 2055 2056 mCurrentFunctionsApplied = true; 2057 } 2058 return true; 2059 } 2060 getPersistProp(boolean functions)2061 private String getPersistProp(boolean functions) { 2062 String bootMode = getSystemProperty(BOOT_MODE_PROPERTY, "unknown"); 2063 String persistProp = USB_PERSISTENT_CONFIG_PROPERTY; 2064 if (!(bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown"))) { 2065 if (functions) { 2066 persistProp = "persist.sys.usb." + bootMode + ".func"; 2067 } else { 2068 persistProp = "persist.sys.usb." + bootMode + ".config"; 2069 } 2070 } 2071 return persistProp; 2072 } 2073 addFunction(String functions, String function)2074 private static String addFunction(String functions, String function) { 2075 if (UsbManager.USB_FUNCTION_NONE.equals(functions)) { 2076 return function; 2077 } 2078 if (!containsFunction(functions, function)) { 2079 if (functions.length() > 0) { 2080 functions += ","; 2081 } 2082 functions += function; 2083 } 2084 return functions; 2085 } 2086 removeFunction(String functions, String function)2087 private static String removeFunction(String functions, String function) { 2088 String[] split = functions.split(","); 2089 for (int i = 0; i < split.length; i++) { 2090 if (function.equals(split[i])) { 2091 split[i] = null; 2092 } 2093 } 2094 if (split.length == 1 && split[0] == null) { 2095 return UsbManager.USB_FUNCTION_NONE; 2096 } 2097 StringBuilder builder = new StringBuilder(); 2098 for (int i = 0; i < split.length; i++) { 2099 String s = split[i]; 2100 if (s != null) { 2101 if (builder.length() > 0) { 2102 builder.append(","); 2103 } 2104 builder.append(s); 2105 } 2106 } 2107 return builder.toString(); 2108 } 2109 containsFunction(String functions, String function)2110 static boolean containsFunction(String functions, String function) { 2111 int index = functions.indexOf(function); 2112 if (index < 0) return false; 2113 if (index > 0 && functions.charAt(index - 1) != ',') return false; 2114 int charAfter = index + function.length(); 2115 if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false; 2116 return true; 2117 } 2118 2119 /** 2120 * This callback function is only applicable for USB Gadget HAL, 2121 * USBHandlerLegacy does not supported it. 2122 */ 2123 @Override setCurrentUsbFunctionsCb(long functions, int status, int mRequest, long mFunctions, boolean mChargingFunctions)2124 public void setCurrentUsbFunctionsCb(long functions, 2125 int status, int mRequest, long mFunctions, boolean mChargingFunctions){ 2126 } 2127 2128 /** 2129 * This callback function is only applicable for USB Gadget HAL, 2130 * USBHandlerLegacy does not supported it. 2131 */ 2132 @Override getUsbSpeedCb(int speed)2133 public void getUsbSpeedCb(int speed){ 2134 } 2135 2136 /** 2137 * This callback function is only applicable for USB Gadget HAL, 2138 * USBHandlerLegacy does not supported it. 2139 */ 2140 @Override resetCb(int status)2141 public void resetCb(int status){ 2142 } 2143 } 2144 2145 private static final class UsbHandlerHal extends UsbHandler { 2146 2147 private final Object mGadgetProxyLock = new Object(); 2148 2149 /** 2150 * Cookie sent for usb gadget hal death notification. 2151 */ 2152 private static final int USB_GADGET_HAL_DEATH_COOKIE = 2000; 2153 2154 /** 2155 * Keeps track of the latest setCurrentUsbFunctions request number. 2156 */ 2157 private int mCurrentRequest = 0; 2158 2159 /** 2160 * The maximum time for which the UsbDeviceManager would wait once 2161 * setCurrentUsbFunctions is called. 2162 */ 2163 private static final int SET_FUNCTIONS_TIMEOUT_MS = 3000; 2164 2165 /** 2166 * Conseration leeway to make sure that the hal callback arrives before 2167 * SET_FUNCTIONS_TIMEOUT_MS expires. If the callback does not arrive 2168 * within SET_FUNCTIONS_TIMEOUT_MS, UsbDeviceManager retries enabling 2169 * default functions. 2170 */ 2171 private static final int SET_FUNCTIONS_LEEWAY_MS = 500; 2172 2173 /** 2174 * While switching functions, a disconnect is excpect as the usb gadget 2175 * us torn down and brought back up. Wait for SET_FUNCTIONS_TIMEOUT_MS + 2176 * ENUMERATION_TIME_OUT_MS before switching back to default fumctions when 2177 * switching functions. 2178 */ 2179 private static final int ENUMERATION_TIME_OUT_MS = 2000; 2180 2181 /** 2182 * Gadget HAL fully qualified instance name for registering for ServiceNotification. 2183 */ 2184 protected static final String GADGET_HAL_FQ_NAME = 2185 "android.hardware.usb.gadget@1.0::IUsbGadget"; 2186 2187 protected boolean mCurrentUsbFunctionsRequested; 2188 UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager, UsbAlsaManager alsaManager, UsbPermissionManager permissionManager)2189 UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager, 2190 UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) { 2191 super(looper, context, deviceManager, alsaManager, permissionManager); 2192 int operationId = sUsbOperationCount.incrementAndGet(); 2193 try { 2194 2195 synchronized (mGadgetProxyLock) { 2196 mCurrentFunctions = UsbManager.FUNCTION_NONE; 2197 mCurrentUsbFunctionsRequested = true; 2198 mUsbSpeed = UsbSpeed.UNKNOWN; 2199 mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0; 2200 updateUsbGadgetHalVersion(); 2201 } 2202 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); 2203 updateState(state); 2204 } catch (NoSuchElementException e) { 2205 Slog.e(TAG, "Usb gadget hal not found", e); 2206 } catch (Exception e) { 2207 Slog.e(TAG, "Error initializing UsbHandler", e); 2208 } 2209 } 2210 2211 2212 final class UsbGadgetDeathRecipient implements HwBinder.DeathRecipient { 2213 @Override serviceDied(long cookie)2214 public void serviceDied(long cookie) { 2215 if (cookie == USB_GADGET_HAL_DEATH_COOKIE) { 2216 Slog.e(TAG, "Usb Gadget hal service died cookie: " + cookie); 2217 synchronized (mGadgetProxyLock) { 2218 mUsbGadgetHal = null; 2219 } 2220 } 2221 } 2222 } 2223 2224 final class ServiceNotification extends IServiceNotification.Stub { 2225 @Override onRegistration(String fqName, String name, boolean preexisting)2226 public void onRegistration(String fqName, String name, boolean preexisting) { 2227 Slog.i(TAG, "Usb gadget hal service started " + fqName + " " + name); 2228 if (!fqName.equals(GADGET_HAL_FQ_NAME)) { 2229 Slog.e(TAG, "fqName does not match"); 2230 return; 2231 } 2232 2233 sendMessage(MSG_GADGET_HAL_REGISTERED, preexisting); 2234 } 2235 } 2236 2237 @Override handleMessage(Message msg)2238 public void handleMessage(Message msg) { 2239 switch (msg.what) { 2240 case MSG_SET_CHARGING_FUNCTIONS: 2241 int operationId = sUsbOperationCount.incrementAndGet(); 2242 setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); 2243 break; 2244 case MSG_SET_FUNCTIONS_TIMEOUT: 2245 operationId = sUsbOperationCount.incrementAndGet(); 2246 Slog.e(TAG, "Set functions timed out! no reply from usb hal" 2247 + " ,operationId:" + operationId); 2248 if (msg.arg1 != 1) { 2249 // Set this since default function may be selected from Developer options 2250 setEnabledFunctions(mScreenUnlockedFunctions, false, operationId); 2251 } 2252 break; 2253 case MSG_GET_CURRENT_USB_FUNCTIONS: 2254 Slog.i(TAG, "processing MSG_GET_CURRENT_USB_FUNCTIONS"); 2255 mCurrentUsbFunctionsReceived = true; 2256 operationId = msg.arg2; 2257 2258 if (mCurrentUsbFunctionsRequested) { 2259 Slog.i(TAG, "updating mCurrentFunctions"); 2260 // Mask out adb, since it is stored in mAdbEnabled 2261 mCurrentFunctions = ((Long) msg.obj) & ~UsbManager.FUNCTION_ADB; 2262 Slog.i(TAG, 2263 "mCurrentFunctions:" + mCurrentFunctions + "applied:" + msg.arg1); 2264 mCurrentFunctionsApplied = msg.arg1 == 1; 2265 } 2266 finishBoot(operationId); 2267 break; 2268 case MSG_FUNCTION_SWITCH_TIMEOUT: 2269 /** 2270 * Dont force to default when the configuration is already set to default. 2271 */ 2272 operationId = sUsbOperationCount.incrementAndGet(); 2273 if (msg.arg1 != 1) { 2274 // Set this since default function may be selected from Developer options 2275 setEnabledFunctions(mScreenUnlockedFunctions, false, operationId); 2276 } 2277 break; 2278 case MSG_GADGET_HAL_REGISTERED: 2279 boolean preexisting = msg.arg1 == 1; 2280 operationId = sUsbOperationCount.incrementAndGet(); 2281 synchronized (mGadgetProxyLock) { 2282 try { 2283 mUsbGadgetHal = UsbGadgetHalInstance.getInstance(mUsbDeviceManager, 2284 null); 2285 if (!mCurrentFunctionsApplied && !preexisting) { 2286 setEnabledFunctions(mCurrentFunctions, false, operationId); 2287 } 2288 } catch (NoSuchElementException e) { 2289 Slog.e(TAG, "Usb gadget hal not found", e); 2290 } 2291 } 2292 break; 2293 case MSG_RESET_USB_GADGET: 2294 operationId = sUsbOperationCount.incrementAndGet(); 2295 synchronized (mGadgetProxyLock) { 2296 if (mUsbGadgetHal == null) { 2297 Slog.e(TAG, "reset Usb Gadget mUsbGadgetHal is null"); 2298 break; 2299 } 2300 2301 try { 2302 // MSG_ACCESSORY_MODE_ENTER_TIMEOUT has to be removed to allow exiting 2303 // AOAP mode during resetUsbGadget. 2304 removeMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT); 2305 if (mConfigured) { 2306 mResetUsbGadgetDisableDebounce = true; 2307 } 2308 mUsbGadgetHal.reset(operationId); 2309 } catch (Exception e) { 2310 Slog.e(TAG, "reset Usb Gadget failed", e); 2311 mResetUsbGadgetDisableDebounce = false; 2312 } 2313 } 2314 break; 2315 case MSG_UPDATE_USB_SPEED: 2316 operationId = sUsbOperationCount.incrementAndGet(); 2317 if (mUsbGadgetHal == null) { 2318 Slog.e(TAG, "mGadgetHal is null, operationId:" + operationId); 2319 break; 2320 } 2321 2322 try { 2323 mUsbGadgetHal.getUsbSpeed(operationId); 2324 } catch (Exception e) { 2325 Slog.e(TAG, "get UsbSpeed failed", e); 2326 } 2327 break; 2328 case MSG_UPDATE_HAL_VERSION: 2329 if (mUsbGadgetHal == null) { 2330 Slog.e(TAG, "mUsbGadgetHal is null"); 2331 break; 2332 } 2333 else { 2334 try { 2335 mCurrentGadgetHalVersion = mUsbGadgetHal.getGadgetHalVersion(); 2336 } catch (RemoteException e) { 2337 Slog.e(TAG, "update Usb gadget version failed", e); 2338 } 2339 } 2340 break; 2341 default: 2342 super.handleMessage(msg); 2343 } 2344 } 2345 2346 @Override setCurrentUsbFunctionsCb(long functions, int status, int mRequest, long mFunctions, boolean mChargingFunctions)2347 public void setCurrentUsbFunctionsCb(long functions, 2348 int status, int mRequest, long mFunctions, boolean mChargingFunctions) { 2349 2350 if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT) 2351 || (mFunctions != functions)) { 2352 return; 2353 } 2354 2355 removeMessages(MSG_SET_FUNCTIONS_TIMEOUT); 2356 Slog.i(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status); 2357 if (status == Status.SUCCESS) { 2358 mCurrentFunctionsApplied = true; 2359 } else if (!mChargingFunctions) { 2360 Slog.e(TAG, "Setting default fuctions"); 2361 sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS); 2362 } 2363 } 2364 2365 @Override getUsbSpeedCb(int speed)2366 public void getUsbSpeedCb(int speed) { 2367 mUsbSpeed = speed; 2368 } 2369 2370 @Override resetCb(int status)2371 public void resetCb(int status) { 2372 if (status != Status.SUCCESS) 2373 Slog.e(TAG, "resetCb fail"); 2374 } 2375 setUsbConfig(long config, boolean chargingFunctions, int operationId)2376 private void setUsbConfig(long config, boolean chargingFunctions, int operationId) { 2377 if (true) Slog.d(TAG, "setUsbConfig(" + config + ") request:" + ++mCurrentRequest); 2378 /** 2379 * Cancel any ongoing requests, if present. 2380 */ 2381 removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT); 2382 removeMessages(MSG_SET_FUNCTIONS_TIMEOUT); 2383 removeMessages(MSG_SET_CHARGING_FUNCTIONS); 2384 2385 synchronized (mGadgetProxyLock) { 2386 if (mUsbGadgetHal == null) { 2387 Slog.e(TAG, "setUsbConfig mUsbGadgetHal is null"); 2388 return; 2389 } 2390 try { 2391 if ((config & UsbManager.FUNCTION_ADB) != 0) { 2392 /** 2393 * Start adbd if ADB function is included in the configuration. 2394 */ 2395 LocalServices.getService(AdbManagerInternal.class) 2396 .startAdbdForTransport(AdbTransportType.USB); 2397 } else { 2398 /** 2399 * Stop adbd otherwise 2400 */ 2401 LocalServices.getService(AdbManagerInternal.class) 2402 .stopAdbdForTransport(AdbTransportType.USB); 2403 } 2404 mUsbGadgetHal.setCurrentUsbFunctions(mCurrentRequest, 2405 config, chargingFunctions, 2406 SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS, operationId); 2407 sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions, 2408 SET_FUNCTIONS_TIMEOUT_MS); 2409 if (mConnected) { 2410 // Only queue timeout of enumeration when the USB is connected 2411 sendMessageDelayed(MSG_FUNCTION_SWITCH_TIMEOUT, chargingFunctions, 2412 SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS); 2413 } 2414 if (DEBUG) Slog.d(TAG, "timeout message queued"); 2415 } catch (Exception e) {//RemoteException e) { 2416 Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e); 2417 } 2418 } 2419 } 2420 2421 @Override setEnabledFunctions(long functions, boolean forceRestart, int operationId)2422 protected void setEnabledFunctions(long functions, boolean forceRestart, int operationId) { 2423 if (DEBUG) { 2424 Slog.d(TAG, "setEnabledFunctionsi " + 2425 "functions=" + functions + 2426 ", forceRestart=" + forceRestart + 2427 ", operationId=" + operationId); 2428 } 2429 if (mCurrentGadgetHalVersion < UsbManager.GADGET_HAL_V1_2) { 2430 if ((functions & UsbManager.FUNCTION_NCM) != 0) { 2431 Slog.e(TAG, "Could not set unsupported function for the GadgetHal"); 2432 return; 2433 } 2434 } 2435 if (mCurrentFunctions != functions 2436 || !mCurrentFunctionsApplied 2437 || forceRestart) { 2438 Slog.i(TAG, "Setting USB config to " + UsbManager.usbFunctionsToString(functions)); 2439 mCurrentFunctions = functions; 2440 mCurrentFunctionsApplied = false; 2441 // set the flag to false as that would be stale value 2442 mCurrentUsbFunctionsRequested = false; 2443 2444 boolean chargingFunctions = functions == UsbManager.FUNCTION_NONE; 2445 functions = getAppliedFunctions(functions); 2446 2447 // Set the new USB configuration. 2448 setUsbConfig(functions, chargingFunctions, operationId); 2449 2450 if (mBootCompleted && isUsbDataTransferActive(functions)) { 2451 // Start up dependent services. 2452 updateUsbStateBroadcastIfNeeded(functions); 2453 } 2454 } 2455 } 2456 2457 @Override handlerInitDone(int operationId)2458 public void handlerInitDone(int operationId) { 2459 mUsbGadgetHal.getCurrentUsbFunctions(operationId); 2460 } 2461 } 2462 2463 /* returns the currently attached USB accessory */ getCurrentAccessory()2464 public UsbAccessory getCurrentAccessory() { 2465 return mHandler.getCurrentAccessory(); 2466 } 2467 2468 /** 2469 * opens the currently attached USB accessory. 2470 * 2471 * @param accessory accessory to be openened. 2472 * @param uid Uid of the caller 2473 */ openAccessory(UsbAccessory accessory, UsbUserPermissionManager permissions, int pid, int uid)2474 public ParcelFileDescriptor openAccessory(UsbAccessory accessory, 2475 UsbUserPermissionManager permissions, int pid, int uid) { 2476 UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); 2477 if (currentAccessory == null) { 2478 throw new IllegalArgumentException("no accessory attached"); 2479 } 2480 if (!currentAccessory.equals(accessory)) { 2481 String error = accessory.toString() 2482 + " does not match current accessory " 2483 + currentAccessory; 2484 throw new IllegalArgumentException(error); 2485 } 2486 permissions.checkPermission(accessory, pid, uid); 2487 return nativeOpenAccessory(); 2488 } 2489 getCurrentFunctions()2490 public long getCurrentFunctions() { 2491 return mHandler.getEnabledFunctions(); 2492 } 2493 getCurrentUsbSpeed()2494 public int getCurrentUsbSpeed() { 2495 return mHandler.getUsbSpeed(); 2496 } 2497 getGadgetHalVersion()2498 public int getGadgetHalVersion() { 2499 return mHandler.getGadgetHalVersion(); 2500 } 2501 setCurrentUsbFunctionsCb(long functions, int status, int mRequest, long mFunctions, boolean mChargingFunctions)2502 public void setCurrentUsbFunctionsCb(long functions, 2503 int status, int mRequest, long mFunctions, boolean mChargingFunctions) { 2504 mHandler.setCurrentUsbFunctionsCb(functions, status, 2505 mRequest, mFunctions, mChargingFunctions); 2506 } 2507 getCurrentUsbFunctionsCb(long functions, int status)2508 public void getCurrentUsbFunctionsCb(long functions, int status) { 2509 mHandler.sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions, 2510 status == Status.FUNCTIONS_APPLIED); 2511 } 2512 getUsbSpeedCb(int speed)2513 public void getUsbSpeedCb(int speed) { 2514 mHandler.getUsbSpeedCb(speed); 2515 } 2516 resetCb(int status)2517 public void resetCb(int status) { 2518 mHandler.resetCb(status); 2519 } 2520 2521 /** 2522 * Returns a dup of the control file descriptor for the given function. 2523 */ getControlFd(long usbFunction)2524 public ParcelFileDescriptor getControlFd(long usbFunction) { 2525 FileDescriptor fd = mControlFds.get(usbFunction); 2526 if (fd == null) { 2527 return null; 2528 } 2529 try { 2530 return ParcelFileDescriptor.dup(fd); 2531 } catch (IOException e) { 2532 Slog.e(TAG, "Could not dup fd for " + usbFunction); 2533 return null; 2534 } 2535 } 2536 getScreenUnlockedFunctions()2537 public long getScreenUnlockedFunctions() { 2538 return mHandler.getScreenUnlockedFunctions(); 2539 } 2540 2541 /** 2542 * Adds function to the current USB configuration. 2543 * 2544 * @param functions The functions to set, or empty to set the charging function. 2545 */ setCurrentFunctions(long functions, int operationId)2546 public void setCurrentFunctions(long functions, int operationId) { 2547 if (DEBUG) { 2548 Slog.d(TAG, "setCurrentFunctions(" + UsbManager.usbFunctionsToString(functions) + ")"); 2549 } 2550 if (functions == UsbManager.FUNCTION_NONE) { 2551 MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_CHARGING); 2552 } else if (functions == UsbManager.FUNCTION_MTP) { 2553 MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_MTP); 2554 } else if (functions == UsbManager.FUNCTION_PTP) { 2555 MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_PTP); 2556 } else if (functions == UsbManager.FUNCTION_MIDI) { 2557 MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_MIDI); 2558 } else if (functions == UsbManager.FUNCTION_RNDIS) { 2559 MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_RNDIS); 2560 } else if (functions == UsbManager.FUNCTION_ACCESSORY) { 2561 MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_ACCESSORY); 2562 } else if (functions == UsbManager.FUNCTION_UVC) { 2563 // MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_UVC); 2564 // TODO: Add MetricsEvent for UVC? 2565 } 2566 mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, operationId); 2567 } 2568 2569 /** 2570 * Sets the functions which are set when the screen is unlocked. 2571 * 2572 * @param functions Functions to set. 2573 */ setScreenUnlockedFunctions(long functions)2574 public void setScreenUnlockedFunctions(long functions) { 2575 if (DEBUG) { 2576 Slog.d(TAG, "setScreenUnlockedFunctions(" 2577 + UsbManager.usbFunctionsToString(functions) + ")"); 2578 } 2579 mHandler.sendMessage(MSG_SET_SCREEN_UNLOCKED_FUNCTIONS, functions); 2580 } 2581 2582 /** 2583 * Resets the USB Gadget. 2584 */ resetUsbGadget()2585 public void resetUsbGadget() { 2586 if (DEBUG) { 2587 Slog.d(TAG, "reset Usb Gadget"); 2588 } 2589 2590 mHandler.sendMessage(MSG_RESET_USB_GADGET, null); 2591 } 2592 onAdbEnabled(boolean enabled)2593 private void onAdbEnabled(boolean enabled) { 2594 int operationId = sUsbOperationCount.incrementAndGet(); 2595 mHandler.sendMessage(MSG_ENABLE_ADB, enabled, operationId); 2596 } 2597 2598 /** 2599 * Write the state to a dump stream. 2600 */ dump(DualDumpOutputStream dump, String idName, long id)2601 public void dump(DualDumpOutputStream dump, String idName, long id) { 2602 long token = dump.start(idName, id); 2603 2604 if (mHandler != null) { 2605 mHandler.dump(dump, "handler", UsbDeviceManagerProto.HANDLER); 2606 sEventLogger.dump(new DualOutputStreamDumpSink(dump, UsbHandlerProto.UEVENT)); 2607 } 2608 2609 dump.end(token); 2610 } 2611 nativeGetAccessoryStrings()2612 private native String[] nativeGetAccessoryStrings(); 2613 nativeOpenAccessory()2614 private native ParcelFileDescriptor nativeOpenAccessory(); 2615 nativeOpenControl(String usbFunction)2616 private native FileDescriptor nativeOpenControl(String usbFunction); 2617 nativeIsStartRequested()2618 private native boolean nativeIsStartRequested(); 2619 } 2620