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