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