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