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