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