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 android.app.Notification; 20 import android.app.NotificationChannel; 21 import android.app.NotificationManager; 22 import android.app.PendingIntent; 23 import android.content.BroadcastReceiver; 24 import android.content.ComponentName; 25 import android.content.ContentResolver; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.IntentFilter; 29 import android.content.pm.PackageManager; 30 import android.content.res.Resources; 31 import android.database.ContentObserver; 32 import android.hardware.usb.UsbAccessory; 33 import android.hardware.usb.UsbConfiguration; 34 import android.hardware.usb.UsbConstants; 35 import android.hardware.usb.UsbDevice; 36 import android.hardware.usb.UsbInterface; 37 import android.hardware.usb.UsbManager; 38 import android.hardware.usb.UsbPort; 39 import android.hardware.usb.UsbPortStatus; 40 import android.os.BatteryManager; 41 import android.os.FileUtils; 42 import android.os.Handler; 43 import android.os.Looper; 44 import android.os.Message; 45 import android.os.ParcelFileDescriptor; 46 import android.os.SystemClock; 47 import android.os.SystemProperties; 48 import android.os.UEventObserver; 49 import android.os.UserHandle; 50 import android.os.UserManager; 51 import android.os.storage.StorageManager; 52 import android.os.storage.StorageVolume; 53 import android.provider.Settings; 54 import android.util.Pair; 55 import android.util.Slog; 56 57 import com.android.internal.annotations.GuardedBy; 58 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 59 import com.android.internal.notification.SystemNotificationChannels; 60 import com.android.internal.os.SomeArgs; 61 import com.android.internal.util.IndentingPrintWriter; 62 import com.android.server.FgThread; 63 64 import java.io.File; 65 import java.io.FileNotFoundException; 66 import java.io.IOException; 67 import java.util.HashMap; 68 import java.util.HashSet; 69 import java.util.Iterator; 70 import java.util.Locale; 71 import java.util.Map; 72 import java.util.Scanner; 73 import java.util.Set; 74 75 /** 76 * UsbDeviceManager manages USB state in device mode. 77 */ 78 public class UsbDeviceManager { 79 80 private static final String TAG = "UsbDeviceManager"; 81 private static final boolean DEBUG = false; 82 83 /** 84 * The persistent property which stores whether adb is enabled or not. 85 * May also contain vendor-specific default functions for testing purposes. 86 */ 87 private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config"; 88 89 /** 90 * The non-persistent property which stores the current USB settings. 91 */ 92 private static final String USB_CONFIG_PROPERTY = "sys.usb.config"; 93 94 /** 95 * The non-persistent property which stores the current USB actual state. 96 */ 97 private static final String USB_STATE_PROPERTY = "sys.usb.state"; 98 99 /** 100 * ro.bootmode value when phone boots into usual Android. 101 */ 102 private static final String NORMAL_BOOT = "normal"; 103 104 private static final String USB_STATE_MATCH = 105 "DEVPATH=/devices/virtual/android_usb/android0"; 106 private static final String ACCESSORY_START_MATCH = 107 "DEVPATH=/devices/virtual/misc/usb_accessory"; 108 private static final String FUNCTIONS_PATH = 109 "/sys/class/android_usb/android0/functions"; 110 private static final String STATE_PATH = 111 "/sys/class/android_usb/android0/state"; 112 private static final String RNDIS_ETH_ADDR_PATH = 113 "/sys/class/android_usb/android0/f_rndis/ethaddr"; 114 private static final String AUDIO_SOURCE_PCM_PATH = 115 "/sys/class/android_usb/android0/f_audio_source/pcm"; 116 private static final String MIDI_ALSA_PATH = 117 "/sys/class/android_usb/android0/f_midi/alsa"; 118 119 private static final int MSG_UPDATE_STATE = 0; 120 private static final int MSG_ENABLE_ADB = 1; 121 private static final int MSG_SET_CURRENT_FUNCTIONS = 2; 122 private static final int MSG_SYSTEM_READY = 3; 123 private static final int MSG_BOOT_COMPLETED = 4; 124 private static final int MSG_USER_SWITCHED = 5; 125 private static final int MSG_UPDATE_USER_RESTRICTIONS = 6; 126 private static final int MSG_UPDATE_PORT_STATE = 7; 127 private static final int MSG_ACCESSORY_MODE_ENTER_TIMEOUT = 8; 128 private static final int MSG_UPDATE_CHARGING_STATE = 9; 129 private static final int MSG_UPDATE_HOST_STATE = 10; 130 private static final int MSG_LOCALE_CHANGED = 11; 131 132 private static final int AUDIO_MODE_SOURCE = 1; 133 134 // Delay for debouncing USB disconnects. 135 // We often get rapid connect/disconnect events when enabling USB functions, 136 // which need debouncing. 137 private static final int UPDATE_DELAY = 1000; 138 139 // Timeout for entering USB request mode. 140 // Request is cancelled if host does not configure device within 10 seconds. 141 private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000; 142 143 private static final String BOOT_MODE_PROPERTY = "ro.bootmode"; 144 145 private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv"; 146 147 private UsbHandler mHandler; 148 private boolean mBootCompleted; 149 150 private final Object mLock = new Object(); 151 152 private final Context mContext; 153 private final ContentResolver mContentResolver; 154 @GuardedBy("mLock") 155 private UsbProfileGroupSettingsManager mCurrentSettings; 156 private NotificationManager mNotificationManager; 157 private final boolean mHasUsbAccessory; 158 private boolean mUseUsbNotification; 159 private boolean mAdbEnabled; 160 private boolean mAudioSourceEnabled; 161 private boolean mMidiEnabled; 162 private int mMidiCard; 163 private int mMidiDevice; 164 private HashMap<String, HashMap<String, Pair<String, String>>> mOemModeMap; 165 private String[] mAccessoryStrings; 166 private UsbDebuggingManager mDebuggingManager; 167 private final UsbAlsaManager mUsbAlsaManager; 168 private final UsbSettingsManager mSettingsManager; 169 private Intent mBroadcastedIntent; 170 private boolean mPendingBootBroadcast; 171 private static Set<Integer> sBlackListedInterfaces; 172 173 static { 174 sBlackListedInterfaces = new HashSet<>(); 175 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_AUDIO); 176 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_COMM); 177 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_HID); 178 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_PRINTER); 179 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_MASS_STORAGE); 180 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_HUB); 181 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CDC_DATA); 182 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CSCID); 183 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CONTENT_SEC); 184 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_VIDEO); 185 sBlackListedInterfaces.add(UsbConstants.USB_CLASS_WIRELESS_CONTROLLER); 186 } 187 188 private class AdbSettingsObserver extends ContentObserver { AdbSettingsObserver()189 public AdbSettingsObserver() { 190 super(null); 191 } 192 193 @Override onChange(boolean selfChange)194 public void onChange(boolean selfChange) { 195 boolean enable = (Settings.Global.getInt(mContentResolver, 196 Settings.Global.ADB_ENABLED, 0) > 0); 197 mHandler.sendMessage(MSG_ENABLE_ADB, enable); 198 } 199 } 200 201 /* 202 * Listens for uevent messages from the kernel to monitor the USB state 203 */ 204 private final UEventObserver mUEventObserver = new UEventObserver() { 205 @Override 206 public void onUEvent(UEventObserver.UEvent event) { 207 if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString()); 208 209 String state = event.get("USB_STATE"); 210 String accessory = event.get("ACCESSORY"); 211 if (state != null) { 212 mHandler.updateState(state); 213 } else if ("START".equals(accessory)) { 214 if (DEBUG) Slog.d(TAG, "got accessory start"); 215 startAccessoryMode(); 216 } 217 } 218 }; 219 UsbDeviceManager(Context context, UsbAlsaManager alsaManager, UsbSettingsManager settingsManager)220 public UsbDeviceManager(Context context, UsbAlsaManager alsaManager, 221 UsbSettingsManager settingsManager) { 222 mContext = context; 223 mUsbAlsaManager = alsaManager; 224 mSettingsManager = settingsManager; 225 mContentResolver = context.getContentResolver(); 226 PackageManager pm = mContext.getPackageManager(); 227 mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); 228 initRndisAddress(); 229 230 readOemUsbOverrideConfig(); 231 232 mHandler = new UsbHandler(FgThread.get().getLooper()); 233 234 if (nativeIsStartRequested()) { 235 if (DEBUG) Slog.d(TAG, "accessory attached at boot"); 236 startAccessoryMode(); 237 } 238 239 boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false); 240 boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt")); 241 if (secureAdbEnabled && !dataEncrypted) { 242 mDebuggingManager = new UsbDebuggingManager(context); 243 } 244 245 BroadcastReceiver portReceiver = new BroadcastReceiver() { 246 @Override 247 public void onReceive(Context context, Intent intent) { 248 UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT); 249 UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS); 250 mHandler.updateHostState(port, status); 251 } 252 }; 253 254 BroadcastReceiver chargingReceiver = new BroadcastReceiver() { 255 @Override 256 public void onReceive(Context context, Intent intent) { 257 int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 258 boolean usbCharging = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; 259 mHandler.sendMessage(MSG_UPDATE_CHARGING_STATE, usbCharging); 260 } 261 }; 262 263 BroadcastReceiver hostReceiver = new BroadcastReceiver() { 264 @Override 265 public void onReceive(Context context, Intent intent) { 266 Iterator devices = ((UsbManager) context.getSystemService(Context.USB_SERVICE)) 267 .getDeviceList().entrySet().iterator(); 268 if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { 269 mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, true); 270 } else { 271 mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, false); 272 } 273 } 274 }; 275 276 BroadcastReceiver languageChangedReceiver = new BroadcastReceiver() { 277 @Override 278 public void onReceive(Context context, Intent intent) { 279 mHandler.sendEmptyMessage(MSG_LOCALE_CHANGED); 280 } 281 }; 282 283 mContext.registerReceiver(portReceiver, 284 new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED)); 285 mContext.registerReceiver(chargingReceiver, 286 new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 287 288 IntentFilter filter = 289 new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED); 290 filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); 291 mContext.registerReceiver(hostReceiver, filter); 292 293 mContext.registerReceiver(languageChangedReceiver, 294 new IntentFilter(Intent.ACTION_LOCALE_CHANGED)); 295 } 296 getCurrentSettings()297 private UsbProfileGroupSettingsManager getCurrentSettings() { 298 synchronized (mLock) { 299 return mCurrentSettings; 300 } 301 } 302 systemReady()303 public void systemReady() { 304 if (DEBUG) Slog.d(TAG, "systemReady"); 305 306 mNotificationManager = (NotificationManager) 307 mContext.getSystemService(Context.NOTIFICATION_SERVICE); 308 309 // Ensure that the notification channels are set up 310 if (isTv()) { 311 // TV-specific notification channel 312 mNotificationManager.createNotificationChannel( 313 new NotificationChannel(ADB_NOTIFICATION_CHANNEL_ID_TV, 314 mContext.getString( 315 com.android.internal.R.string 316 .adb_debugging_notification_channel_tv), 317 NotificationManager.IMPORTANCE_HIGH)); 318 } 319 320 // We do not show the USB notification if the primary volume supports mass storage. 321 // The legacy mass storage UI will be used instead. 322 boolean massStorageSupported; 323 final StorageManager storageManager = StorageManager.from(mContext); 324 final StorageVolume primary = storageManager.getPrimaryVolume(); 325 massStorageSupported = primary != null && primary.allowMassStorage(); 326 mUseUsbNotification = !massStorageSupported && mContext.getResources().getBoolean( 327 com.android.internal.R.bool.config_usbChargingMessage); 328 329 // make sure the ADB_ENABLED setting value matches the current state 330 try { 331 Settings.Global.putInt(mContentResolver, 332 Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0); 333 } catch (SecurityException e) { 334 // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed. 335 Slog.d(TAG, "ADB_ENABLED is restricted."); 336 } 337 mHandler.sendEmptyMessage(MSG_SYSTEM_READY); 338 } 339 bootCompleted()340 public void bootCompleted() { 341 if (DEBUG) Slog.d(TAG, "boot completed"); 342 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); 343 } 344 setCurrentUser(int newCurrentUserId, UsbProfileGroupSettingsManager settings)345 public void setCurrentUser(int newCurrentUserId, UsbProfileGroupSettingsManager settings) { 346 synchronized (mLock) { 347 mCurrentSettings = settings; 348 mHandler.obtainMessage(MSG_USER_SWITCHED, newCurrentUserId, 0).sendToTarget(); 349 } 350 } 351 updateUserRestrictions()352 public void updateUserRestrictions() { 353 mHandler.sendEmptyMessage(MSG_UPDATE_USER_RESTRICTIONS); 354 } 355 startAccessoryMode()356 private void startAccessoryMode() { 357 if (!mHasUsbAccessory) return; 358 359 mAccessoryStrings = nativeGetAccessoryStrings(); 360 boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE); 361 // don't start accessory mode if our mandatory strings have not been set 362 boolean enableAccessory = (mAccessoryStrings != null && 363 mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null && 364 mAccessoryStrings[UsbAccessory.MODEL_STRING] != null); 365 String functions = null; 366 367 if (enableAccessory && enableAudio) { 368 functions = UsbManager.USB_FUNCTION_ACCESSORY + "," 369 + UsbManager.USB_FUNCTION_AUDIO_SOURCE; 370 } else if (enableAccessory) { 371 functions = UsbManager.USB_FUNCTION_ACCESSORY; 372 } else if (enableAudio) { 373 functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE; 374 } 375 376 if (functions != null) { 377 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_MODE_ENTER_TIMEOUT), 378 ACCESSORY_REQUEST_TIMEOUT); 379 setCurrentFunctions(functions, false); 380 } 381 } 382 initRndisAddress()383 private static void initRndisAddress() { 384 // configure RNDIS ethernet address based on our serial number using the same algorithm 385 // we had been previously using in kernel board files 386 final int ETH_ALEN = 6; 387 int address[] = new int[ETH_ALEN]; 388 // first byte is 0x02 to signify a locally administered address 389 address[0] = 0x02; 390 391 String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF"); 392 int serialLength = serial.length(); 393 // XOR the USB serial across the remaining 5 bytes 394 for (int i = 0; i < serialLength; i++) { 395 address[i % (ETH_ALEN - 1) + 1] ^= (int) serial.charAt(i); 396 } 397 String addrString = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", 398 address[0], address[1], address[2], address[3], address[4], address[5]); 399 try { 400 FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString); 401 } catch (IOException e) { 402 Slog.e(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH); 403 } 404 } 405 isTv()406 private boolean isTv() { 407 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK); 408 } 409 410 private final class UsbHandler extends Handler { 411 412 // current USB state 413 private boolean mConnected; 414 private boolean mHostConnected; 415 private boolean mSourcePower; 416 private boolean mSinkPower; 417 private boolean mConfigured; 418 private boolean mUsbDataUnlocked; 419 private boolean mAudioAccessoryConnected; 420 private boolean mAudioAccessorySupported; 421 private String mCurrentFunctions; 422 private boolean mCurrentFunctionsApplied; 423 private UsbAccessory mCurrentAccessory; 424 private int mUsbNotificationId; 425 private boolean mAdbNotificationShown; 426 private int mCurrentUser = UserHandle.USER_NULL; 427 private boolean mUsbCharging; 428 private String mCurrentOemFunctions; 429 private boolean mHideUsbNotification; 430 private boolean mSupportsAllCombinations; 431 UsbHandler(Looper looper)432 public UsbHandler(Looper looper) { 433 super(looper); 434 try { 435 // Restore default functions. 436 437 if (isNormalBoot()) { 438 mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY, 439 UsbManager.USB_FUNCTION_NONE); 440 mCurrentFunctionsApplied = mCurrentFunctions.equals( 441 SystemProperties.get(USB_STATE_PROPERTY)); 442 } else { 443 mCurrentFunctions = SystemProperties.get(getPersistProp(true), 444 UsbManager.USB_FUNCTION_NONE); 445 mCurrentFunctionsApplied = SystemProperties.get(USB_CONFIG_PROPERTY, 446 UsbManager.USB_FUNCTION_NONE).equals( 447 SystemProperties.get(USB_STATE_PROPERTY)); 448 } 449 450 /* 451 * Use the normal bootmode persistent prop to maintain state of adb across 452 * all boot modes. 453 */ 454 mAdbEnabled = UsbManager.containsFunction( 455 SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY), 456 UsbManager.USB_FUNCTION_ADB); 457 458 /* 459 * Previous versions can set persist config to mtp/ptp but it does not 460 * get reset on OTA. Reset the property here instead. 461 */ 462 String persisted = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY); 463 if (UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_MTP) 464 || UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_PTP)) { 465 SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, 466 UsbManager.removeFunction(UsbManager.removeFunction(persisted, 467 UsbManager.USB_FUNCTION_MTP), UsbManager.USB_FUNCTION_PTP)); 468 } 469 470 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); 471 updateState(state); 472 473 // register observer to listen for settings changes 474 mContentResolver.registerContentObserver( 475 Settings.Global.getUriFor(Settings.Global.ADB_ENABLED), 476 false, new AdbSettingsObserver()); 477 478 // Watch for USB configuration changes 479 mUEventObserver.startObserving(USB_STATE_MATCH); 480 mUEventObserver.startObserving(ACCESSORY_START_MATCH); 481 } catch (Exception e) { 482 Slog.e(TAG, "Error initializing UsbHandler", e); 483 } 484 } 485 sendMessage(int what, boolean arg)486 public void sendMessage(int what, boolean arg) { 487 removeMessages(what); 488 Message m = Message.obtain(this, what); 489 m.arg1 = (arg ? 1 : 0); 490 sendMessage(m); 491 } 492 sendMessage(int what, Object arg)493 public void sendMessage(int what, Object arg) { 494 removeMessages(what); 495 Message m = Message.obtain(this, what); 496 m.obj = arg; 497 sendMessage(m); 498 } 499 sendMessage(int what, Object arg, boolean arg1)500 public void sendMessage(int what, Object arg, boolean arg1) { 501 removeMessages(what); 502 Message m = Message.obtain(this, what); 503 m.obj = arg; 504 m.arg1 = (arg1 ? 1 : 0); 505 sendMessage(m); 506 } 507 updateState(String state)508 public void updateState(String state) { 509 int connected, configured; 510 511 if ("DISCONNECTED".equals(state)) { 512 connected = 0; 513 configured = 0; 514 } else if ("CONNECTED".equals(state)) { 515 connected = 1; 516 configured = 0; 517 } else if ("CONFIGURED".equals(state)) { 518 connected = 1; 519 configured = 1; 520 } else { 521 Slog.e(TAG, "unknown state " + state); 522 return; 523 } 524 removeMessages(MSG_UPDATE_STATE); 525 Message msg = Message.obtain(this, MSG_UPDATE_STATE); 526 msg.arg1 = connected; 527 msg.arg2 = configured; 528 // debounce disconnects to avoid problems bringing up USB tethering 529 sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0); 530 } 531 updateHostState(UsbPort port, UsbPortStatus status)532 public void updateHostState(UsbPort port, UsbPortStatus status) { 533 if (DEBUG) { 534 Slog.i(TAG, "updateHostState " + port + " status=" + status); 535 } 536 537 SomeArgs args = SomeArgs.obtain(); 538 args.arg1 = port; 539 args.arg2 = status; 540 541 removeMessages(MSG_UPDATE_PORT_STATE); 542 Message msg = obtainMessage(MSG_UPDATE_PORT_STATE, args); 543 // debounce rapid transitions of connect/disconnect on type-c ports 544 sendMessageDelayed(msg, UPDATE_DELAY); 545 } 546 waitForState(String state)547 private boolean waitForState(String state) { 548 // wait for the transition to complete. 549 // give up after 1 second. 550 String value = null; 551 for (int i = 0; i < 20; i++) { 552 // State transition is done when sys.usb.state is set to the new configuration 553 value = SystemProperties.get(USB_STATE_PROPERTY); 554 if (state.equals(value)) return true; 555 SystemClock.sleep(50); 556 } 557 Slog.e(TAG, "waitForState(" + state + ") FAILED: got " + value); 558 return false; 559 } 560 setUsbConfig(String config)561 private void setUsbConfig(String config) { 562 if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); 563 // set the new configuration 564 // we always set it due to b/23631400, where adbd was getting killed 565 // and not restarted due to property timeouts on some devices 566 SystemProperties.set(USB_CONFIG_PROPERTY, config); 567 } 568 setAdbEnabled(boolean enable)569 private void setAdbEnabled(boolean enable) { 570 if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); 571 if (enable != mAdbEnabled) { 572 mAdbEnabled = enable; 573 String oldFunctions = mCurrentFunctions; 574 575 // Persist the adb setting 576 String newFunction = applyAdbFunction(SystemProperties.get( 577 USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_NONE)); 578 SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunction); 579 580 // Remove mtp from the config if file transfer is not enabled 581 if (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) && 582 !mUsbDataUnlocked && enable) { 583 oldFunctions = UsbManager.USB_FUNCTION_NONE; 584 } 585 586 setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked); 587 updateAdbNotification(false); 588 } 589 590 if (mDebuggingManager != null) { 591 mDebuggingManager.setAdbEnabled(mAdbEnabled); 592 } 593 } 594 595 /** 596 * Evaluates USB function policies and applies the change accordingly. 597 */ setEnabledFunctions(String functions, boolean forceRestart, boolean usbDataUnlocked)598 private void setEnabledFunctions(String functions, boolean forceRestart, 599 boolean usbDataUnlocked) { 600 if (DEBUG) { 601 Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", " 602 + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked); 603 } 604 605 if (usbDataUnlocked != mUsbDataUnlocked) { 606 mUsbDataUnlocked = usbDataUnlocked; 607 updateUsbNotification(false); 608 forceRestart = true; 609 } 610 611 // Try to set the enabled functions. 612 final String oldFunctions = mCurrentFunctions; 613 final boolean oldFunctionsApplied = mCurrentFunctionsApplied; 614 if (trySetEnabledFunctions(functions, forceRestart)) { 615 return; 616 } 617 618 // Didn't work. Try to revert changes. 619 // We always reapply the policy in case certain constraints changed such as 620 // user restrictions independently of any other new functions we were 621 // trying to activate. 622 if (oldFunctionsApplied && !oldFunctions.equals(functions)) { 623 Slog.e(TAG, "Failsafe 1: Restoring previous USB functions."); 624 if (trySetEnabledFunctions(oldFunctions, false)) { 625 return; 626 } 627 } 628 629 // Still didn't work. Try to restore the default functions. 630 Slog.e(TAG, "Failsafe 2: Restoring default USB functions."); 631 if (trySetEnabledFunctions(null, false)) { 632 return; 633 } 634 635 // Now we're desperate. Ignore the default functions. 636 // Try to get ADB working if enabled. 637 Slog.e(TAG, "Failsafe 3: Restoring empty function list (with ADB if enabled)."); 638 if (trySetEnabledFunctions(UsbManager.USB_FUNCTION_NONE, false)) { 639 return; 640 } 641 642 // Ouch. 643 Slog.e(TAG, "Unable to set any USB functions!"); 644 } 645 isNormalBoot()646 private boolean isNormalBoot() { 647 String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 648 return bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown"); 649 } 650 trySetEnabledFunctions(String functions, boolean forceRestart)651 private boolean trySetEnabledFunctions(String functions, boolean forceRestart) { 652 if (functions == null || applyAdbFunction(functions) 653 .equals(UsbManager.USB_FUNCTION_NONE)) { 654 functions = getDefaultFunctions(); 655 } 656 functions = applyAdbFunction(functions); 657 658 String oemFunctions = applyOemOverrideFunction(functions); 659 660 if (!isNormalBoot() && !mCurrentFunctions.equals(functions)) { 661 SystemProperties.set(getPersistProp(true), functions); 662 } 663 664 if ((!functions.equals(oemFunctions) && 665 (mCurrentOemFunctions == null || 666 !mCurrentOemFunctions.equals(oemFunctions))) 667 || !mCurrentFunctions.equals(functions) 668 || !mCurrentFunctionsApplied 669 || forceRestart) { 670 Slog.i(TAG, "Setting USB config to " + functions); 671 mCurrentFunctions = functions; 672 mCurrentOemFunctions = oemFunctions; 673 mCurrentFunctionsApplied = false; 674 675 // Kick the USB stack to close existing connections. 676 setUsbConfig(UsbManager.USB_FUNCTION_NONE); 677 678 if (!waitForState(UsbManager.USB_FUNCTION_NONE)) { 679 Slog.e(TAG, "Failed to kick USB config"); 680 return false; 681 } 682 683 // Set the new USB configuration. 684 setUsbConfig(oemFunctions); 685 686 if (mBootCompleted 687 && (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP) 688 || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) { 689 // Start up dependent services. 690 updateUsbStateBroadcastIfNeeded(true); 691 } 692 693 if (!waitForState(oemFunctions)) { 694 Slog.e(TAG, "Failed to switch USB config to " + functions); 695 return false; 696 } 697 698 mCurrentFunctionsApplied = true; 699 } 700 return true; 701 } 702 applyAdbFunction(String functions)703 private String applyAdbFunction(String functions) { 704 // Do not pass null pointer to the UsbManager. 705 // There isnt a check there. 706 if (functions == null) { 707 functions = ""; 708 } 709 if (mAdbEnabled) { 710 functions = UsbManager.addFunction(functions, UsbManager.USB_FUNCTION_ADB); 711 } else { 712 functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_ADB); 713 } 714 return functions; 715 } 716 isUsbTransferAllowed()717 private boolean isUsbTransferAllowed() { 718 UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 719 return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER); 720 } 721 updateCurrentAccessory()722 private void updateCurrentAccessory() { 723 // We are entering accessory mode if we have received a request from the host 724 // and the request has not timed out yet. 725 boolean enteringAccessoryMode = hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT); 726 727 if (mConfigured && enteringAccessoryMode) { 728 // successfully entered accessory mode 729 if (mAccessoryStrings != null) { 730 mCurrentAccessory = new UsbAccessory(mAccessoryStrings); 731 Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory); 732 // defer accessoryAttached if system is not ready 733 if (mBootCompleted) { 734 getCurrentSettings().accessoryAttached(mCurrentAccessory); 735 } // else handle in boot completed 736 } else { 737 Slog.e(TAG, "nativeGetAccessoryStrings failed"); 738 } 739 } else { 740 if (!enteringAccessoryMode) { 741 notifyAccessoryModeExit(); 742 } else if (DEBUG) { 743 Slog.v(TAG, "Debouncing accessory mode exit"); 744 } 745 } 746 } 747 notifyAccessoryModeExit()748 private void notifyAccessoryModeExit() { 749 // make sure accessory mode is off 750 // and restore default functions 751 Slog.d(TAG, "exited USB accessory mode"); 752 setEnabledFunctions(null, false, false); 753 754 if (mCurrentAccessory != null) { 755 if (mBootCompleted) { 756 mSettingsManager.usbAccessoryRemoved(mCurrentAccessory); 757 } 758 mCurrentAccessory = null; 759 mAccessoryStrings = null; 760 } 761 } 762 isUsbStateChanged(Intent intent)763 private boolean isUsbStateChanged(Intent intent) { 764 final Set<String> keySet = intent.getExtras().keySet(); 765 if (mBroadcastedIntent == null) { 766 for (String key : keySet) { 767 if (intent.getBooleanExtra(key, false)) { 768 return true; 769 } 770 } 771 } else { 772 if (!keySet.equals(mBroadcastedIntent.getExtras().keySet())) { 773 return true; 774 } 775 for (String key : keySet) { 776 if (intent.getBooleanExtra(key, false) != 777 mBroadcastedIntent.getBooleanExtra(key, false)) { 778 return true; 779 } 780 } 781 } 782 return false; 783 } 784 updateUsbStateBroadcastIfNeeded(boolean configChanged)785 private void updateUsbStateBroadcastIfNeeded(boolean configChanged) { 786 // send a sticky broadcast containing current USB state 787 Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 788 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 789 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 790 | Intent.FLAG_RECEIVER_FOREGROUND); 791 intent.putExtra(UsbManager.USB_CONNECTED, mConnected); 792 intent.putExtra(UsbManager.USB_HOST_CONNECTED, mHostConnected); 793 intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); 794 intent.putExtra(UsbManager.USB_DATA_UNLOCKED, 795 isUsbTransferAllowed() && mUsbDataUnlocked); 796 intent.putExtra(UsbManager.USB_CONFIG_CHANGED, configChanged); 797 798 if (mCurrentFunctions != null) { 799 String[] functions = mCurrentFunctions.split(","); 800 for (int i = 0; i < functions.length; i++) { 801 final String function = functions[i]; 802 if (UsbManager.USB_FUNCTION_NONE.equals(function)) { 803 continue; 804 } 805 intent.putExtra(function, true); 806 } 807 } 808 809 // send broadcast intent only if the USB state has changed 810 if (!isUsbStateChanged(intent) && !configChanged) { 811 if (DEBUG) { 812 Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras()); 813 } 814 return; 815 } 816 817 if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras()); 818 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 819 mBroadcastedIntent = intent; 820 } 821 updateUsbFunctions()822 private void updateUsbFunctions() { 823 updateAudioSourceFunction(); 824 updateMidiFunction(); 825 } 826 updateAudioSourceFunction()827 private void updateAudioSourceFunction() { 828 boolean enabled = UsbManager.containsFunction(mCurrentFunctions, 829 UsbManager.USB_FUNCTION_AUDIO_SOURCE); 830 if (enabled != mAudioSourceEnabled) { 831 int card = -1; 832 int device = -1; 833 834 if (enabled) { 835 Scanner scanner = null; 836 try { 837 scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH)); 838 card = scanner.nextInt(); 839 device = scanner.nextInt(); 840 } catch (FileNotFoundException e) { 841 Slog.e(TAG, "could not open audio source PCM file", e); 842 } finally { 843 if (scanner != null) { 844 scanner.close(); 845 } 846 } 847 } 848 mUsbAlsaManager.setAccessoryAudioState(enabled, card, device); 849 mAudioSourceEnabled = enabled; 850 } 851 } 852 updateMidiFunction()853 private void updateMidiFunction() { 854 boolean enabled = UsbManager.containsFunction(mCurrentFunctions, 855 UsbManager.USB_FUNCTION_MIDI); 856 if (enabled != mMidiEnabled) { 857 if (enabled) { 858 Scanner scanner = null; 859 try { 860 scanner = new Scanner(new File(MIDI_ALSA_PATH)); 861 mMidiCard = scanner.nextInt(); 862 mMidiDevice = scanner.nextInt(); 863 } catch (FileNotFoundException e) { 864 Slog.e(TAG, "could not open MIDI file", e); 865 enabled = false; 866 } finally { 867 if (scanner != null) { 868 scanner.close(); 869 } 870 } 871 } 872 mMidiEnabled = enabled; 873 } 874 mUsbAlsaManager.setPeripheralMidiState( 875 mMidiEnabled && mConfigured, mMidiCard, mMidiDevice); 876 } 877 878 @Override handleMessage(Message msg)879 public void handleMessage(Message msg) { 880 switch (msg.what) { 881 case MSG_UPDATE_STATE: 882 mConnected = (msg.arg1 == 1); 883 mConfigured = (msg.arg2 == 1); 884 885 updateUsbNotification(false); 886 updateAdbNotification(false); 887 if (mBootCompleted) { 888 updateUsbStateBroadcastIfNeeded(false); 889 } 890 if (UsbManager.containsFunction(mCurrentFunctions, 891 UsbManager.USB_FUNCTION_ACCESSORY)) { 892 updateCurrentAccessory(); 893 } 894 if (mBootCompleted) { 895 if (!mConnected) { 896 // restore defaults when USB is disconnected 897 setEnabledFunctions(null, !mAdbEnabled, false); 898 } 899 updateUsbFunctions(); 900 } else { 901 mPendingBootBroadcast = true; 902 } 903 break; 904 case MSG_UPDATE_PORT_STATE: 905 SomeArgs args = (SomeArgs) msg.obj; 906 boolean prevHostConnected = mHostConnected; 907 UsbPort port = (UsbPort) args.arg1; 908 UsbPortStatus status = (UsbPortStatus) args.arg2; 909 mHostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST; 910 mSourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE; 911 mSinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK; 912 mAudioAccessoryConnected = 913 (status.getCurrentMode() == UsbPort.MODE_AUDIO_ACCESSORY); 914 mAudioAccessorySupported = port.isModeSupported(UsbPort.MODE_AUDIO_ACCESSORY); 915 // Ideally we want to see if PR_SWAP and DR_SWAP is supported. 916 // But, this should be suffice, since, all four combinations are only supported 917 // when PR_SWAP and DR_SWAP are supported. 918 mSupportsAllCombinations = status.isRoleCombinationSupported( 919 UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST) 920 && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, 921 UsbPort.DATA_ROLE_HOST) 922 && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, 923 UsbPort.DATA_ROLE_DEVICE) 924 && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, 925 UsbPort.DATA_ROLE_HOST); 926 927 args.recycle(); 928 updateUsbNotification(false); 929 if (mBootCompleted) { 930 if (mHostConnected || prevHostConnected) { 931 updateUsbStateBroadcastIfNeeded(false); 932 } 933 } else { 934 mPendingBootBroadcast = true; 935 } 936 break; 937 case MSG_UPDATE_CHARGING_STATE: 938 mUsbCharging = (msg.arg1 == 1); 939 updateUsbNotification(false); 940 break; 941 case MSG_UPDATE_HOST_STATE: 942 Iterator devices = (Iterator) msg.obj; 943 boolean connected = (msg.arg1 == 1); 944 945 if (DEBUG) { 946 Slog.i(TAG, "HOST_STATE connected:" + connected); 947 } 948 949 mHideUsbNotification = false; 950 while (devices.hasNext()) { 951 Map.Entry pair = (Map.Entry) devices.next(); 952 if (DEBUG) { 953 Slog.i(TAG, pair.getKey() + " = " + pair.getValue()); 954 } 955 UsbDevice device = (UsbDevice) pair.getValue(); 956 int configurationCount = device.getConfigurationCount() - 1; 957 while (configurationCount >= 0) { 958 UsbConfiguration config = device.getConfiguration(configurationCount); 959 configurationCount--; 960 int interfaceCount = config.getInterfaceCount() - 1; 961 while (interfaceCount >= 0) { 962 UsbInterface intrface = config.getInterface(interfaceCount); 963 interfaceCount--; 964 if (sBlackListedInterfaces.contains(intrface.getInterfaceClass())) { 965 mHideUsbNotification = true; 966 break; 967 } 968 } 969 } 970 } 971 updateUsbNotification(false); 972 break; 973 case MSG_ENABLE_ADB: 974 setAdbEnabled(msg.arg1 == 1); 975 break; 976 case MSG_SET_CURRENT_FUNCTIONS: 977 String functions = (String) msg.obj; 978 setEnabledFunctions(functions, false, msg.arg1 == 1); 979 break; 980 case MSG_UPDATE_USER_RESTRICTIONS: 981 // Restart the USB stack if USB transfer is enabled but no longer allowed. 982 final boolean forceRestart = mUsbDataUnlocked 983 && isUsbDataTransferActive() 984 && !isUsbTransferAllowed(); 985 setEnabledFunctions( 986 mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart); 987 break; 988 case MSG_SYSTEM_READY: 989 updateUsbNotification(false); 990 updateAdbNotification(false); 991 updateUsbFunctions(); 992 break; 993 case MSG_LOCALE_CHANGED: 994 updateAdbNotification(true); 995 updateUsbNotification(true); 996 break; 997 case MSG_BOOT_COMPLETED: 998 mBootCompleted = true; 999 if (mPendingBootBroadcast) { 1000 updateUsbStateBroadcastIfNeeded(false); 1001 mPendingBootBroadcast = false; 1002 } 1003 setEnabledFunctions(null, false, false); 1004 if (mCurrentAccessory != null) { 1005 getCurrentSettings().accessoryAttached(mCurrentAccessory); 1006 } 1007 if (mDebuggingManager != null) { 1008 mDebuggingManager.setAdbEnabled(mAdbEnabled); 1009 } 1010 break; 1011 case MSG_USER_SWITCHED: { 1012 if (mCurrentUser != msg.arg1) { 1013 // Restart the USB stack and re-apply user restrictions for MTP or PTP. 1014 if (mUsbDataUnlocked 1015 && isUsbDataTransferActive() 1016 && mCurrentUser != UserHandle.USER_NULL) { 1017 Slog.v(TAG, "Current user switched to " + msg.arg1 1018 + "; resetting USB host stack for MTP or PTP"); 1019 // avoid leaking sensitive data from previous user 1020 setEnabledFunctions(null, true, false); 1021 } 1022 mCurrentUser = msg.arg1; 1023 } 1024 break; 1025 } 1026 case MSG_ACCESSORY_MODE_ENTER_TIMEOUT: { 1027 if (DEBUG) { 1028 Slog.v(TAG, "Accessory mode enter timeout: " + mConnected); 1029 } 1030 if (!mConnected || !UsbManager.containsFunction( 1031 mCurrentFunctions, 1032 UsbManager.USB_FUNCTION_ACCESSORY)) { 1033 notifyAccessoryModeExit(); 1034 } 1035 break; 1036 } 1037 } 1038 } 1039 isUsbDataTransferActive()1040 private boolean isUsbDataTransferActive() { 1041 return UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP) 1042 || UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP); 1043 } 1044 getCurrentAccessory()1045 public UsbAccessory getCurrentAccessory() { 1046 return mCurrentAccessory; 1047 } 1048 updateUsbNotification(boolean force)1049 private void updateUsbNotification(boolean force) { 1050 if (mNotificationManager == null || !mUseUsbNotification 1051 || ("0".equals(SystemProperties.get("persist.charging.notify")))) { 1052 return; 1053 } 1054 1055 // Dont show the notification when connected to a USB peripheral 1056 // and the link does not support PR_SWAP and DR_SWAP 1057 if (mHideUsbNotification && !mSupportsAllCombinations) { 1058 if (mUsbNotificationId != 0) { 1059 mNotificationManager.cancelAsUser(null, mUsbNotificationId, 1060 UserHandle.ALL); 1061 mUsbNotificationId = 0; 1062 Slog.d(TAG, "Clear notification"); 1063 } 1064 return; 1065 } 1066 1067 int id = 0; 1068 int titleRes = 0; 1069 Resources r = mContext.getResources(); 1070 if (mAudioAccessoryConnected && !mAudioAccessorySupported) { 1071 titleRes = com.android.internal.R.string.usb_unsupported_audio_accessory_title; 1072 id = SystemMessage.NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED; 1073 } else if (mConnected) { 1074 if (!mUsbDataUnlocked) { 1075 if (mSourcePower) { 1076 titleRes = com.android.internal.R.string.usb_supplying_notification_title; 1077 id = SystemMessage.NOTE_USB_SUPPLYING; 1078 } else { 1079 titleRes = com.android.internal.R.string.usb_charging_notification_title; 1080 id = SystemMessage.NOTE_USB_CHARGING; 1081 } 1082 } else if (UsbManager.containsFunction(mCurrentFunctions, 1083 UsbManager.USB_FUNCTION_MTP)) { 1084 titleRes = com.android.internal.R.string.usb_mtp_notification_title; 1085 id = SystemMessage.NOTE_USB_MTP; 1086 } else if (UsbManager.containsFunction(mCurrentFunctions, 1087 UsbManager.USB_FUNCTION_PTP)) { 1088 titleRes = com.android.internal.R.string.usb_ptp_notification_title; 1089 id = SystemMessage.NOTE_USB_PTP; 1090 } else if (UsbManager.containsFunction(mCurrentFunctions, 1091 UsbManager.USB_FUNCTION_MIDI)) { 1092 titleRes = com.android.internal.R.string.usb_midi_notification_title; 1093 id = SystemMessage.NOTE_USB_MIDI; 1094 } else if (UsbManager.containsFunction(mCurrentFunctions, 1095 UsbManager.USB_FUNCTION_ACCESSORY)) { 1096 titleRes = com.android.internal.R.string.usb_accessory_notification_title; 1097 id = SystemMessage.NOTE_USB_ACCESSORY; 1098 } else if (mSourcePower) { 1099 titleRes = com.android.internal.R.string.usb_supplying_notification_title; 1100 id = SystemMessage.NOTE_USB_SUPPLYING; 1101 } else { 1102 titleRes = com.android.internal.R.string.usb_charging_notification_title; 1103 id = SystemMessage.NOTE_USB_CHARGING; 1104 } 1105 } else if (mSourcePower) { 1106 titleRes = com.android.internal.R.string.usb_supplying_notification_title; 1107 id = SystemMessage.NOTE_USB_SUPPLYING; 1108 } else if (mHostConnected && mSinkPower && mUsbCharging) { 1109 titleRes = com.android.internal.R.string.usb_charging_notification_title; 1110 id = SystemMessage.NOTE_USB_CHARGING; 1111 } 1112 if (id != mUsbNotificationId || force) { 1113 // clear notification if title needs changing 1114 if (mUsbNotificationId != 0) { 1115 mNotificationManager.cancelAsUser(null, mUsbNotificationId, 1116 UserHandle.ALL); 1117 Slog.d(TAG, "Clear notification"); 1118 mUsbNotificationId = 0; 1119 } 1120 if (id != 0) { 1121 CharSequence message; 1122 CharSequence title = r.getText(titleRes); 1123 PendingIntent pi; 1124 String channel; 1125 1126 if (titleRes 1127 != com.android.internal.R.string 1128 .usb_unsupported_audio_accessory_title) { 1129 Intent intent = Intent.makeRestartActivityTask( 1130 new ComponentName("com.android.settings", 1131 "com.android.settings.deviceinfo.UsbModeChooserActivity")); 1132 pi = PendingIntent.getActivityAsUser(mContext, 0, 1133 intent, 0, null, UserHandle.CURRENT); 1134 channel = SystemNotificationChannels.USB; 1135 message = r.getText( 1136 com.android.internal.R.string.usb_notification_message); 1137 } else { 1138 final Intent intent = new Intent(); 1139 intent.setClassName("com.android.settings", 1140 "com.android.settings.HelpTrampoline"); 1141 intent.putExtra(Intent.EXTRA_TEXT, 1142 "help_url_audio_accessory_not_supported"); 1143 1144 if (mContext.getPackageManager().resolveActivity(intent, 0) != null) { 1145 pi = PendingIntent.getActivity(mContext, 0, intent, 0); 1146 } else { 1147 pi = null; 1148 } 1149 1150 channel = SystemNotificationChannels.ALERTS; 1151 message = r.getText( 1152 com.android.internal.R.string 1153 .usb_unsupported_audio_accessory_message); 1154 } 1155 1156 Notification.Builder builder = new Notification.Builder(mContext, channel) 1157 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 1158 .setWhen(0) 1159 .setOngoing(true) 1160 .setTicker(title) 1161 .setDefaults(0) // please be quiet 1162 .setColor(mContext.getColor( 1163 com.android.internal.R.color 1164 .system_notification_accent_color)) 1165 .setContentTitle(title) 1166 .setContentText(message) 1167 .setContentIntent(pi) 1168 .setVisibility(Notification.VISIBILITY_PUBLIC); 1169 1170 if (titleRes 1171 == com.android.internal.R.string 1172 .usb_unsupported_audio_accessory_title) { 1173 builder.setStyle(new Notification.BigTextStyle() 1174 .bigText(message)); 1175 } 1176 Notification notification = builder.build(); 1177 1178 mNotificationManager.notifyAsUser(null, id, notification, 1179 UserHandle.ALL); 1180 Slog.d(TAG, "push notification:" + title); 1181 mUsbNotificationId = id; 1182 } 1183 } 1184 } 1185 updateAdbNotification(boolean force)1186 private void updateAdbNotification(boolean force) { 1187 if (mNotificationManager == null) return; 1188 final int id = SystemMessage.NOTE_ADB_ACTIVE; 1189 final int titleRes = com.android.internal.R.string.adb_active_notification_title; 1190 1191 if (mAdbEnabled && mConnected) { 1192 if ("0".equals(SystemProperties.get("persist.adb.notify"))) return; 1193 1194 if (force && mAdbNotificationShown) { 1195 mAdbNotificationShown = false; 1196 mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); 1197 } 1198 1199 if (!mAdbNotificationShown) { 1200 Resources r = mContext.getResources(); 1201 CharSequence title = r.getText(titleRes); 1202 CharSequence message = r.getText( 1203 com.android.internal.R.string.adb_active_notification_message); 1204 1205 Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS); 1206 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 1207 | Intent.FLAG_ACTIVITY_CLEAR_TASK); 1208 PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, 1209 intent, 0, null, UserHandle.CURRENT); 1210 1211 Notification notification = 1212 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER) 1213 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 1214 .setWhen(0) 1215 .setOngoing(true) 1216 .setTicker(title) 1217 .setDefaults(0) // please be quiet 1218 .setColor(mContext.getColor( 1219 com.android.internal.R.color 1220 .system_notification_accent_color)) 1221 .setContentTitle(title) 1222 .setContentText(message) 1223 .setContentIntent(pi) 1224 .setVisibility(Notification.VISIBILITY_PUBLIC) 1225 .extend(new Notification.TvExtender() 1226 .setChannelId(ADB_NOTIFICATION_CHANNEL_ID_TV)) 1227 .build(); 1228 mAdbNotificationShown = true; 1229 mNotificationManager.notifyAsUser(null, id, notification, 1230 UserHandle.ALL); 1231 } 1232 } else if (mAdbNotificationShown) { 1233 mAdbNotificationShown = false; 1234 mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); 1235 } 1236 } 1237 getDefaultFunctions()1238 private String getDefaultFunctions() { 1239 String func = SystemProperties.get(getPersistProp(true), 1240 UsbManager.USB_FUNCTION_NONE); 1241 // if ADB is enabled, reset functions to ADB 1242 // else enable MTP as usual. 1243 if (UsbManager.containsFunction(func, UsbManager.USB_FUNCTION_ADB)) { 1244 return UsbManager.USB_FUNCTION_ADB; 1245 } else { 1246 return UsbManager.USB_FUNCTION_MTP; 1247 } 1248 } 1249 dump(IndentingPrintWriter pw)1250 public void dump(IndentingPrintWriter pw) { 1251 pw.println("USB Device State:"); 1252 pw.println(" mCurrentFunctions: " + mCurrentFunctions); 1253 pw.println(" mCurrentOemFunctions: " + mCurrentOemFunctions); 1254 pw.println(" mCurrentFunctionsApplied: " + mCurrentFunctionsApplied); 1255 pw.println(" mConnected: " + mConnected); 1256 pw.println(" mConfigured: " + mConfigured); 1257 pw.println(" mUsbDataUnlocked: " + mUsbDataUnlocked); 1258 pw.println(" mCurrentAccessory: " + mCurrentAccessory); 1259 pw.println(" mHostConnected: " + mHostConnected); 1260 pw.println(" mSourcePower: " + mSourcePower); 1261 pw.println(" mSinkPower: " + mSinkPower); 1262 pw.println(" mUsbCharging: " + mUsbCharging); 1263 pw.println(" mHideUsbNotification: " + mHideUsbNotification); 1264 pw.println(" mAudioAccessoryConnected: " + mAudioAccessoryConnected); 1265 1266 try { 1267 pw.println(" Kernel state: " 1268 + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); 1269 pw.println(" Kernel function list: " 1270 + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); 1271 } catch (IOException e) { 1272 pw.println("IOException: " + e); 1273 } 1274 } 1275 } 1276 1277 /* returns the currently attached USB accessory */ getCurrentAccessory()1278 public UsbAccessory getCurrentAccessory() { 1279 return mHandler.getCurrentAccessory(); 1280 } 1281 1282 /* opens the currently attached USB accessory */ openAccessory(UsbAccessory accessory, UsbUserSettingsManager settings)1283 public ParcelFileDescriptor openAccessory(UsbAccessory accessory, 1284 UsbUserSettingsManager settings) { 1285 UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); 1286 if (currentAccessory == null) { 1287 throw new IllegalArgumentException("no accessory attached"); 1288 } 1289 if (!currentAccessory.equals(accessory)) { 1290 String error = accessory.toString() 1291 + " does not match current accessory " 1292 + currentAccessory; 1293 throw new IllegalArgumentException(error); 1294 } 1295 settings.checkPermission(accessory); 1296 return nativeOpenAccessory(); 1297 } 1298 isFunctionEnabled(String function)1299 public boolean isFunctionEnabled(String function) { 1300 return UsbManager.containsFunction(SystemProperties.get(USB_CONFIG_PROPERTY), function); 1301 } 1302 setCurrentFunctions(String functions, boolean usbDataUnlocked)1303 public void setCurrentFunctions(String functions, boolean usbDataUnlocked) { 1304 if (DEBUG) { 1305 Slog.d(TAG, "setCurrentFunctions(" + functions + ", " + 1306 usbDataUnlocked + ")"); 1307 } 1308 mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, usbDataUnlocked); 1309 } 1310 readOemUsbOverrideConfig()1311 private void readOemUsbOverrideConfig() { 1312 String[] configList = mContext.getResources().getStringArray( 1313 com.android.internal.R.array.config_oemUsbModeOverride); 1314 1315 if (configList != null) { 1316 for (String config : configList) { 1317 String[] items = config.split(":"); 1318 if (items.length == 3 || items.length == 4) { 1319 if (mOemModeMap == null) { 1320 mOemModeMap = new HashMap<>(); 1321 } 1322 HashMap<String, Pair<String, String>> overrideMap 1323 = mOemModeMap.get(items[0]); 1324 if (overrideMap == null) { 1325 overrideMap = new HashMap<>(); 1326 mOemModeMap.put(items[0], overrideMap); 1327 } 1328 1329 // Favoring the first combination if duplicate exists 1330 if (!overrideMap.containsKey(items[1])) { 1331 if (items.length == 3) { 1332 overrideMap.put(items[1], new Pair<>(items[2], "")); 1333 } else { 1334 overrideMap.put(items[1], new Pair<>(items[2], items[3])); 1335 } 1336 } 1337 } 1338 } 1339 } 1340 } 1341 applyOemOverrideFunction(String usbFunctions)1342 private String applyOemOverrideFunction(String usbFunctions) { 1343 if ((usbFunctions == null) || (mOemModeMap == null)) { 1344 return usbFunctions; 1345 } 1346 1347 String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 1348 Slog.d(TAG, "applyOemOverride usbfunctions=" + usbFunctions + " bootmode=" + bootMode); 1349 1350 Map<String, Pair<String, String>> overridesMap = 1351 mOemModeMap.get(bootMode); 1352 // Check to ensure that the oem is not overriding in the normal 1353 // boot mode 1354 if (overridesMap != null && !(bootMode.equals(NORMAL_BOOT) || 1355 bootMode.equals("unknown"))) { 1356 Pair<String, String> overrideFunctions = 1357 overridesMap.get(usbFunctions); 1358 if (overrideFunctions != null) { 1359 Slog.d(TAG, "OEM USB override: " + usbFunctions 1360 + " ==> " + overrideFunctions.first 1361 + " persist across reboot " 1362 + overrideFunctions.second); 1363 if (!overrideFunctions.second.equals("")) { 1364 String newFunction; 1365 if (mAdbEnabled) { 1366 newFunction = UsbManager.addFunction(overrideFunctions.second, 1367 UsbManager.USB_FUNCTION_ADB); 1368 } else { 1369 newFunction = overrideFunctions.second; 1370 } 1371 Slog.d(TAG, "OEM USB override persisting: " + newFunction + "in prop: " 1372 + UsbDeviceManager.getPersistProp(false)); 1373 SystemProperties.set(UsbDeviceManager.getPersistProp(false), 1374 newFunction); 1375 } 1376 return overrideFunctions.first; 1377 } else if (mAdbEnabled) { 1378 String newFunction = UsbManager.addFunction(UsbManager.USB_FUNCTION_NONE, 1379 UsbManager.USB_FUNCTION_ADB); 1380 SystemProperties.set(UsbDeviceManager.getPersistProp(false), 1381 newFunction); 1382 } else { 1383 SystemProperties.set(UsbDeviceManager.getPersistProp(false), 1384 UsbManager.USB_FUNCTION_NONE); 1385 } 1386 } 1387 // return passed in functions as is. 1388 return usbFunctions; 1389 } 1390 getPersistProp(boolean functions)1391 public static String getPersistProp(boolean functions) { 1392 String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 1393 String persistProp = USB_PERSISTENT_CONFIG_PROPERTY; 1394 if (!(bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown"))) { 1395 if (functions) { 1396 persistProp = "persist.sys.usb." + bootMode + ".func"; 1397 } else { 1398 persistProp = "persist.sys.usb." + bootMode + ".config"; 1399 } 1400 } 1401 1402 return persistProp; 1403 } 1404 1405 allowUsbDebugging(boolean alwaysAllow, String publicKey)1406 public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { 1407 if (mDebuggingManager != null) { 1408 mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey); 1409 } 1410 } 1411 denyUsbDebugging()1412 public void denyUsbDebugging() { 1413 if (mDebuggingManager != null) { 1414 mDebuggingManager.denyUsbDebugging(); 1415 } 1416 } 1417 clearUsbDebuggingKeys()1418 public void clearUsbDebuggingKeys() { 1419 if (mDebuggingManager != null) { 1420 mDebuggingManager.clearUsbDebuggingKeys(); 1421 } else { 1422 throw new RuntimeException("Cannot clear Usb Debugging keys, " 1423 + "UsbDebuggingManager not enabled"); 1424 } 1425 } 1426 dump(IndentingPrintWriter pw)1427 public void dump(IndentingPrintWriter pw) { 1428 if (mHandler != null) { 1429 mHandler.dump(pw); 1430 } 1431 if (mDebuggingManager != null) { 1432 mDebuggingManager.dump(pw); 1433 } 1434 } 1435 nativeGetAccessoryStrings()1436 private native String[] nativeGetAccessoryStrings(); 1437 nativeOpenAccessory()1438 private native ParcelFileDescriptor nativeOpenAccessory(); 1439 nativeIsStartRequested()1440 private native boolean nativeIsStartRequested(); 1441 nativeGetAudioMode()1442 private native int nativeGetAudioMode(); 1443 } 1444