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