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