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