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