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