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