UsbDeviceManager.java revision 72ec482be00c34d9e8e9486010388e5f347ecdda
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2011 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions an 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.server.usb; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 198f573952b8729b4319043ae0908997ecd2d68951Dianne Hackbornimport android.app.Notification; 20629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.app.NotificationChannel; 21629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.app.NotificationManager; 2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.app.PendingIntent; 2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.BroadcastReceiver; 2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ComponentName; 255c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.content.ContentResolver; 2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.content.Intent; 2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.IntentFilter; 2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.PackageManager; 30f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.content.res.Resources; 315c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.database.ContentObserver; 32080d9b614e609826dce2606f9e474af674ead933Joe Onoratoimport android.hardware.usb.UsbAccessory; 33080d9b614e609826dce2606f9e474af674ead933Joe Onoratoimport android.hardware.usb.UsbManager; 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.hardware.usb.UsbPort; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.hardware.usb.UsbPortStatus; 3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.BatteryManager; 3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.FileUtils; 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Handler; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Looper; 4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Message; 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.ParcelFileDescriptor; 42f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.os.SystemClock; 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.SystemProperties; 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.UEventObserver; 4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.UserHandle; 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.UserManager; 4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.storage.StorageManager; 4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.storage.StorageVolume; 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.provider.Settings; 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.Pair; 5185a02a8d13eced310aee4c2a795e9c9c5435038fJoe Onoratoimport android.util.Slog; 52e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy 533a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onoratoimport com.android.internal.annotations.GuardedBy; 5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport com.android.internal.notification.SystemNotificationChannels; 5570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkeyimport com.android.internal.os.SomeArgs; 5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport com.android.internal.util.IndentingPrintWriter; 5731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport com.android.server.FgThread; 5831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.io.File; 6031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.io.FileNotFoundException; 618f573952b8729b4319043ae0908997ecd2d68951Dianne Hackbornimport java.io.IOException; 628f573952b8729b4319043ae0908997ecd2d68951Dianne Hackbornimport java.util.HashMap; 6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.LinkedList; 6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.List; 6531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.Locale; 6631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.Map; 6731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.Scanner; 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.Set; 6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * UsbDeviceManager manages USB state in device mode. 7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 7331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpublic class UsbDeviceManager { 7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String TAG = "UsbDeviceManager"; 7670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private static final boolean DEBUG = false; 7770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 7870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 7970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * The persistent property which stores whether adb is enabled or not. 8070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * May also contain vendor-specific default functions for testing purposes. 8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config"; 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 84f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron /** 8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The non-persistent property which stores the current USB settings. 8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String USB_CONFIG_PROPERTY = "sys.usb.config"; 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The property which stores the current build type (user/userdebug/eng). 9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String BUILD_TYPE_PROPERTY = "ro.build.type"; 9300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 9470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private static final String BUILD_TYPE_USERDEBUG = "userdebug"; 9570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private static final String BUILD_TYPE_ENG = "eng"; 9670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 9770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 9870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * The non-persistent property which stores the current USB actual state. 9970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 10031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String USB_STATE_PROPERTY = "sys.usb.state"; 10170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 10231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 103a9c28f6f97a4b34d9527c786e3aa8f02d92d9e07Joe Onorato * ro.bootmode value when phone boots into usual Android. 10431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 10531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String NORMAL_BOOT = "normal"; 106a206daaed1318005d1534cca2e4eeec56144d104Romain Guy 10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String USB_STATE_MATCH = 1088a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy "DEVPATH=/devices/virtual/android_usb/android0"; 1098a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy private static final String ACCESSORY_START_MATCH = 1108a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy "DEVPATH=/devices/virtual/misc/usb_accessory"; 11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String FUNCTIONS_PATH = 11231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project "/sys/class/android_usb/android0/functions"; 11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String STATE_PATH = 11431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project "/sys/class/android_usb/android0/state"; 11531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String RNDIS_ETH_ADDR_PATH = 11631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project "/sys/class/android_usb/android0/f_rndis/ethaddr"; 11731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String AUDIO_SOURCE_PCM_PATH = 11831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project "/sys/class/android_usb/android0/f_audio_source/pcm"; 11931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String MIDI_ALSA_PATH = 12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project "/sys/class/android_usb/android0/f_midi/alsa"; 12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_UPDATE_STATE = 0; 12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_ENABLE_ADB = 1; 12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_SET_CURRENT_FUNCTIONS = 2; 12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_SYSTEM_READY = 3; 12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_BOOT_COMPLETED = 4; 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_USER_SWITCHED = 5; 12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_UPDATE_USER_RESTRICTIONS = 6; 12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_UPDATE_HOST_STATE = 7; 13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int MSG_ACCESSORY_MODE_ENTER_TIMEOUT = 8; 1318f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private static final int MSG_UPDATE_CHARGING_STATE = 9; 1328f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn 13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int AUDIO_MODE_SOURCE = 1; 13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Delay for debouncing USB disconnects. 13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // We often get rapid connect/disconnect events when enabling USB functions, 1370d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato // which need debouncing. 13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int UPDATE_DELAY = 1000; 13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Timeout for entering USB request mode. 14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Request is cancelled if host does not configure device within 10 seconds. 14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000; 14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String BOOT_MODE_PROPERTY = "ro.bootmode"; 14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv"; 14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private UsbHandler mHandler; 149a206daaed1318005d1534cca2e4eeec56144d104Romain Guy private boolean mBootCompleted; 150a206daaed1318005d1534cca2e4eeec56144d104Romain Guy 151a206daaed1318005d1534cca2e4eeec56144d104Romain Guy private final Object mLock = new Object(); 15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final Context mContext; 15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final ContentResolver mContentResolver; 15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @GuardedBy("mLock") 15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private UsbProfileGroupSettingsManager mCurrentSettings; 15731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private NotificationManager mNotificationManager; 15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final boolean mHasUsbAccessory; 15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mUseUsbNotification; 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mAdbEnabled; 16131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mAudioSourceEnabled; 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mMidiEnabled; 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mMidiCard; 16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mMidiDevice; 16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private HashMap<String, HashMap<String, Pair<String, String>>> mOemModeMap; 16631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private String[] mAccessoryStrings; 16731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private UsbDebuggingManager mDebuggingManager; 16831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final UsbAlsaManager mUsbAlsaManager; 16931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final UsbSettingsManager mSettingsManager; 17031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Intent mBroadcastedIntent; 17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mPendingBootBroadcast; 17231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private class AdbSettingsObserver extends ContentObserver { 17431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public AdbSettingsObserver() { 17531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(null); 17631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 17731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 17931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onChange(boolean selfChange) { 18031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean enable = (Settings.Global.getInt(mContentResolver, 18131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Settings.Global.ADB_ENABLED, 0) > 0); 18231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.sendMessage(MSG_ENABLE_ADB, enable); 18331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /* 18731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Listens for uevent messages from the kernel to monitor the USB state 18831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 18931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final UEventObserver mUEventObserver = new UEventObserver() { 19031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 19131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onUEvent(UEventObserver.UEvent event) { 19231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString()); 19331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String state = event.get("USB_STATE"); 19531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String accessory = event.get("ACCESSORY"); 19631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (state != null) { 19731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.updateState(state); 19831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if ("START".equals(accessory)) { 19931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) Slog.d(TAG, "got accessory start"); 20031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project startAccessoryMode(); 20131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 20231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 20331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project }; 20431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 20531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() { 20631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 20731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onReceive(Context context, Intent intent) { 20831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT); 20931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS); 21031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.updateHostState(port, status); 21131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project }; 21331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() { 21531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 21631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onReceive(Context context, Intent intent) { 21731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 21831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean usbCharging = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; 21931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.sendMessage(MSG_UPDATE_CHARGING_STATE, usbCharging); 22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project }; 22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public UsbDeviceManager(Context context, UsbAlsaManager alsaManager, 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbSettingsManager settingsManager) { 22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mContext = context; 22631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mUsbAlsaManager = alsaManager; 22731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mSettingsManager = settingsManager; 22831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mContentResolver = context.getContentResolver(); 22931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project PackageManager pm = mContext.getPackageManager(); 23031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); 23131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project initRndisAddress(); 23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project readOemUsbOverrideConfig(); 23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler = new UsbHandler(FgThread.get().getLooper()); 23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (nativeIsStartRequested()) { 23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) Slog.d(TAG, "accessory attached at boot"); 23931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project startAccessoryMode(); 24031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 24131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 24231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false); 24331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt")); 24431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (secureAdbEnabled && !dataEncrypted) { 24531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDebuggingManager = new UsbDebuggingManager(context); 24631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 24731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mContext.registerReceiver(mHostReceiver, 24831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED)); 249c45b16862918a0c6c253bba12032165b030565afJoe Onorato mContext.registerReceiver(mChargingReceiver, 2504c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 25131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 25331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private UsbProfileGroupSettingsManager getCurrentSettings() { 25431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project synchronized (mLock) { 25531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mCurrentSettings; 25631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 25931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void systemReady() { 26031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) Slog.d(TAG, "systemReady"); 26131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mNotificationManager = (NotificationManager) 26331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mContext.getSystemService(Context.NOTIFICATION_SERVICE); 26431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Ensure that the notification channels are set up 26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (isTv()) { 26731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // TV-specific notification channel 26831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mNotificationManager.createNotificationChannel( 26931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project new NotificationChannel(ADB_NOTIFICATION_CHANNEL_ID_TV, 27031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mContext.getString( 27131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project com.android.internal.R.string 27231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project .adb_debugging_notification_channel_tv), 27331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project NotificationManager.IMPORTANCE_HIGH)); 27431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // We do not show the USB notification if the primary volume supports mass storage. 27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // The legacy mass storage UI will be used instead. 27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean massStorageSupported = false; 27931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final StorageManager storageManager = StorageManager.from(mContext); 28031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final StorageVolume primary = storageManager.getPrimaryVolume(); 28131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project massStorageSupported = primary != null && primary.allowMassStorage(); 28231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mUseUsbNotification = !massStorageSupported && mContext.getResources().getBoolean( 28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project com.android.internal.R.bool.config_usbChargingMessage); 28431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // make sure the ADB_ENABLED setting value matches the current state 28631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project try { 28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Settings.Global.putInt(mContentResolver, 28831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0); 28931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } catch (SecurityException e) { 29031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed. 29131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.d(TAG, "ADB_ENABLED is restricted."); 29231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 29331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.sendEmptyMessage(MSG_SYSTEM_READY); 29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void bootCompleted() { 29731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) Slog.d(TAG, "boot completed"); 29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); 29931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 30131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void setCurrentUser(int newCurrentUserId, UsbProfileGroupSettingsManager settings) { 30231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project synchronized (mLock) { 30331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentSettings = settings; 30431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.obtainMessage(MSG_USER_SWITCHED, newCurrentUserId, 0).sendToTarget(); 30531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 30831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void updateUserRestrictions() { 30931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.sendEmptyMessage(MSG_UPDATE_USER_RESTRICTIONS); 31031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 31131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 31231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void startAccessoryMode() { 31331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!mHasUsbAccessory) return; 31431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 31531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAccessoryStrings = nativeGetAccessoryStrings(); 31631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE); 3174c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy // don't start accessory mode if our mandatory strings have not been set 3184c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy boolean enableAccessory = (mAccessoryStrings != null && 31931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null && 32031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAccessoryStrings[UsbAccessory.MODEL_STRING] != null); 32131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String functions = null; 32231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 32331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (enableAccessory && enableAudio) { 32431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project functions = UsbManager.USB_FUNCTION_ACCESSORY + "," 32531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project + UsbManager.USB_FUNCTION_AUDIO_SOURCE; 32631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (enableAccessory) { 32731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project functions = UsbManager.USB_FUNCTION_ACCESSORY; 32831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (enableAudio) { 32931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE; 33031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 3310d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato 33231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (functions != null) { 33331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_MODE_ENTER_TIMEOUT), 33400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato ACCESSORY_REQUEST_TIMEOUT); 33500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato setCurrentFunctions(functions, false); 33600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 33731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 33931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private static void initRndisAddress() { 34031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // configure RNDIS ethernet address based on our serial number using the same algorithm 34131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // we had been previously using in kernel board files 34270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey final int ETH_ALEN = 6; 34331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int address[] = new int[ETH_ALEN]; 34431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // first byte is 0x02 to signify a locally administered address 34531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project address[0] = 0x02; 34631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3474c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF"); 3484c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy int serialLength = serial.length(); 3494c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy // XOR the USB serial across the remaining 5 bytes 3504c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy for (int i = 0; i < serialLength; i++) { 3514c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy address[i % (ETH_ALEN - 1) + 1] ^= (int) serial.charAt(i); 3524c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy } 35331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String addrString = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", 35431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project address[0], address[1], address[2], address[3], address[4], address[5]); 35531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project try { 35631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString); 35731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } catch (IOException e) { 35831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH); 35931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 36031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 36131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 36231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean isTv() { 36331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK); 36431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 36531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 36631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final class UsbHandler extends Handler { 36731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3688f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn // current USB state 369798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy private boolean mConnected; 370798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy private boolean mHostConnected; 371798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy private boolean mSourcePower; 372798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy private boolean mSinkPower; 373c07c79b10b663a02ef67da57bdda60a1ea299eb5Marco Nelissen private boolean mConfigured; 37449cdb1b18c12a81cac9817c4800e43d5b507e0c4Dianne Hackborn private boolean mUsbDataUnlocked; 3758f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private String mCurrentFunctions; 3768f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private boolean mCurrentFunctionsApplied; 37731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private UsbAccessory mCurrentAccessory; 37831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mUsbNotificationId; 37931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mAdbNotificationShown; 38031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mCurrentUser = UserHandle.USER_NULL; 38131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean mUsbCharging; 3828f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private String mCurrentOemFunctions; 38331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 38431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public UsbHandler(Looper looper) { 38531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(looper); 3868a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy try { 3878a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy // Restore default functions. 38831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 38931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (isNormalBoot()) { 39031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY, 39131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbManager.USB_FUNCTION_NONE); 39231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentFunctionsApplied = mCurrentFunctions.equals( 39331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SystemProperties.get(USB_STATE_PROPERTY)); 39431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 39531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentFunctions = SystemProperties.get(getPersistProp(true), 3967376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project UsbManager.USB_FUNCTION_NONE); 397e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato mCurrentFunctionsApplied = SystemProperties.get(USB_CONFIG_PROPERTY, 398e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato UsbManager.USB_FUNCTION_NONE).equals( 39931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SystemProperties.get(USB_STATE_PROPERTY)); 40031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 40131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 40231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 40331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Use the normal bootmode persistent prop to maintain state of adb across 404f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy * all boot modes. 40531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 40631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAdbEnabled = UsbManager.containsFunction( 40731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY), 40831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbManager.USB_FUNCTION_ADB); 40931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 41031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 41131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Remove MTP from persistent config, to bring usb to a good state 41231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * after fixes to b/31814300. This block can be removed after the update 41331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 41431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String persisted = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY); 41531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_MTP)) { 41631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, 41731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbManager.removeFunction(persisted, UsbManager.USB_FUNCTION_MTP)); 41831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 41931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 42031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); 42131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateState(state); 42231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4237376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project // register observer to listen for settings changes 4247376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project mContentResolver.registerContentObserver( 425e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato Settings.Global.getUriFor(Settings.Global.ADB_ENABLED), 4267376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project false, new AdbSettingsObserver()); 42731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 42831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Watch for USB configuration changes 42900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mUEventObserver.startObserving(USB_STATE_MATCH); 43000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mUEventObserver.startObserving(ACCESSORY_START_MATCH); 43100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } catch (Exception e) { 43200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato Slog.e(TAG, "Error initializing UsbHandler", e); 43300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 43431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 43531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 43631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void sendMessage(int what, boolean arg) { 43731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project removeMessages(what); 43831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Message m = Message.obtain(this, what); 43931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project m.arg1 = (arg ? 1 : 0); 44031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sendMessage(m); 44131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 44231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 44331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void sendMessage(int what, Object arg) { 44431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project removeMessages(what); 44531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Message m = Message.obtain(this, what); 44631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project m.obj = arg; 44731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sendMessage(m); 44831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 44931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 45031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void sendMessage(int what, Object arg, boolean arg1) { 45131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project removeMessages(what); 45231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Message m = Message.obtain(this, what); 45331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project m.obj = arg; 45431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project m.arg1 = (arg1 ? 1 : 0); 4553a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron sendMessage(m); 45631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 4573a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron 45831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void updateState(String state) { 4593a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron int connected, configured; 460798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy 46131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if ("DISCONNECTED".equals(state)) { 46231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project connected = 0; 46331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project configured = 0; 46431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if ("CONNECTED".equals(state)) { 46531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project connected = 1; 46631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project configured = 0; 46731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if ("CONFIGURED".equals(state)) { 46831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project connected = 1; 46931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project configured = 1; 47031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 47131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "unknown state " + state); 47231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 47331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 47431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project removeMessages(MSG_UPDATE_STATE); 47531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Message msg = Message.obtain(this, MSG_UPDATE_STATE); 47631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project msg.arg1 = connected; 47731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project msg.arg2 = configured; 47831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // debounce disconnects to avoid problems bringing up USB tethering 47931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0); 48031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 48131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 48231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void updateHostState(UsbPort port, UsbPortStatus status) { 48331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean hostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST; 48431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean sourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE; 48531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean sinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK; 48631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 48731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) { 48831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.i(TAG, "updateHostState " + port + " status=" + status); 48931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 49031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 49131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SomeArgs args = SomeArgs.obtain(); 49231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project args.argi1 = hostConnected ? 1 : 0; 49331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project args.argi2 = sourcePower ? 1 : 0; 494678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato args.argi3 = sinkPower ? 1 : 0; 49531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 49631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project removeMessages(MSG_UPDATE_HOST_STATE); 49731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Message msg = obtainMessage(MSG_UPDATE_HOST_STATE, args); 49831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // debounce rapid transitions of connect/disconnect on type-c ports 49931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sendMessageDelayed(msg, UPDATE_DELAY); 50031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 50131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 50231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean waitForState(String state) { 50331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // wait for the transition to complete. 50431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // give up after 1 second. 50531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String value = null; 50631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < 20; i++) { 50731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // State transition is done when sys.usb.state is set to the new configuration 50831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project value = SystemProperties.get(USB_STATE_PROPERTY); 50931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (state.equals(value)) return true; 51031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SystemClock.sleep(50); 51131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 51231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "waitForState(" + state + ") FAILED: got " + value); 51331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 51431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 51531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 51631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void setUsbConfig(String config) { 51731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); 51831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // set the new configuration 51931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // we always set it due to b/23631400, where adbd was getting killed 52031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // and not restarted due to property timeouts on some devices 52131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SystemProperties.set(USB_CONFIG_PROPERTY, config); 52231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 52331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 52431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void setAdbEnabled(boolean enable) { 52531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); 52631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (enable != mAdbEnabled) { 52731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAdbEnabled = enable; 528c2e24c0a37ddeab930f731c062705d435e477f75Romain Guy String oldFunctions = mCurrentFunctions; 529678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato 53031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Persist the adb setting 53131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String newFunction = applyAdbFunction(SystemProperties.get( 53231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_NONE)); 53331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunction); 53431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 53531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Remove mtp from the config if file transfer is not enabled 53631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) && 53731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project !mUsbDataUnlocked && enable) { 53831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project oldFunctions = UsbManager.USB_FUNCTION_NONE; 53931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 54131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked); 54231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateAdbNotification(); 54331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 54531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDebuggingManager != null) { 54631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDebuggingManager.setAdbEnabled(mAdbEnabled); 54731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 5497bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato 5507bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato /** 5517bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato * Evaluates USB function policies and applies the change accordingly. 5527bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato */ 5537bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato private void setEnabledFunctions(String functions, boolean forceRestart, 5547bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato boolean usbDataUnlocked) { 5557bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato if (DEBUG) { 5567bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", " 5577bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked); 5587bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 55931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 56068ba5ca5d7f17df65f0cc8813603de2d3f215bf4Joe Onorato if (usbDataUnlocked != mUsbDataUnlocked) { 56168ba5ca5d7f17df65f0cc8813603de2d3f215bf4Joe Onorato mUsbDataUnlocked = usbDataUnlocked; 56268ba5ca5d7f17df65f0cc8813603de2d3f215bf4Joe Onorato updateUsbNotification(); 5637c312c15e33b6cffbda707429e88ade498fc9f5eJoe Onorato forceRestart = true; 56431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 56531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 56631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Try to set the enabled functions. 56731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final String oldFunctions = mCurrentFunctions; 56831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final boolean oldFunctionsApplied = mCurrentFunctionsApplied; 56931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (trySetEnabledFunctions(functions, forceRestart)) { 57031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 57131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 57231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 57331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Didn't work. Try to revert changes. 57431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // We always reapply the policy in case certain constraints changed such as 57531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // user restrictions independently of any other new functions we were 57631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // trying to activate. 57731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (oldFunctionsApplied && !oldFunctions.equals(functions)) { 57831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "Failsafe 1: Restoring previous USB functions."); 57931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (trySetEnabledFunctions(oldFunctions, false)) { 58031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 58131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 58231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 58331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 58431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Still didn't work. Try to restore the default functions. 58531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "Failsafe 2: Restoring default USB functions."); 58631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (trySetEnabledFunctions(null, false)) { 58731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 58831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 58931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 59031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Now we're desperate. Ignore the default functions. 59131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Try to get ADB working if enabled. 59231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "Failsafe 3: Restoring empty function list (with ADB if enabled)."); 59331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (trySetEnabledFunctions(UsbManager.USB_FUNCTION_NONE, false)) { 59431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 59531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 59631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 59731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Ouch. 59831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "Unable to set any USB functions!"); 59931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 60031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 60131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean isNormalBoot() { 60231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 60331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown")) { 60431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 60531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 60631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 60731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 6083a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron 60931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean trySetEnabledFunctions(String functions, boolean forceRestart) { 61031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (functions == null || applyAdbFunction(functions) 61131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project .equals(UsbManager.USB_FUNCTION_NONE)) { 61231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project functions = getDefaultFunctions(); 61331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 61431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project functions = applyAdbFunction(functions); 61531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 61631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String oemFunctions = applyOemOverrideFunction(functions); 61731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 61831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!isNormalBoot() && !mCurrentFunctions.equals(functions)) { 61931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SystemProperties.set(getPersistProp(true), functions); 62031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 62131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 62231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if ((!functions.equals(oemFunctions) && 62331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project (mCurrentOemFunctions == null || 62431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project !mCurrentOemFunctions.equals(oemFunctions))) 62531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project || !mCurrentFunctions.equals(functions) 62631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project || !mCurrentFunctionsApplied 62731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project || forceRestart) { 62831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.i(TAG, "Setting USB config to " + functions); 62931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentFunctions = functions; 63031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentOemFunctions = oemFunctions; 63131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentFunctionsApplied = false; 63231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 63331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Kick the USB stack to close existing connections. 63431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setUsbConfig(UsbManager.USB_FUNCTION_NONE); 63531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 63631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!waitForState(UsbManager.USB_FUNCTION_NONE)) { 63731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "Failed to kick USB config"); 638f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron return false; 639f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron } 640f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron 641f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron // Set the new USB configuration. 642f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron setUsbConfig(oemFunctions); 643f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron 644f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron if (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP) 645f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP)) { 646f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron // Start up dependent services. 647f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron updateUsbStateBroadcastIfNeeded(true); 648f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron } 64931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 65031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!waitForState(oemFunctions)) { 65131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "Failed to switch USB config to " + functions); 65231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 653f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron } 65431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 65531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentFunctionsApplied = true; 65631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 65731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 65831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 65931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 66031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private String applyAdbFunction(String functions) { 66131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Do not pass null pointer to the UsbManager. 66231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // There isnt a check there. 66331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (functions == null) { 6643a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato functions = ""; 6653a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato } 6663a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato if (mAdbEnabled) { 6673a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato functions = UsbManager.addFunction(functions, UsbManager.USB_FUNCTION_ADB); 6683a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato } else { 6693a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_ADB); 6703a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato } 6713a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato return functions; 6723a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato } 6733a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato 6743a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato private boolean isUsbTransferAllowed() { 6753a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 6763a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER); 6773a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato } 6783a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato 6793a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato private void updateCurrentAccessory() { 6803a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato // We are entering accessory mode if we have received a request from the host 6813a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato // and the request has not timed out yet. 6823a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato boolean enteringAccessoryMode = hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT); 6833a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato 6843a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato if (mConfigured && enteringAccessoryMode) { 6853a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato // successfully entered accessory mode 6863a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato if (mAccessoryStrings != null) { 6873a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato mCurrentAccessory = new UsbAccessory(mAccessoryStrings); 6883a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory); 6893a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato // defer accessoryAttached if system is not ready 6903a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato if (mBootCompleted) { 6913a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato getCurrentSettings().accessoryAttached(mCurrentAccessory); 6923a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } // else handle in boot completed 6933a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } else { 6943a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron Slog.e(TAG, "nativeGetAccessoryStrings failed"); 6953a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 6963a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } else { 6973a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron if (!enteringAccessoryMode) { 69831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project notifyAccessoryModeExit(); 6993a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } else if (DEBUG) { 7003a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron Slog.v(TAG, "Debouncing accessory mode exit"); 7013a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 7023a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 7033a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 70431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 70531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void notifyAccessoryModeExit() { 70631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // make sure accessory mode is off 70731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // and restore default functions 70831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.d(TAG, "exited USB accessory mode"); 70931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setEnabledFunctions(null, false, false); 71031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 71131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mCurrentAccessory != null) { 71231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mBootCompleted) { 71331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mSettingsManager.usbAccessoryRemoved(mCurrentAccessory); 71431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 71531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentAccessory = null; 71631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAccessoryStrings = null; 71731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 71831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 71931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 720f8bbd34d7d4705b49db202be92b920196bc7ea38Mike Cleron private boolean isUsbStateChanged(Intent intent) { 7212bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato final Set<String> keySet = intent.getExtras().keySet(); 7222bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (mBroadcastedIntent == null) { 7232bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato for (String key : keySet) { 7242bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (intent.getBooleanExtra(key, false)) { 7252bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato return true; 7262bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato } 7272bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato } 7282bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato } else { 7292bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (!keySet.equals(mBroadcastedIntent.getExtras().keySet())) { 7307c312c15e33b6cffbda707429e88ade498fc9f5eJoe Onorato return true; 73131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 73231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (String key : keySet) { 73331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (intent.getBooleanExtra(key, false) != 73431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mBroadcastedIntent.getBooleanExtra(key, false)) { 73531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 73631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 73731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 73831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 73931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 74031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 74131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 74231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void updateUsbStateBroadcastIfNeeded(boolean configChanged) { 74331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // send a sticky broadcast containing current USB state 74431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 74531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 74631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 74731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project | Intent.FLAG_RECEIVER_FOREGROUND); 74831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project intent.putExtra(UsbManager.USB_CONNECTED, mConnected); 74931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project intent.putExtra(UsbManager.USB_HOST_CONNECTED, mHostConnected); 75031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); 75131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project intent.putExtra(UsbManager.USB_DATA_UNLOCKED, 75231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project isUsbTransferAllowed() && mUsbDataUnlocked); 75331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project intent.putExtra(UsbManager.USB_CONFIG_CHANGED, configChanged); 75431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 75531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mCurrentFunctions != null) { 75631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String[] functions = mCurrentFunctions.split(","); 75731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < functions.length; i++) { 75831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final String function = functions[i]; 75931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (UsbManager.USB_FUNCTION_NONE.equals(function)) { 76031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project continue; 76131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 76231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project intent.putExtra(function, true); 7638f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn } 76431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 76531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 76631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // send broadcast intent only if the USB state has changed 76731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!isUsbStateChanged(intent)) { 76831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) { 76931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras()); 7708f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn } 77131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 7723a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 7733a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron 77431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras()); 77531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 77631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mBroadcastedIntent = intent; 77731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 77831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 77931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void updateUsbFunctions() { 780a206daaed1318005d1534cca2e4eeec56144d104Romain Guy updateAudioSourceFunction(); 78131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateMidiFunction(); 78231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 78331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 78431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void updateAudioSourceFunction() { 78531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean enabled = UsbManager.containsFunction(mCurrentFunctions, 78631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbManager.USB_FUNCTION_AUDIO_SOURCE); 78731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (enabled != mAudioSourceEnabled) { 78831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int card = -1; 78931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int device = -1; 79031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 79131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (enabled) { 79231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Scanner scanner = null; 79331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project try { 79431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH)); 79531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project card = scanner.nextInt(); 79631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project device = scanner.nextInt(); 79731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } catch (FileNotFoundException e) { 79831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "could not open audio source PCM file", e); 79931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } finally { 80031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (scanner != null) { 80131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project scanner.close(); 80231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 80331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 80431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 80531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mUsbAlsaManager.setAccessoryAudioState(enabled, card, device); 80631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mAudioSourceEnabled = enabled; 80731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 80831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 80931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 81031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void updateMidiFunction() { 81131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean enabled = UsbManager.containsFunction(mCurrentFunctions, 81231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbManager.USB_FUNCTION_MIDI); 81331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (enabled != mMidiEnabled) { 81431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (enabled) { 815e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy Scanner scanner = null; 81682d94d9e9ee4eb6b14db3c8df2f47dcae5ce4ab0Romain Guy try { 8173a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron scanner = new Scanner(new File(MIDI_ALSA_PATH)); 8183a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron mMidiCard = scanner.nextInt(); 8194c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy mMidiDevice = scanner.nextInt(); 8203a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } catch (FileNotFoundException e) { 82131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.e(TAG, "could not open MIDI file", e); 8223a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron enabled = false; 82331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } finally { 82431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (scanner != null) { 825e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy scanner.close(); 826e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy } 827e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy } 82831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 82931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mMidiEnabled = enabled; 8303a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 83131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mUsbAlsaManager.setPeripheralMidiState( 83231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mMidiEnabled && mConfigured, mMidiCard, mMidiDevice); 83331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 83431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 83531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 8363a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron public void handleMessage(Message msg) { 8373a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron switch (msg.what) { 838f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy case MSG_UPDATE_STATE: 839f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy mConnected = (msg.arg1 == 1); 840c45b16862918a0c6c253bba12032165b030565afJoe Onorato mConfigured = (msg.arg2 == 1); 84131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 84231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateUsbNotification(); 84331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateAdbNotification(); 84431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (UsbManager.containsFunction(mCurrentFunctions, 84531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbManager.USB_FUNCTION_ACCESSORY)) { 84631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateCurrentAccessory(); 84731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8487984c9496bcaeca23ee7fdecc4d4f1bb2467e0f2Bjorn Bringert if (mBootCompleted) { 84931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!mConnected) { 85031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // restore defaults when USB is disconnected 85131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setEnabledFunctions(null, false, false); 85231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 85331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateUsbStateBroadcastIfNeeded(false); 85431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateUsbFunctions(); 85531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 85631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mPendingBootBroadcast = true; 85731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 85800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato break; 85931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MSG_UPDATE_HOST_STATE: 86031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project SomeArgs args = (SomeArgs) msg.obj; 86131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHostConnected = (args.argi1 == 1); 86231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mSourcePower = (args.argi2 == 1); 86331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mSinkPower = (args.argi3 == 1); 86431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project args.recycle(); 86531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateUsbNotification(); 86631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mBootCompleted) { 86731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateUsbStateBroadcastIfNeeded(false); 86831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 86931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mPendingBootBroadcast = true; 87031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 87131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 87231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MSG_UPDATE_CHARGING_STATE: 87331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mUsbCharging = (msg.arg1 == 1); 87431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateUsbNotification(); 87531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 87631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MSG_ENABLE_ADB: 87731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setAdbEnabled(msg.arg1 == 1); 87831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 87931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MSG_SET_CURRENT_FUNCTIONS: 88031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String functions = (String) msg.obj; 88131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setEnabledFunctions(functions, false, msg.arg1 == 1); 88231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 88331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MSG_UPDATE_USER_RESTRICTIONS: 88431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Restart the USB stack if USB transfer is enabled but no longer allowed. 88531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final boolean forceRestart = mUsbDataUnlocked 88631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project && isUsbDataTransferActive() 88731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project && !isUsbTransferAllowed(); 88831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setEnabledFunctions( 88931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart); 89031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 89131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MSG_SYSTEM_READY: 89200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato updateUsbNotification(); 89300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato updateAdbNotification(); 89470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey updateUsbFunctions(); 89531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 89631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MSG_BOOT_COMPLETED: 89731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mBootCompleted = true; 89831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mPendingBootBroadcast) { 89931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateUsbStateBroadcastIfNeeded(false); 90031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mPendingBootBroadcast = false; 90152d9cb32608e7c3d065b4fb8e97269e238f1683eRomain Guy } 90252d9cb32608e7c3d065b4fb8e97269e238f1683eRomain Guy setEnabledFunctions(null, false, false); 90331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mCurrentAccessory != null) { 90431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project getCurrentSettings().accessoryAttached(mCurrentAccessory); 90531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 90631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDebuggingManager != null) { 907263e019baafb3b6cbcfdef9c81d74a4bea769180Romain Guy mDebuggingManager.setAdbEnabled(mAdbEnabled); 90870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 90970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey break; 91031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case MSG_USER_SWITCHED: { 91184f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy if (mCurrentUser != msg.arg1) { 91231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Restart the USB stack and re-apply user restrictions for MTP or PTP. 91331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mUsbDataUnlocked 91452d9cb32608e7c3d065b4fb8e97269e238f1683eRomain Guy && isUsbDataTransferActive() 91531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project && mCurrentUser != UserHandle.USER_NULL) { 91631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.v(TAG, "Current user switched to " + msg.arg1 91731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project + "; resetting USB host stack for MTP or PTP"); 91831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // avoid leaking sensitive data from previous user 91931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setEnabledFunctions(mCurrentFunctions, true, false); 92000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 9214c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy mCurrentUser = msg.arg1; 92231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 92331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 92431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 92500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato case MSG_ACCESSORY_MODE_ENTER_TIMEOUT: { 92631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) { 92731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.v(TAG, "Accessory mode enter timeout: " + mConnected); 92831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 92900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (!mConnected) { 9304c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy notifyAccessoryModeExit(); 93131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 93231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 93331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 93431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 93531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 93631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 93731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private boolean isUsbDataTransferActive() { 93831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP) 93931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project || UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP); 94031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 94131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 94231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public UsbAccessory getCurrentAccessory() { 94331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mCurrentAccessory; 94431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 94531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 94631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void updateUsbNotification() { 94731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mNotificationManager == null || !mUseUsbNotification 94831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project || ("0".equals(SystemProperties.get("persist.charging.notify")))) { 94931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 95031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 95131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int id = 0; 95231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Resources r = mContext.getResources(); 95331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mConnected) { 95431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!mUsbDataUnlocked) { 95531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mSourcePower) { 95631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project id = com.android.internal.R.string.usb_supplying_notification_title; 95731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 95831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project id = com.android.internal.R.string.usb_charging_notification_title; 95931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 96031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (UsbManager.containsFunction(mCurrentFunctions, 96131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbManager.USB_FUNCTION_MTP)) { 96231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project id = com.android.internal.R.string.usb_mtp_notification_title; 9630d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato } else if (UsbManager.containsFunction(mCurrentFunctions, 96431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbManager.USB_FUNCTION_PTP)) { 96500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato id = com.android.internal.R.string.usb_ptp_notification_title; 966207e40ee66fddded52a028b8f68be3605da3df37Romain Guy } else if (UsbManager.containsFunction(mCurrentFunctions, 96700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato UsbManager.USB_FUNCTION_MIDI)) { 96800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato id = com.android.internal.R.string.usb_midi_notification_title; 969263e019baafb3b6cbcfdef9c81d74a4bea769180Romain Guy } else if (UsbManager.containsFunction(mCurrentFunctions, 97070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey UsbManager.USB_FUNCTION_ACCESSORY)) { 97131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project id = com.android.internal.R.string.usb_accessory_notification_title; 97231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (mSourcePower) { 97331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project id = com.android.internal.R.string.usb_supplying_notification_title; 97431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 97531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project id = com.android.internal.R.string.usb_charging_notification_title; 97670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 97770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } else if (mSourcePower) { 97870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey id = com.android.internal.R.string.usb_supplying_notification_title; 97970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } else if (mHostConnected && mSinkPower && mUsbCharging) { 98070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey id = com.android.internal.R.string.usb_charging_notification_title; 98170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 98270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if (id != mUsbNotificationId) { 98370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey // clear notification if title needs changing 98470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if (mUsbNotificationId != 0) { 98531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mNotificationManager.cancelAsUser(null, mUsbNotificationId, 98670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey UserHandle.ALL); 98770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey mUsbNotificationId = 0; 98870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 98970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if (id != 0) { 99000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato CharSequence message = r.getText( 9914c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy com.android.internal.R.string.usb_notification_message); 9924c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy CharSequence title = r.getText(id); 9934c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy 9944c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy Intent intent = Intent.makeRestartActivityTask( 9954c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy new ComponentName("com.android.settings", 9964c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy "com.android.settings.deviceinfo.UsbModeChooserActivity")); 9974c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, 9984c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy intent, 0, null, UserHandle.CURRENT); 9994c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy 10004c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy Notification notification = 10014c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy new Notification.Builder(mContext, SystemNotificationChannels.USB) 100270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 100370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setWhen(0) 100470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setOngoing(true) 100570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setTicker(title) 100670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setDefaults(0) // please be quiet 100770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setColor(mContext.getColor( 100800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato com.android.internal.R.color 100970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .system_notification_accent_color)) 101070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setContentTitle(title) 101131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project .setContentText(message) 101270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setContentIntent(pi) 101370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setVisibility(Notification.VISIBILITY_PUBLIC) 101470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .build(); 101570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey mNotificationManager.notifyAsUser(null, id, notification, 101670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey UserHandle.ALL); 101770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey mUsbNotificationId = id; 101870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 1019263e019baafb3b6cbcfdef9c81d74a4bea769180Romain Guy } 102070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 102170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 102270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private void updateAdbNotification() { 102370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if (mNotificationManager == null) return; 102470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey final int id = com.android.internal.R.string.adb_active_notification_title; 102570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if (mAdbEnabled && mConnected) { 102670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if ("0".equals(SystemProperties.get("persist.adb.notify"))) return; 102770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 102870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if (!mAdbNotificationShown) { 102970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey Resources r = mContext.getResources(); 103070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey CharSequence title = r.getText(id); 103170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey CharSequence message = r.getText( 103270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey com.android.internal.R.string.adb_active_notification_message); 103370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 103470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS); 103531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 103631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project | Intent.FLAG_ACTIVITY_CLEAR_TASK); 103770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, 103870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey intent, 0, null, UserHandle.CURRENT); 103970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 1040263e019baafb3b6cbcfdef9c81d74a4bea769180Romain Guy Notification notification = 104170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER) 104270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 104370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setWhen(0) 104470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setOngoing(true) 104570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setTicker(title) 104670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setDefaults(0) // please be quiet 104770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setColor(mContext.getColor( 104870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey com.android.internal.R.color 104970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .system_notification_accent_color)) 105070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setContentTitle(title) 105170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey .setContentText(message) 105231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project .setContentIntent(pi) 105331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project .setVisibility(Notification.VISIBILITY_PUBLIC) 105431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project .extend(new Notification.TvExtender() 105531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project .setChannel(ADB_NOTIFICATION_CHANNEL_ID_TV)) 105600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato .build(); 105700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mAdbNotificationShown = true; 105831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mNotificationManager.notifyAsUser(null, id, notification, 105931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UserHandle.ALL); 106031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1061207e40ee66fddded52a028b8f68be3605da3df37Romain Guy } else if (mAdbNotificationShown) { 1062207e40ee66fddded52a028b8f68be3605da3df37Romain Guy mAdbNotificationShown = false; 106331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); 106431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 106531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 106631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 106700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private String getDefaultFunctions() { 106800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato String func = SystemProperties.get(getPersistProp(true), 106900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato UsbManager.USB_FUNCTION_NONE); 1070207e40ee66fddded52a028b8f68be3605da3df37Romain Guy if (UsbManager.USB_FUNCTION_NONE.equals(func)) { 107131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project func = UsbManager.USB_FUNCTION_MTP; 107231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 107331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return func; 107431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 107531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 107631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void dump(IndentingPrintWriter pw) { 107731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pw.println("USB Device State:"); 107831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pw.println(" mCurrentFunctions: " + mCurrentFunctions); 107931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pw.println(" mCurrentOemFunctions: " + mCurrentOemFunctions); 108031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pw.println(" mCurrentFunctionsApplied: " + mCurrentFunctionsApplied); 108131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pw.println(" mConnected: " + mConnected); 108231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pw.println(" mConfigured: " + mConfigured); 10834c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy pw.println(" mUsbDataUnlocked: " + mUsbDataUnlocked); 1084f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy pw.println(" mCurrentAccessory: " + mCurrentAccessory); 1085f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy pw.println(" mHostConnected: " + mHostConnected); 1086f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy pw.println(" mSourcePower: " + mSourcePower); 1087f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy pw.println(" mSinkPower: " + mSinkPower); 108831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pw.println(" mUsbCharging: " + mUsbCharging); 108931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project try { 109031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pw.println(" Kernel state: " 109131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); 10924c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy pw.println(" Kernel function list: " 1093f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); 1094f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy } catch (IOException e) { 1095f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy pw.println("IOException: " + e); 1096f8e6a80acd4e5558fdf7e0559f1043a2b183a8faRomain Guy } 109731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 109831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 109931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 110031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /* returns the currently attached USB accessory */ 110131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public UsbAccessory getCurrentAccessory() { 110231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mHandler.getCurrentAccessory(); 110331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 110431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 110531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /* opens the currently attached USB accessory */ 110631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public ParcelFileDescriptor openAccessory(UsbAccessory accessory, 110731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbUserSettingsManager settings) { 110831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); 110931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (currentAccessory == null) { 111031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("no accessory attached"); 111131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 111231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!currentAccessory.equals(accessory)) { 1113138a04170d964da9cdec228e95b976875ae52481Karl Rosaen String error = accessory.toString() 111431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project + " does not match current accessory " 111531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project + currentAccessory; 111631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException(error); 111731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 111831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project settings.checkPermission(accessory); 111931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return nativeOpenAccessory(); 112031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 112131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 112231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean isFunctionEnabled(String function) { 112331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return UsbManager.containsFunction(SystemProperties.get(USB_CONFIG_PROPERTY), function); 112431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 112531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 112631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void setCurrentFunctions(String functions, boolean usbDataUnlocked) { 112731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (DEBUG) { 112831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Slog.d(TAG, "setCurrentFunctions(" + functions + ", " + 112931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project usbDataUnlocked + ")"); 113031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 113131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, usbDataUnlocked); 113231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 113331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 113431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void readOemUsbOverrideConfig() { 113531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String[] configList = mContext.getResources().getStringArray( 113631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project com.android.internal.R.array.config_oemUsbModeOverride); 113731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 113831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (configList != null) { 113931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (String config : configList) { 114031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project String[] items = config.split(":"); 114131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (items.length == 3 || items.length == 4) { 114231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mOemModeMap == null) { 114331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mOemModeMap = new HashMap<String, HashMap<String, 114431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Pair<String, String>>>(); 114531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 114631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project HashMap<String, Pair<String, String>> overrideMap 114731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project = mOemModeMap.get(items[0]); 114831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (overrideMap == null) { 114931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project overrideMap = new HashMap<String, 115031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Pair<String, String>>(); 115131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mOemModeMap.put(items[0], overrideMap); 115231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 115331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1154ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project // Favoring the first combination if duplicate exists 1155ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project if (!overrideMap.containsKey(items[1])) { 1156ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project if (items.length == 3) { 1157ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project overrideMap.put(items[1], 1158ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project new Pair<String, String>(items[2], "")); 1159ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project } else { 1160ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project overrideMap.put(items[1], 1161ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project new Pair<String, String>(items[2], items[3])); 116231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1163629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 116431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 11655c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 1166629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1167574d20ec84551370987dde530c27ec493bdef564Romain Guy } 116831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 116931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private String applyOemOverrideFunction(String usbFunctions) { 1170629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if ((usbFunctions == null) || (mOemModeMap == null)) { 1171629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy return usbFunctions; 1172629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1173629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1174629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 1175629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Slog.d(TAG, "applyOemOverride usbfunctions=" + usbFunctions + " bootmode=" + bootMode); 1176629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1177629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Map<String, Pair<String, String>> overridesMap = 1178629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mOemModeMap.get(bootMode); 1179629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy // Check to ensure that the oem is not overriding in the normal 1180629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy // boot mode 1181629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (overridesMap != null && !(bootMode.equals(NORMAL_BOOT) || 1182629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy bootMode.equals("unknown"))) { 1183629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Pair<String, String> overrideFunctions = 1184629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy overridesMap.get(usbFunctions); 1185629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (overrideFunctions != null) { 1186629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Slog.d(TAG, "OEM USB override: " + usbFunctions 1187629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy + " ==> " + overrideFunctions.first 1188629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy + " persist across reboot " 1189629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy + overrideFunctions.second); 1190629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (!overrideFunctions.second.equals("")) { 1191629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy String newFunction; 1192629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (mAdbEnabled) { 1193629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy newFunction = UsbManager.addFunction(overrideFunctions.second, 1194629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy UsbManager.USB_FUNCTION_ADB); 1195629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else { 1196629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy newFunction = UsbManager.addFunction(UsbManager.USB_FUNCTION_NONE, 1197629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy UsbManager.USB_FUNCTION_ADB); 1198629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1199629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Slog.d(TAG, "OEM USB override persisting: " + newFunction + "in prop: " 1200629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy + UsbDeviceManager.getPersistProp(false)); 1201629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy SystemProperties.set(UsbDeviceManager.getPersistProp(false), 1202629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy newFunction); 1203629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1204629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy return overrideFunctions.first; 1205629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (mAdbEnabled) { 1206629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy String newFunction = UsbManager.addFunction(UsbManager.USB_FUNCTION_NONE, 1207629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy UsbManager.USB_FUNCTION_ADB); 1208629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy SystemProperties.set(UsbDeviceManager.getPersistProp(false), 1209629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy newFunction); 1210629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else { 1211629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy SystemProperties.set(UsbDeviceManager.getPersistProp(false), 1212629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy UsbManager.USB_FUNCTION_NONE); 1213629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1214629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1215629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy // return passed in functions as is. 1216629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy return usbFunctions; 1217629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1218629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1219629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy public static String getPersistProp(boolean functions) { 1220629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 1221629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy String persistProp = USB_PERSISTENT_CONFIG_PROPERTY; 1222629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (!(bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown"))) { 1223629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (functions == true) { 1224629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy persistProp = "persist.sys.usb." + bootMode + ".func"; 1225629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else { 1226629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy persistProp = "persist.sys.usb." + bootMode + ".config"; 1227629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1228629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1229629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1230629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy return persistProp; 1231629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1232629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1233629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1234629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { 1235629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (mDebuggingManager != null) { 1236629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey); 1237629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1238629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1239629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1240629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy public void denyUsbDebugging() { 1241629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (mDebuggingManager != null) { 1242629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mDebuggingManager.denyUsbDebugging(); 1243629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1244629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1245574d20ec84551370987dde530c27ec493bdef564Romain Guy 1246574d20ec84551370987dde530c27ec493bdef564Romain Guy public void clearUsbDebuggingKeys() { 1247629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (mDebuggingManager != null) { 1248629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mDebuggingManager.clearUsbDebuggingKeys(); 1249629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else { 1250629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy throw new RuntimeException("Cannot clear Usb Debugging keys, " 1251629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy + "UsbDebuggingManager not enabled"); 1252629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1253629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1254629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1255574d20ec84551370987dde530c27ec493bdef564Romain Guy public void dump(IndentingPrintWriter pw) { 1256629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (mHandler != null) { 1257629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mHandler.dump(pw); 1258629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1259629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (mDebuggingManager != null) { 12605c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy mDebuggingManager.dump(pw); 126131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1262629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 126331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 126431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private native String[] nativeGetAccessoryStrings(); 1265f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1266f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project private native ParcelFileDescriptor nativeOpenAccessory(); 12679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 12689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private native boolean nativeIsStartRequested(); 1269f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1270f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project private native int nativeGetAudioMode(); 1271f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project} 1272f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project