146d0adf8256a42416584765625852b6e48497c90Mike Lockwood/* 246d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Copyright (C) 2011 The Android Open Source Project 346d0adf8256a42416584765625852b6e48497c90Mike Lockwood * 446d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 546d0adf8256a42416584765625852b6e48497c90Mike Lockwood * you may not use this file except in compliance with the License. 646d0adf8256a42416584765625852b6e48497c90Mike Lockwood * You may obtain a copy of the License at 746d0adf8256a42416584765625852b6e48497c90Mike Lockwood * 846d0adf8256a42416584765625852b6e48497c90Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 946d0adf8256a42416584765625852b6e48497c90Mike Lockwood * 1046d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Unless required by applicable law or agreed to in writing, software 1146d0adf8256a42416584765625852b6e48497c90Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 1246d0adf8256a42416584765625852b6e48497c90Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346d0adf8256a42416584765625852b6e48497c90Mike Lockwood * See the License for the specific language governing permissions an 1446d0adf8256a42416584765625852b6e48497c90Mike Lockwood * limitations under the License. 1546d0adf8256a42416584765625852b6e48497c90Mike Lockwood */ 1646d0adf8256a42416584765625852b6e48497c90Mike Lockwood 1746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodpackage com.android.server.usb; 1846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 19541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.app.Notification; 20541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.app.NotificationManager; 21fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.app.PendingIntent; 22d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwoodimport android.content.BroadcastReceiver; 23541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.content.ComponentName; 2446d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.ContentResolver; 2546d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.Context; 2646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.Intent; 2746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.IntentFilter; 2846d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.content.pm.PackageManager; 29541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.content.res.Resources; 30541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.database.ContentObserver; 3146d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.hardware.usb.UsbAccessory; 3246d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.hardware.usb.UsbManager; 3302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.FileUtils; 3446d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Handler; 3502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.HandlerThread; 3602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.Looper; 3746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Message; 3846d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.ParcelFileDescriptor; 3902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.Process; 40dab2072365565b4892be7910b0cdb870e83689f6RoboErikimport android.os.SystemClock; 41541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.os.SystemProperties; 4246d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.UEventObserver; 43fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.UserHandle; 44fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.storage.StorageManager; 45fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.storage.StorageVolume; 4646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.provider.Settings; 47afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport android.util.Pair; 4846d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.util.Slog; 4946d0adf8256a42416584765625852b6e48497c90Mike Lockwood 5046d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.File; 5146d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.FileDescriptor; 5246d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.FileNotFoundException; 5302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport java.io.IOException; 5446d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.PrintWriter; 55fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport java.util.HashMap; 56afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport java.util.LinkedList; 5746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.util.List; 58afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport java.util.Map; 599d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwoodimport java.util.Scanner; 6046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 6146d0adf8256a42416584765625852b6e48497c90Mike Lockwood/** 6246d0adf8256a42416584765625852b6e48497c90Mike Lockwood * UsbDeviceManager manages USB state in device mode. 6346d0adf8256a42416584765625852b6e48497c90Mike Lockwood */ 6446d0adf8256a42416584765625852b6e48497c90Mike Lockwoodpublic class UsbDeviceManager { 6502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 6646d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final String TAG = UsbDeviceManager.class.getSimpleName(); 67fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood private static final boolean DEBUG = false; 6846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 6902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String USB_STATE_MATCH = 7002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "DEVPATH=/devices/virtual/android_usb/android0"; 7102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String ACCESSORY_START_MATCH = 7202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "DEVPATH=/devices/virtual/misc/usb_accessory"; 7302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String FUNCTIONS_PATH = 7402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "/sys/class/android_usb/android0/functions"; 7502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String STATE_PATH = 7602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "/sys/class/android_usb/android0/state"; 7702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String MASS_STORAGE_FILE_PATH = 78629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood "/sys/class/android_usb/android0/f_mass_storage/lun/file"; 79629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood private static final String RNDIS_ETH_ADDR_PATH = 80629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood "/sys/class/android_usb/android0/f_rndis/ethaddr"; 819d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood private static final String AUDIO_SOURCE_PCM_PATH = 829d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood "/sys/class/android_usb/android0/f_audio_source/pcm"; 8346d0adf8256a42416584765625852b6e48497c90Mike Lockwood 8446d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final int MSG_UPDATE_STATE = 0; 8502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final int MSG_ENABLE_ADB = 1; 86166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private static final int MSG_SET_CURRENT_FUNCTIONS = 2; 87f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private static final int MSG_SYSTEM_READY = 3; 88d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private static final int MSG_BOOT_COMPLETED = 4; 8927bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey private static final int MSG_USER_SWITCHED = 5; 9046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 91166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private static final int AUDIO_MODE_NONE = 0; 92166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private static final int AUDIO_MODE_SOURCE = 1; 93166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 9446d0adf8256a42416584765625852b6e48497c90Mike Lockwood // Delay for debouncing USB disconnects. 9546d0adf8256a42416584765625852b6e48497c90Mike Lockwood // We often get rapid connect/disconnect events when enabling USB functions, 9646d0adf8256a42416584765625852b6e48497c90Mike Lockwood // which need debouncing. 9746d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final int UPDATE_DELAY = 1000; 9846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 99afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private static final String BOOT_MODE_PROPERTY = "ro.bootmode"; 100afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 10102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private UsbHandler mHandler; 102d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private boolean mBootCompleted; 10346d0adf8256a42416584765625852b6e48497c90Mike Lockwood 104fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey private final Object mLock = new Object(); 105fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey 10646d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final Context mContext; 10702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private final ContentResolver mContentResolver; 108fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey // @GuardedBy("mLock") 109fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey private UsbSettingsManager mCurrentSettings; 110541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private NotificationManager mNotificationManager; 11146d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final boolean mHasUsbAccessory; 1125787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood private boolean mUseUsbNotification; 113541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private boolean mAdbEnabled; 1149d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood private boolean mAudioSourceEnabled; 115afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private Map<String, List<Pair<String, String>>> mOemModeMap; 116166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private String[] mAccessoryStrings; 1174e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private UsbDebuggingManager mDebuggingManager; 118541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 119541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private class AdbSettingsObserver extends ContentObserver { 120541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood public AdbSettingsObserver() { 121541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood super(null); 122541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 123541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood @Override 124541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood public void onChange(boolean selfChange) { 125bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown boolean enable = (Settings.Global.getInt(mContentResolver, 126bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown Settings.Global.ADB_ENABLED, 0) > 0); 12702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.sendMessage(MSG_ENABLE_ADB, enable); 128541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 129541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 130541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 13146d0adf8256a42416584765625852b6e48497c90Mike Lockwood /* 13246d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Listens for uevent messages from the kernel to monitor the USB state 13346d0adf8256a42416584765625852b6e48497c90Mike Lockwood */ 13446d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final UEventObserver mUEventObserver = new UEventObserver() { 13546d0adf8256a42416584765625852b6e48497c90Mike Lockwood @Override 13646d0adf8256a42416584765625852b6e48497c90Mike Lockwood public void onUEvent(UEventObserver.UEvent event) { 137fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString()); 13846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 13902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String state = event.get("USB_STATE"); 14002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String accessory = event.get("ACCESSORY"); 14102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (state != null) { 14202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.updateState(state); 14302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("START".equals(accessory)) { 144fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.d(TAG, "got accessory start"); 145166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood startAccessoryMode(); 14646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 14746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 14846d0adf8256a42416584765625852b6e48497c90Mike Lockwood }; 14946d0adf8256a42416584765625852b6e48497c90Mike Lockwood 150fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey public UsbDeviceManager(Context context) { 15146d0adf8256a42416584765625852b6e48497c90Mike Lockwood mContext = context; 152541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood mContentResolver = context.getContentResolver(); 15346d0adf8256a42416584765625852b6e48497c90Mike Lockwood PackageManager pm = mContext.getPackageManager(); 15446d0adf8256a42416584765625852b6e48497c90Mike Lockwood mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); 155629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood initRndisAddress(); 15646d0adf8256a42416584765625852b6e48497c90Mike Lockwood 157afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo readOemUsbOverrideConfig(); 158afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 15902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // create a thread for our Handler 16002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood HandlerThread thread = new HandlerThread("UsbDeviceManager", 1613fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood Process.THREAD_PRIORITY_BACKGROUND); 16202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood thread.start(); 1633fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood mHandler = new UsbHandler(thread.getLooper()); 164d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 165d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (nativeIsStartRequested()) { 166d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "accessory attached at boot"); 167166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood startAccessoryMode(); 168d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } 1694e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 1704e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if ("1".equals(SystemProperties.get("ro.adb.secure"))) { 1714e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager = new UsbDebuggingManager(context); 1724e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 17302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 17402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 175fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey public void setCurrentSettings(UsbSettingsManager settings) { 176fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey synchronized (mLock) { 177fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey mCurrentSettings = settings; 178fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey } 179fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey } 180fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey 181fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey private UsbSettingsManager getCurrentSettings() { 182fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey synchronized (mLock) { 183fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey return mCurrentSettings; 184fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey } 185fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey } 186fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey 18702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void systemReady() { 188d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "systemReady"); 18902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 19002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mNotificationManager = (NotificationManager) 19102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mContext.getSystemService(Context.NOTIFICATION_SERVICE); 19246d0adf8256a42416584765625852b6e48497c90Mike Lockwood 1935787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood // We do not show the USB notification if the primary volume supports mass storage. 1945787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood // The legacy mass storage UI will be used instead. 1955787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood boolean massStorageSupported = false; 196b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey final StorageManager storageManager = StorageManager.from(mContext); 197b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey final StorageVolume primary = storageManager.getPrimaryVolume(); 198b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey massStorageSupported = primary != null && primary.allowMassStorage(); 1995787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood mUseUsbNotification = !massStorageSupported; 2005787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood 20102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // make sure the ADB_ENABLED setting value matches the current state 202bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0); 203541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 20402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.sendEmptyMessage(MSG_SYSTEM_READY); 20502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 206541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 207166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private void startAccessoryMode() { 208166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mAccessoryStrings = nativeGetAccessoryStrings(); 209166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE); 210166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood // don't start accessory mode if our mandatory strings have not been set 211166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood boolean enableAccessory = (mAccessoryStrings != null && 212166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null && 213166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mAccessoryStrings[UsbAccessory.MODEL_STRING] != null); 214166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood String functions = null; 215166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 216166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood if (enableAccessory && enableAudio) { 217166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood functions = UsbManager.USB_FUNCTION_ACCESSORY + "," 218166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood + UsbManager.USB_FUNCTION_AUDIO_SOURCE; 219166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } else if (enableAccessory) { 220166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood functions = UsbManager.USB_FUNCTION_ACCESSORY; 221166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } else if (enableAudio) { 222166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE; 223166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } 224166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 225166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood if (functions != null) { 226166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood setCurrentFunctions(functions, false); 227166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } 228166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } 229166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 230629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood private static void initRndisAddress() { 231629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // configure RNDIS ethernet address based on our serial number using the same algorithm 232629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // we had been previously using in kernel board files 233629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood final int ETH_ALEN = 6; 234629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood int address[] = new int[ETH_ALEN]; 235629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // first byte is 0x02 to signify a locally administered address 236629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[0] = 0x02; 237629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood 238629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF"); 239629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood int serialLength = serial.length(); 240629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // XOR the USB serial across the remaining 5 bytes 241629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood for (int i = 0; i < serialLength; i++) { 242629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[i % (ETH_ALEN - 1) + 1] ^= (int)serial.charAt(i); 243629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 244629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood String addrString = String.format("%02X:%02X:%02X:%02X:%02X:%02X", 245629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[0], address[1], address[2], address[3], address[4], address[5]); 246629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood try { 247629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString); 248629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } catch (IOException e) { 249629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood Slog.e(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH); 250629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 251629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 252629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood 25302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static String addFunction(String functions, String function) { 254dab2072365565b4892be7910b0cdb870e83689f6RoboErik if ("none".equals(functions)) { 255dab2072365565b4892be7910b0cdb870e83689f6RoboErik return function; 256dab2072365565b4892be7910b0cdb870e83689f6RoboErik } 25702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (!containsFunction(functions, function)) { 25802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (functions.length() > 0) { 25902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood functions += ","; 26046d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 26102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood functions += function; 26246d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 26302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return functions; 26446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 26546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 26602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static String removeFunction(String functions, String function) { 26702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String[] split = functions.split(","); 26802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < split.length; i++) { 26902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (function.equals(split[i])) { 27002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood split[i] = null; 27102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 27202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 273dab2072365565b4892be7910b0cdb870e83689f6RoboErik if (split.length == 1 && split[0] == null) { 274dab2072365565b4892be7910b0cdb870e83689f6RoboErik return "none"; 275dab2072365565b4892be7910b0cdb870e83689f6RoboErik } 27602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood StringBuilder builder = new StringBuilder(); 27702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < split.length; i++) { 27802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String s = split[i]; 27902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (s != null) { 28002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (builder.length() > 0) { 28102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood builder.append(","); 28202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 28302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood builder.append(s); 28402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 28502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 28602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return builder.toString(); 28702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 28846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 28902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static boolean containsFunction(String functions, String function) { 29002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int index = functions.indexOf(function); 29102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (index < 0) return false; 29202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (index > 0 && functions.charAt(index - 1) != ',') return false; 29302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int charAfter = index + function.length(); 29402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false; 29502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return true; 29602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 29702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 29802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private final class UsbHandler extends Handler { 29902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 30002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // current USB state 30102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private boolean mConnected; 30202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private boolean mConfigured; 30302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private String mCurrentFunctions; 30402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private String mDefaultFunctions; 30502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private UsbAccessory mCurrentAccessory; 306d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private int mUsbNotificationId; 307d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private boolean mAdbNotificationShown; 30827bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey private int mCurrentUser = UserHandle.USER_NULL; 309d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 310d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() { 31127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey @Override 312d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood public void onReceive(Context context, Intent intent) { 313d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "boot completed"); 314d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); 315d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } 316d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood }; 317d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 31827bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() { 31927bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey @Override 32027bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey public void onReceive(Context context, Intent intent) { 32127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 32227bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mHandler.obtainMessage(MSG_USER_SWITCHED, userId, 0).sendToTarget(); 32327bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey } 32427bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey }; 32527bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey 3263fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood public UsbHandler(Looper looper) { 3273fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood super(looper); 32802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood try { 329c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood // persist.sys.usb.config should never be unset. But if it is, set it to "adb" 330c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood // so we have a chance of debugging what happened. 331c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb"); 332afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 333afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // Check if USB mode needs to be overridden depending on OEM specific bootmode. 334afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo mDefaultFunctions = processOemUsbOverride(mDefaultFunctions); 335afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 336de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood // sanity check the sys.usb.config system property 337de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood // this may be necessary if we crashed while switching USB configurations 338de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood String config = SystemProperties.get("sys.usb.config", "none"); 339c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood if (!config.equals(mDefaultFunctions)) { 340c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions); 341c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood SystemProperties.set("sys.usb.config", mDefaultFunctions); 342de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood } 343de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood 344c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood mCurrentFunctions = mDefaultFunctions; 34502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); 34602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateState(state); 34702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB); 34802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 34902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // Upgrade step for previous versions that used persist.service.adb.enable 35002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String value = SystemProperties.get("persist.service.adb.enable", ""); 35102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (value.length() > 0) { 35202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood char enable = value.charAt(0); 35302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (enable == '1') { 35402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(true); 35502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if (enable == '0') { 35602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(false); 35702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 35802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood SystemProperties.set("persist.service.adb.enable", ""); 35902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 36002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 36102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // register observer to listen for settings changes 36202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mContentResolver.registerContentObserver( 363bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown Settings.Global.getUriFor(Settings.Global.ADB_ENABLED), 36402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood false, new AdbSettingsObserver()); 36502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 36602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // Watch for USB configuration changes 36702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mUEventObserver.startObserving(USB_STATE_MATCH); 36802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mUEventObserver.startObserving(ACCESSORY_START_MATCH); 369d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 37027bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mContext.registerReceiver( 37127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mBootCompletedReceiver, new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); 37227bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mContext.registerReceiver( 37327bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mUserSwitchedReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED)); 37402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } catch (Exception e) { 37502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "Error initializing UsbHandler", e); 37602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 37746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 37802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 37902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void sendMessage(int what, boolean arg) { 38002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(what); 38102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message m = Message.obtain(this, what); 38202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood m.arg1 = (arg ? 1 : 0); 38302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessage(m); 38446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 38546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 38602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void sendMessage(int what, Object arg) { 38702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(what); 38802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message m = Message.obtain(this, what); 38902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood m.obj = arg; 39002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessage(m); 39102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 39202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 393f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood public void sendMessage(int what, Object arg0, boolean arg1) { 394f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood removeMessages(what); 395f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood Message m = Message.obtain(this, what); 396f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood m.obj = arg0; 397f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood m.arg1 = (arg1 ? 1 : 0); 398f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood sendMessage(m); 399f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood } 400f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood 40102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void updateState(String state) { 40202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int connected, configured; 40302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 40402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if ("DISCONNECTED".equals(state)) { 40502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 0; 40602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 0; 40702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("CONNECTED".equals(state)) { 40802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 1; 40902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 0; 41002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("CONFIGURED".equals(state)) { 41102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 1; 41202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 1; 41302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else { 41402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "unknown state " + state); 41502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return; 41602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 41702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(MSG_UPDATE_STATE); 41802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message msg = Message.obtain(this, MSG_UPDATE_STATE); 41902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood msg.arg1 = connected; 42002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood msg.arg2 = configured; 42102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // debounce disconnects to avoid problems bringing up USB tethering 42202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0); 42302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 42402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 425f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private boolean waitForState(String state) { 42602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // wait for the transition to complete. 42702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // give up after 1 second. 42802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < 20; i++) { 42968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // State transition is done when sys.usb.state is set to the new configuration 430f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood if (state.equals(SystemProperties.get("sys.usb.state"))) return true; 431dab2072365565b4892be7910b0cdb870e83689f6RoboErik SystemClock.sleep(50); 43202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 433fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.e(TAG, "waitForState(" + state + ") FAILED"); 43402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return false; 43502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 43602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 437f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private boolean setUsbConfig(String config) { 438fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); 439f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // set the new configuration 440f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood SystemProperties.set("sys.usb.config", config); 441f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood return waitForState(config); 442f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood } 443f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood 44402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void setAdbEnabled(boolean enable) { 445de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); 44602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (enable != mAdbEnabled) { 44702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mAdbEnabled = enable; 448f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // Due to the persist.sys.usb.config property trigger, changing adb state requires 449f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // switching to default function 4501984e79d1593b80adf46b16666862f5787157aedMike Lockwood setEnabledFunctions(mDefaultFunctions, true); 451d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 45202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 4534e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 4544e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.setAdbEnabled(mAdbEnabled); 4554e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 45602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 45702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 45868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood private void setEnabledFunctions(String functions, boolean makeDefault) { 459afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 460afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // Do not update persystent.sys.usb.config if the device is booted up 461afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // with OEM specific mode. 462afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (functions != null && makeDefault && !needsOemUsbOverride()) { 463afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 4648b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood if (mAdbEnabled) { 4658b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); 4668b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood } else { 4678b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); 4688b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood } 46968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!mDefaultFunctions.equals(functions)) { 47068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!setUsbConfig("none")) { 47168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to disable USB"); 47268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 47368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 47468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood return; 47568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 47668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // setting this property will also change the current USB state 47768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // via a property trigger 47868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood SystemProperties.set("persist.sys.usb.config", functions); 47968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (waitForState(functions)) { 48068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mCurrentFunctions = functions; 48168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mDefaultFunctions = functions; 48268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 48368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to switch persistent USB config to " + functions); 48468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 48568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood SystemProperties.set("persist.sys.usb.config", mDefaultFunctions); 48668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 48768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 48868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 48968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (functions == null) { 49068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood functions = mDefaultFunctions; 49168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 492afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 493afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // Override with bootmode specific usb mode if needed 494afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo functions = processOemUsbOverride(functions); 495afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 4968b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood if (mAdbEnabled) { 4978b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); 4988b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood } else { 4998b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); 5008b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood } 50168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!mCurrentFunctions.equals(functions)) { 50268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!setUsbConfig("none")) { 50368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to disable USB"); 50468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 50568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 50668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood return; 50768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 50868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (setUsbConfig(functions)) { 50968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mCurrentFunctions = functions; 51068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 51168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to switch USB config to " + functions); 51268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 51368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 51468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 51568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 51602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 51702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 51802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 51902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void updateCurrentAccessory() { 52002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (!mHasUsbAccessory) return; 52102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 52202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mConfigured) { 523166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood if (mAccessoryStrings != null) { 524166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mCurrentAccessory = new UsbAccessory(mAccessoryStrings); 525fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory); 52602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // defer accessoryAttached if system is not ready 527d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 528fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey getCurrentSettings().accessoryAttached(mCurrentAccessory); 529d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } // else handle in mBootCompletedReceiver 53002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else { 531fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.e(TAG, "nativeGetAccessoryStrings failed"); 53202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 53302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if (!mConnected) { 53402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // make sure accessory mode is off 53502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // and restore default functions 536fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.d(TAG, "exited USB accessory mode"); 53768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setEnabledFunctions(mDefaultFunctions, false); 53802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 53902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mCurrentAccessory != null) { 540d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 541fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey getCurrentSettings().accessoryDetached(mCurrentAccessory); 54202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 54302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mCurrentAccessory = null; 544166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mAccessoryStrings = null; 54546d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 54646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 54746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 54846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 54902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void updateUsbState() { 55002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // send a sticky broadcast containing current USB state 55102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 55202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 55302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(UsbManager.USB_CONNECTED, mConnected); 55402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); 55502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 55602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mCurrentFunctions != null) { 55702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String[] functions = mCurrentFunctions.split(","); 55802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < functions.length; i++) { 55902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(functions[i], true); 56002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 56146d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 56202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 5635ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 56446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 56546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 566bf91046872dd711019e8dec543441601576cc950Mike Lockwood private void updateAudioSourceFunction() { 567bf91046872dd711019e8dec543441601576cc950Mike Lockwood boolean enabled = containsFunction(mCurrentFunctions, 568bf91046872dd711019e8dec543441601576cc950Mike Lockwood UsbManager.USB_FUNCTION_AUDIO_SOURCE); 569bf91046872dd711019e8dec543441601576cc950Mike Lockwood if (enabled != mAudioSourceEnabled) { 570bf91046872dd711019e8dec543441601576cc950Mike Lockwood // send a sticky broadcast containing current USB state 571bf91046872dd711019e8dec543441601576cc950Mike Lockwood Intent intent = new Intent(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG); 572bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 573bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 574bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.putExtra("state", (enabled ? 1 : 0)); 575bf91046872dd711019e8dec543441601576cc950Mike Lockwood if (enabled) { 576bf91046872dd711019e8dec543441601576cc950Mike Lockwood try { 577bf91046872dd711019e8dec543441601576cc950Mike Lockwood Scanner scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH)); 578bf91046872dd711019e8dec543441601576cc950Mike Lockwood int card = scanner.nextInt(); 579bf91046872dd711019e8dec543441601576cc950Mike Lockwood int device = scanner.nextInt(); 580bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.putExtra("card", card); 581bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.putExtra("device", device); 582bf91046872dd711019e8dec543441601576cc950Mike Lockwood } catch (FileNotFoundException e) { 583bf91046872dd711019e8dec543441601576cc950Mike Lockwood Slog.e(TAG, "could not open audio source PCM file", e); 584bf91046872dd711019e8dec543441601576cc950Mike Lockwood } 5859d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood } 5865ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 587bf91046872dd711019e8dec543441601576cc950Mike Lockwood mAudioSourceEnabled = enabled; 5889d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood } 5899d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood } 5909d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood 59102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood @Override 59202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void handleMessage(Message msg) { 59302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood switch (msg.what) { 59402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_UPDATE_STATE: 59502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mConnected = (msg.arg1 == 1); 59602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mConfigured = (msg.arg2 == 1); 597d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateUsbNotification(); 598d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 59902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (containsFunction(mCurrentFunctions, 60002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood UsbManager.USB_FUNCTION_ACCESSORY)) { 60102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateCurrentAccessory(); 60202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 60302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 60402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (!mConnected) { 60502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // restore defaults when USB is disconnected 60668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setEnabledFunctions(mDefaultFunctions, false); 60702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 608d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 60902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateUsbState(); 610bf91046872dd711019e8dec543441601576cc950Mike Lockwood updateAudioSourceFunction(); 61102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 61202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 61302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_ENABLE_ADB: 61402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(msg.arg1 == 1); 61502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 616166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood case MSG_SET_CURRENT_FUNCTIONS: 617166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood String functions = (String)msg.obj; 618f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood boolean makeDefault = (msg.arg1 == 1); 619166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood setEnabledFunctions(functions, makeDefault); 62002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 62102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_SYSTEM_READY: 622d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateUsbNotification(); 623d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 62402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateUsbState(); 625bf91046872dd711019e8dec543441601576cc950Mike Lockwood updateAudioSourceFunction(); 626d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood break; 627d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood case MSG_BOOT_COMPLETED: 628d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood mBootCompleted = true; 629d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mCurrentAccessory != null) { 630fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey getCurrentSettings().accessoryAttached(mCurrentAccessory); 63102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 6324e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 6334e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.setAdbEnabled(mAdbEnabled); 6344e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 63502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 63627bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey case MSG_USER_SWITCHED: { 63727bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey final boolean mtpActive = 63827bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP) 63927bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey || containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP); 64027bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey if (mtpActive && mCurrentUser != UserHandle.USER_NULL) { 64127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey Slog.v(TAG, "Current user switched; resetting USB host stack for MTP"); 64227bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey setUsbConfig("none"); 64327bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey setUsbConfig(mCurrentFunctions); 64427bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey } 64527bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mCurrentUser = msg.arg1; 64627bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey break; 64727bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey } 64846d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 64946d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 65046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 65102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public UsbAccessory getCurrentAccessory() { 65202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return mCurrentAccessory; 65302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 65402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 655d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private void updateUsbNotification() { 656d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mNotificationManager == null || !mUseUsbNotification) return; 657fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood int id = 0; 658a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood Resources r = mContext.getResources(); 659d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mConnected) { 660d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) { 661fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood id = com.android.internal.R.string.usb_mtp_notification_title; 662d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP)) { 663fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood id = com.android.internal.R.string.usb_ptp_notification_title; 664d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (containsFunction(mCurrentFunctions, 665d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood UsbManager.USB_FUNCTION_MASS_STORAGE)) { 666fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood id = com.android.internal.R.string.usb_cd_installer_notification_title; 6676e680dea3bc9e2d4ba1a09f428c303cd2a59c051Mike Lockwood } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) { 668fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood id = com.android.internal.R.string.usb_accessory_notification_title; 669d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else { 670a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood // There is a different notification for USB tethering so we don't need one here 6717ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn //if (!containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_RNDIS)) { 6727ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn // Slog.e(TAG, "No known USB function in updateUsbNotification"); 6737ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn //} 674d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 675a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood } 676a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood if (id != mUsbNotificationId) { 677a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood // clear notification if title needs changing 678fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood if (mUsbNotificationId != 0) { 67950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.cancelAsUser(null, mUsbNotificationId, 68050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle.ALL); 681fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood mUsbNotificationId = 0; 682a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood } 683fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood if (id != 0) { 684d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood CharSequence message = r.getText( 685d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.usb_notification_message); 686fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood CharSequence title = r.getText(id); 687d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 688d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Notification notification = new Notification(); 689d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.icon = com.android.internal.R.drawable.stat_sys_data_usb; 690d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.when = 0; 691d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.flags = Notification.FLAG_ONGOING_EVENT; 692d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.tickerText = title; 693d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.defaults = 0; // please be quiet 694d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.sound = null; 695d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.vibrate = null; 69649a2ad1f404622803faba0bc5937b8a39aba02b3Daniel Sandler notification.priority = Notification.PRIORITY_MIN; 697d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 698765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate Intent intent = Intent.makeRestartActivityTask( 699765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate new ComponentName("com.android.settings", 700765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate "com.android.settings.UsbSettings")); 70150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, 70250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn intent, 0, null, UserHandle.CURRENT); 703d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.setLatestEventInfo(mContext, title, message, pi); 70450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.notifyAsUser(null, id, notification, 70550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle.ALL); 706d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mUsbNotificationId = id; 707d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 708d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 709d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 710d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 711d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private void updateAdbNotification() { 712d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mNotificationManager == null) return; 713fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood final int id = com.android.internal.R.string.adb_active_notification_title; 714d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mAdbEnabled && mConnected) { 715d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if ("0".equals(SystemProperties.get("persist.adb.notify"))) return; 716d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 717d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (!mAdbNotificationShown) { 718d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Resources r = mContext.getResources(); 719fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood CharSequence title = r.getText(id); 720d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood CharSequence message = r.getText( 721d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.adb_active_notification_message); 722d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 723d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Notification notification = new Notification(); 724d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.icon = com.android.internal.R.drawable.stat_sys_adb; 725d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.when = 0; 726d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.flags = Notification.FLAG_ONGOING_EVENT; 727d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.tickerText = title; 728d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.defaults = 0; // please be quiet 729d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.sound = null; 730d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.vibrate = null; 731a25079e6bafcfd77135a852f0e838738d80606efDaniel Sandler notification.priority = Notification.PRIORITY_LOW; 732d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 733765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate Intent intent = Intent.makeRestartActivityTask( 734765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate new ComponentName("com.android.settings", 735765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate "com.android.settings.DevelopmentSettings")); 73650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, 73750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn intent, 0, null, UserHandle.CURRENT); 738d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.setLatestEventInfo(mContext, title, message, pi); 739d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mAdbNotificationShown = true; 74050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.notifyAsUser(null, id, notification, 74150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle.ALL); 742d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 743d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (mAdbNotificationShown) { 744d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mAdbNotificationShown = false; 74550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); 746d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 747d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 748d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 74902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void dump(FileDescriptor fd, PrintWriter pw) { 75002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" USB Device State:"); 75102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" Current Functions: " + mCurrentFunctions); 75202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" Default Functions: " + mDefaultFunctions); 75302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mConnected: " + mConnected); 75402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mConfigured: " + mConfigured); 75502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mCurrentAccessory: " + mCurrentAccessory); 7566ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood try { 7576ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Kernel state: " 7586ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); 7596ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Kernel function list: " 7606ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); 7616ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Mass storage backing file: " 7626ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(MASS_STORAGE_FILE_PATH), 0, null).trim()); 7636ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood } catch (IOException e) { 7646ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println("IOException: " + e); 7656ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood } 76602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 76746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 76846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 76902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood /* returns the currently attached USB accessory */ 77046d0adf8256a42416584765625852b6e48497c90Mike Lockwood public UsbAccessory getCurrentAccessory() { 77102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return mHandler.getCurrentAccessory(); 77246d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 77346d0adf8256a42416584765625852b6e48497c90Mike Lockwood 77402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood /* opens the currently attached USB accessory */ 775abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { 776abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); 777abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood if (currentAccessory == null) { 778abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood throw new IllegalArgumentException("no accessory attached"); 77946d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 780abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood if (!currentAccessory.equals(accessory)) { 781abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood String error = accessory.toString() 782abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood + " does not match current accessory " 783abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood + currentAccessory; 784abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood throw new IllegalArgumentException(error); 785abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood } 786fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey getCurrentSettings().checkPermission(accessory); 787abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood return nativeOpenAccessory(); 788abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood } 78902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 790166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood public void setCurrentFunctions(String functions, boolean makeDefault) { 791166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ") default: " + makeDefault); 792166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, makeDefault); 79302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 79446d0adf8256a42416584765625852b6e48497c90Mike Lockwood 79502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void setMassStorageBackingFile(String path) { 79602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (path == null) path = ""; 79702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood try { 79802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood FileUtils.stringToFile(MASS_STORAGE_FILE_PATH, path); 79902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } catch (IOException e) { 80002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "failed to write to " + MASS_STORAGE_FILE_PATH); 80146d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 80202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 80346d0adf8256a42416584765625852b6e48497c90Mike Lockwood 804afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private void readOemUsbOverrideConfig() { 805afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo String[] configList = mContext.getResources().getStringArray( 806afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo com.android.internal.R.array.config_oemUsbModeOverride); 807afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 808afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (configList != null) { 809afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo for (String config: configList) { 810afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo String[] items = config.split(":"); 811afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (items.length == 3) { 812afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (mOemModeMap == null) { 813afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo mOemModeMap = new HashMap<String, List<Pair<String, String>>>(); 814afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 815afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo List overrideList = mOemModeMap.get(items[0]); 816afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (overrideList == null) { 817afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo overrideList = new LinkedList<Pair<String, String>>(); 818afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo mOemModeMap.put(items[0], overrideList); 819afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 820afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo overrideList.add(new Pair<String, String>(items[1], items[2])); 821afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 822afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 823afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 824afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 825afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 826afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private boolean needsOemUsbOverride() { 827afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (mOemModeMap == null) return false; 828afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 829afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 830afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo return (mOemModeMap.get(bootMode) != null) ? true : false; 831afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 832afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 833afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private String processOemUsbOverride(String usbFunctions) { 834afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if ((usbFunctions == null) || (mOemModeMap == null)) return usbFunctions; 835afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 836afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 837afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 838afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo List<Pair<String, String>> overrides = mOemModeMap.get(bootMode); 839afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (overrides != null) { 840afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo for (Pair<String, String> pair: overrides) { 841afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (pair.first.equals(usbFunctions)) { 842afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo Slog.d(TAG, "OEM USB override: " + pair.first + " ==> " + pair.second); 843afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo return pair.second; 844afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 845afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 846afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 847afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // return passed in functions as is. 848afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo return usbFunctions; 849afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 850afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 8514e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { 8524e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 8534e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey); 8544e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 8554e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 8564e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 8574e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public void denyUsbDebugging() { 8584e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 8594e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.denyUsbDebugging(); 8604e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 8614e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 8624e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 86346d0adf8256a42416584765625852b6e48497c90Mike Lockwood public void dump(FileDescriptor fd, PrintWriter pw) { 86402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mHandler != null) { 86502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.dump(fd, pw); 86646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 8674e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 8684e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.dump(fd, pw); 8694e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 87046d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 87146d0adf8256a42416584765625852b6e48497c90Mike Lockwood 87246d0adf8256a42416584765625852b6e48497c90Mike Lockwood private native String[] nativeGetAccessoryStrings(); 87346d0adf8256a42416584765625852b6e48497c90Mike Lockwood private native ParcelFileDescriptor nativeOpenAccessory(); 874d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private native boolean nativeIsStartRequested(); 875166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private native int nativeGetAudioMode(); 87646d0adf8256a42416584765625852b6e48497c90Mike Lockwood} 877