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.Looper; 3646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Message; 3746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.ParcelFileDescriptor; 38dab2072365565b4892be7910b0cdb870e83689f6RoboErikimport android.os.SystemClock; 39541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.os.SystemProperties; 4046d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.UEventObserver; 41fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.UserHandle; 42fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.storage.StorageManager; 43fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport android.os.storage.StorageVolume; 4446d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.provider.Settings; 45afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport android.util.Pair; 4646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.util.Slog; 4746d0adf8256a42416584765625852b6e48497c90Mike Lockwood 488b2c3a14603d163d7564e6f60286995079687690Jeff Sharkeyimport com.android.internal.annotations.GuardedBy; 498d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackbornimport com.android.server.FgThread; 508b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey 5146d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.File; 5246d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.FileDescriptor; 5346d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.FileNotFoundException; 5402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport java.io.IOException; 5546d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.io.PrintWriter; 56fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkeyimport java.util.HashMap; 57afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport java.util.LinkedList; 5846d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.util.List; 59fea17de7aaa5729d3111102b2734b158403d2780Jeff Sharkeyimport java.util.Locale; 60afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondoimport java.util.Map; 619d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwoodimport java.util.Scanner; 6246d0adf8256a42416584765625852b6e48497c90Mike Lockwood 6346d0adf8256a42416584765625852b6e48497c90Mike Lockwood/** 6446d0adf8256a42416584765625852b6e48497c90Mike Lockwood * UsbDeviceManager manages USB state in device mode. 6546d0adf8256a42416584765625852b6e48497c90Mike Lockwood */ 6646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodpublic class UsbDeviceManager { 6702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 6846d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final String TAG = UsbDeviceManager.class.getSimpleName(); 69fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood private static final boolean DEBUG = false; 7046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 7102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String USB_STATE_MATCH = 7202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "DEVPATH=/devices/virtual/android_usb/android0"; 7302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String ACCESSORY_START_MATCH = 7402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "DEVPATH=/devices/virtual/misc/usb_accessory"; 7502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String FUNCTIONS_PATH = 7602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "/sys/class/android_usb/android0/functions"; 7702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String STATE_PATH = 7802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "/sys/class/android_usb/android0/state"; 7902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String MASS_STORAGE_FILE_PATH = 80629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood "/sys/class/android_usb/android0/f_mass_storage/lun/file"; 81629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood private static final String RNDIS_ETH_ADDR_PATH = 82629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood "/sys/class/android_usb/android0/f_rndis/ethaddr"; 839d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood private static final String AUDIO_SOURCE_PCM_PATH = 849d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood "/sys/class/android_usb/android0/f_audio_source/pcm"; 8546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 8646d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final int MSG_UPDATE_STATE = 0; 8702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final int MSG_ENABLE_ADB = 1; 88166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private static final int MSG_SET_CURRENT_FUNCTIONS = 2; 89f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private static final int MSG_SYSTEM_READY = 3; 90d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private static final int MSG_BOOT_COMPLETED = 4; 9127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey private static final int MSG_USER_SWITCHED = 5; 9246d0adf8256a42416584765625852b6e48497c90Mike Lockwood 93166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private static final int AUDIO_MODE_NONE = 0; 94166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private static final int AUDIO_MODE_SOURCE = 1; 95166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 9646d0adf8256a42416584765625852b6e48497c90Mike Lockwood // Delay for debouncing USB disconnects. 9746d0adf8256a42416584765625852b6e48497c90Mike Lockwood // We often get rapid connect/disconnect events when enabling USB functions, 9846d0adf8256a42416584765625852b6e48497c90Mike Lockwood // which need debouncing. 9946d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final int UPDATE_DELAY = 1000; 10046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 101c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood // Time we received a request to enter USB accessory mode 102c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood private long mAccessoryModeRequestTime = 0; 103c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood 104c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood // Timeout for entering USB request mode. 105c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood // Request is cancelled if host does not configure device within 10 seconds. 106c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000; 107c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood 108afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private static final String BOOT_MODE_PROPERTY = "ro.bootmode"; 109afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 11002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private UsbHandler mHandler; 111d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private boolean mBootCompleted; 11246d0adf8256a42416584765625852b6e48497c90Mike Lockwood 113fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey private final Object mLock = new Object(); 114fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey 11546d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final Context mContext; 11602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private final ContentResolver mContentResolver; 1178b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey @GuardedBy("mLock") 118fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey private UsbSettingsManager mCurrentSettings; 119541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private NotificationManager mNotificationManager; 12046d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final boolean mHasUsbAccessory; 1215787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood private boolean mUseUsbNotification; 122541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private boolean mAdbEnabled; 1239d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood private boolean mAudioSourceEnabled; 124afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private Map<String, List<Pair<String, String>>> mOemModeMap; 125166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private String[] mAccessoryStrings; 1264e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private UsbDebuggingManager mDebuggingManager; 127541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 128541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private class AdbSettingsObserver extends ContentObserver { 129541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood public AdbSettingsObserver() { 130541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood super(null); 131541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 132541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood @Override 133541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood public void onChange(boolean selfChange) { 134bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown boolean enable = (Settings.Global.getInt(mContentResolver, 135bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown Settings.Global.ADB_ENABLED, 0) > 0); 13602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.sendMessage(MSG_ENABLE_ADB, enable); 137541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 138541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 139541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 14046d0adf8256a42416584765625852b6e48497c90Mike Lockwood /* 14146d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Listens for uevent messages from the kernel to monitor the USB state 14246d0adf8256a42416584765625852b6e48497c90Mike Lockwood */ 14346d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final UEventObserver mUEventObserver = new UEventObserver() { 14446d0adf8256a42416584765625852b6e48497c90Mike Lockwood @Override 14546d0adf8256a42416584765625852b6e48497c90Mike Lockwood public void onUEvent(UEventObserver.UEvent event) { 146fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString()); 14746d0adf8256a42416584765625852b6e48497c90Mike Lockwood 14802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String state = event.get("USB_STATE"); 14902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String accessory = event.get("ACCESSORY"); 15002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (state != null) { 15102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.updateState(state); 15202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("START".equals(accessory)) { 153fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.d(TAG, "got accessory start"); 154205a3ea0e2c49bc4d0ed534469f3a6920c14c4feMike Lockwood startAccessoryMode(); 15546d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 15646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 15746d0adf8256a42416584765625852b6e48497c90Mike Lockwood }; 15846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 159fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey public UsbDeviceManager(Context context) { 16046d0adf8256a42416584765625852b6e48497c90Mike Lockwood mContext = context; 161541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood mContentResolver = context.getContentResolver(); 16246d0adf8256a42416584765625852b6e48497c90Mike Lockwood PackageManager pm = mContext.getPackageManager(); 16346d0adf8256a42416584765625852b6e48497c90Mike Lockwood mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); 164629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood initRndisAddress(); 16546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 166afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo readOemUsbOverrideConfig(); 167afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 1688d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandler = new UsbHandler(FgThread.get().getLooper()); 169d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 170d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (nativeIsStartRequested()) { 171d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "accessory attached at boot"); 172205a3ea0e2c49bc4d0ed534469f3a6920c14c4feMike Lockwood startAccessoryMode(); 173d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } 1744e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 17578a9687fc2eab03b9d764cd27eaa1d56c66960beBenoit Goby boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false); 17678a9687fc2eab03b9d764cd27eaa1d56c66960beBenoit Goby boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt")); 17778a9687fc2eab03b9d764cd27eaa1d56c66960beBenoit Goby if (secureAdbEnabled && !dataEncrypted) { 1784e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager = new UsbDebuggingManager(context); 1794e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 18002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 18102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 182fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey public void setCurrentSettings(UsbSettingsManager settings) { 183fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey synchronized (mLock) { 184fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey mCurrentSettings = settings; 185fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey } 186fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey } 187fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey 188fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey private UsbSettingsManager getCurrentSettings() { 189fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey synchronized (mLock) { 190fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey return mCurrentSettings; 191fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey } 192fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey } 193fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey 19402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void systemReady() { 195d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "systemReady"); 19602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 19702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mNotificationManager = (NotificationManager) 19802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mContext.getSystemService(Context.NOTIFICATION_SERVICE); 19946d0adf8256a42416584765625852b6e48497c90Mike Lockwood 2005787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood // We do not show the USB notification if the primary volume supports mass storage. 2015787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood // The legacy mass storage UI will be used instead. 2025787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood boolean massStorageSupported = false; 203b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey final StorageManager storageManager = StorageManager.from(mContext); 204b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey final StorageVolume primary = storageManager.getPrimaryVolume(); 205b049e212ab7fe8967893c202efcb30fecfdb82fbJeff Sharkey massStorageSupported = primary != null && primary.allowMassStorage(); 2065787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood mUseUsbNotification = !massStorageSupported; 2075787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood 20802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // make sure the ADB_ENABLED setting value matches the current state 209bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0); 210541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 21102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.sendEmptyMessage(MSG_SYSTEM_READY); 21202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 213541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 214166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private void startAccessoryMode() { 215c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood if (!mHasUsbAccessory) return; 216c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood 217166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mAccessoryStrings = nativeGetAccessoryStrings(); 218166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE); 219166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood // don't start accessory mode if our mandatory strings have not been set 220166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood boolean enableAccessory = (mAccessoryStrings != null && 221166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null && 222166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mAccessoryStrings[UsbAccessory.MODEL_STRING] != null); 223166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood String functions = null; 224166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 225166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood if (enableAccessory && enableAudio) { 226166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood functions = UsbManager.USB_FUNCTION_ACCESSORY + "," 227166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood + UsbManager.USB_FUNCTION_AUDIO_SOURCE; 228166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } else if (enableAccessory) { 229166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood functions = UsbManager.USB_FUNCTION_ACCESSORY; 230166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } else if (enableAudio) { 231166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE; 232166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } 233166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 234166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood if (functions != null) { 235c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood mAccessoryModeRequestTime = SystemClock.elapsedRealtime(); 236166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood setCurrentFunctions(functions, false); 237166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } 238166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood } 239166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 240629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood private static void initRndisAddress() { 241629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // configure RNDIS ethernet address based on our serial number using the same algorithm 242629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // we had been previously using in kernel board files 243629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood final int ETH_ALEN = 6; 244629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood int address[] = new int[ETH_ALEN]; 245629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // first byte is 0x02 to signify a locally administered address 246629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[0] = 0x02; 247629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood 248629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF"); 249629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood int serialLength = serial.length(); 250629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // XOR the USB serial across the remaining 5 bytes 251629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood for (int i = 0; i < serialLength; i++) { 252629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[i % (ETH_ALEN - 1) + 1] ^= (int)serial.charAt(i); 253629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 254fea17de7aaa5729d3111102b2734b158403d2780Jeff Sharkey String addrString = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", 255629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[0], address[1], address[2], address[3], address[4], address[5]); 256629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood try { 257629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString); 258629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } catch (IOException e) { 259629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood Slog.e(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH); 260629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 261629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 262629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood 26302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static String addFunction(String functions, String function) { 264dab2072365565b4892be7910b0cdb870e83689f6RoboErik if ("none".equals(functions)) { 265dab2072365565b4892be7910b0cdb870e83689f6RoboErik return function; 266dab2072365565b4892be7910b0cdb870e83689f6RoboErik } 26702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (!containsFunction(functions, function)) { 26802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (functions.length() > 0) { 26902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood functions += ","; 27046d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 27102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood functions += function; 27246d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 27302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return functions; 27446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 27546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 27602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static String removeFunction(String functions, String function) { 27702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String[] split = functions.split(","); 27802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < split.length; i++) { 27902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (function.equals(split[i])) { 28002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood split[i] = null; 28102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 28202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 283dab2072365565b4892be7910b0cdb870e83689f6RoboErik if (split.length == 1 && split[0] == null) { 284dab2072365565b4892be7910b0cdb870e83689f6RoboErik return "none"; 285dab2072365565b4892be7910b0cdb870e83689f6RoboErik } 28602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood StringBuilder builder = new StringBuilder(); 28702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < split.length; i++) { 28802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String s = split[i]; 28902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (s != null) { 29002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (builder.length() > 0) { 29102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood builder.append(","); 29202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 29302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood builder.append(s); 29402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 29502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 29602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return builder.toString(); 29702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 29846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 29902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static boolean containsFunction(String functions, String function) { 30002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int index = functions.indexOf(function); 30102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (index < 0) return false; 30202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (index > 0 && functions.charAt(index - 1) != ',') return false; 30302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int charAfter = index + function.length(); 30402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false; 30502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return true; 30602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 30702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 30802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private final class UsbHandler extends Handler { 30902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 31002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // current USB state 31102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private boolean mConnected; 31202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private boolean mConfigured; 31302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private String mCurrentFunctions; 31402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private String mDefaultFunctions; 31502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private UsbAccessory mCurrentAccessory; 316d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private int mUsbNotificationId; 317d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private boolean mAdbNotificationShown; 31827bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey private int mCurrentUser = UserHandle.USER_NULL; 319d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 320d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() { 32127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey @Override 322d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood public void onReceive(Context context, Intent intent) { 323d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "boot completed"); 324d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); 325d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } 326d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood }; 327d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 32827bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() { 32927bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey @Override 33027bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey public void onReceive(Context context, Intent intent) { 33127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 33227bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mHandler.obtainMessage(MSG_USER_SWITCHED, userId, 0).sendToTarget(); 33327bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey } 33427bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey }; 33527bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey 3363fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood public UsbHandler(Looper looper) { 3373fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood super(looper); 33802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood try { 339c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood // persist.sys.usb.config should never be unset. But if it is, set it to "adb" 340c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood // so we have a chance of debugging what happened. 341c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb"); 342afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 343afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // Check if USB mode needs to be overridden depending on OEM specific bootmode. 344afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo mDefaultFunctions = processOemUsbOverride(mDefaultFunctions); 345afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 346de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood // sanity check the sys.usb.config system property 347de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood // this may be necessary if we crashed while switching USB configurations 348de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood String config = SystemProperties.get("sys.usb.config", "none"); 349c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood if (!config.equals(mDefaultFunctions)) { 350c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions); 351c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood SystemProperties.set("sys.usb.config", mDefaultFunctions); 352de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood } 353de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood 354c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood mCurrentFunctions = mDefaultFunctions; 35502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); 35602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateState(state); 35702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB); 35802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 35902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // Upgrade step for previous versions that used persist.service.adb.enable 36002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String value = SystemProperties.get("persist.service.adb.enable", ""); 36102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (value.length() > 0) { 36202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood char enable = value.charAt(0); 36302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (enable == '1') { 36402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(true); 36502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if (enable == '0') { 36602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(false); 36702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 36802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood SystemProperties.set("persist.service.adb.enable", ""); 36902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 37002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 37102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // register observer to listen for settings changes 37202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mContentResolver.registerContentObserver( 373bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown Settings.Global.getUriFor(Settings.Global.ADB_ENABLED), 37402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood false, new AdbSettingsObserver()); 37502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 37602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // Watch for USB configuration changes 37702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mUEventObserver.startObserving(USB_STATE_MATCH); 37802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mUEventObserver.startObserving(ACCESSORY_START_MATCH); 379d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 38027bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mContext.registerReceiver( 38127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mBootCompletedReceiver, new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); 38227bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mContext.registerReceiver( 38327bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mUserSwitchedReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED)); 38402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } catch (Exception e) { 38502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "Error initializing UsbHandler", e); 38602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 38746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 38802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 38902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void sendMessage(int what, boolean arg) { 39002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(what); 39102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message m = Message.obtain(this, what); 39202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood m.arg1 = (arg ? 1 : 0); 39302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessage(m); 39446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 39546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 39602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void sendMessage(int what, Object arg) { 39702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(what); 39802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message m = Message.obtain(this, what); 39902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood m.obj = arg; 40002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessage(m); 40102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 40202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 403f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood public void sendMessage(int what, Object arg0, boolean arg1) { 404f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood removeMessages(what); 405f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood Message m = Message.obtain(this, what); 406f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood m.obj = arg0; 407f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood m.arg1 = (arg1 ? 1 : 0); 408f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood sendMessage(m); 409f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood } 410f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood 41102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void updateState(String state) { 41202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int connected, configured; 41302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 41402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if ("DISCONNECTED".equals(state)) { 41502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 0; 41602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 0; 41702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("CONNECTED".equals(state)) { 41802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 1; 41902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 0; 42002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("CONFIGURED".equals(state)) { 42102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 1; 42202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 1; 42302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else { 42402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "unknown state " + state); 42502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return; 42602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 42702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(MSG_UPDATE_STATE); 42802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message msg = Message.obtain(this, MSG_UPDATE_STATE); 42902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood msg.arg1 = connected; 43002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood msg.arg2 = configured; 43102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // debounce disconnects to avoid problems bringing up USB tethering 43202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0); 43302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 43402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 435f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private boolean waitForState(String state) { 43602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // wait for the transition to complete. 43702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // give up after 1 second. 43802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < 20; i++) { 43968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // State transition is done when sys.usb.state is set to the new configuration 440f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood if (state.equals(SystemProperties.get("sys.usb.state"))) return true; 441dab2072365565b4892be7910b0cdb870e83689f6RoboErik SystemClock.sleep(50); 44202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 443fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.e(TAG, "waitForState(" + state + ") FAILED"); 44402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return false; 44502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 44602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 447f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private boolean setUsbConfig(String config) { 448fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); 449f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // set the new configuration 450f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood SystemProperties.set("sys.usb.config", config); 451f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood return waitForState(config); 452f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood } 453f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood 45402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void setAdbEnabled(boolean enable) { 455de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); 45602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (enable != mAdbEnabled) { 45702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mAdbEnabled = enable; 458f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // Due to the persist.sys.usb.config property trigger, changing adb state requires 459f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // switching to default function 4601984e79d1593b80adf46b16666862f5787157aedMike Lockwood setEnabledFunctions(mDefaultFunctions, true); 461d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 46202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 4634e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 4644e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.setAdbEnabled(mAdbEnabled); 4654e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 46602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 46702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 46868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood private void setEnabledFunctions(String functions, boolean makeDefault) { 469c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions 470c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood + " makeDefault: " + makeDefault); 471afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 472afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // Do not update persystent.sys.usb.config if the device is booted up 473afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // with OEM specific mode. 474afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (functions != null && makeDefault && !needsOemUsbOverride()) { 475afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 4768b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood if (mAdbEnabled) { 4778b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); 4788b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood } else { 4798b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); 4808b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood } 48168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!mDefaultFunctions.equals(functions)) { 48268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!setUsbConfig("none")) { 48368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to disable USB"); 48468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 48568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 48668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood return; 48768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 48868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // setting this property will also change the current USB state 48968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // via a property trigger 49068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood SystemProperties.set("persist.sys.usb.config", functions); 49168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (waitForState(functions)) { 49268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mCurrentFunctions = functions; 49368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mDefaultFunctions = functions; 49468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 49568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to switch persistent USB config to " + functions); 49668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 49768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood SystemProperties.set("persist.sys.usb.config", mDefaultFunctions); 49868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 49968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 50068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 50168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (functions == null) { 50268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood functions = mDefaultFunctions; 50368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 504afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 505afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // Override with bootmode specific usb mode if needed 506afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo functions = processOemUsbOverride(functions); 507afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 5088b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood if (mAdbEnabled) { 5098b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); 5108b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood } else { 5118b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); 5128b4d36e8661e25fcb893e00be15ba02da0950055Mike Lockwood } 51368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!mCurrentFunctions.equals(functions)) { 51468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!setUsbConfig("none")) { 51568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to disable USB"); 51668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 51768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 51868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood return; 51968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 52068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (setUsbConfig(functions)) { 52168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mCurrentFunctions = functions; 52268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 52368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to switch USB config to " + functions); 52468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 52568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 52668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 52768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 52802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 52902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 53002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 53102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void updateCurrentAccessory() { 532c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood // We are entering accessory mode if we have received a request from the host 533c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood // and the request has not timed out yet. 534c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood boolean enteringAccessoryMode = 535c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood mAccessoryModeRequestTime > 0 && 536c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood SystemClock.elapsedRealtime() < 537c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood mAccessoryModeRequestTime + ACCESSORY_REQUEST_TIMEOUT; 538c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood 539c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood if (mConfigured && enteringAccessoryMode) { 540c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood // successfully entered accessory mode 54102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 542166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood if (mAccessoryStrings != null) { 543166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mCurrentAccessory = new UsbAccessory(mAccessoryStrings); 544fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory); 54502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // defer accessoryAttached if system is not ready 546d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 547fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey getCurrentSettings().accessoryAttached(mCurrentAccessory); 548d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } // else handle in mBootCompletedReceiver 54902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else { 550fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.e(TAG, "nativeGetAccessoryStrings failed"); 55102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 552c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood } else if (!enteringAccessoryMode) { 55302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // make sure accessory mode is off 55402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // and restore default functions 555fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.d(TAG, "exited USB accessory mode"); 55668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setEnabledFunctions(mDefaultFunctions, false); 55702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 55802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mCurrentAccessory != null) { 559d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 560fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey getCurrentSettings().accessoryDetached(mCurrentAccessory); 56102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 56202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mCurrentAccessory = null; 563166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mAccessoryStrings = null; 56446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 56546d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 56646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 56746d0adf8256a42416584765625852b6e48497c90Mike Lockwood 56802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void updateUsbState() { 56902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // send a sticky broadcast containing current USB state 57002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 57102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 57202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(UsbManager.USB_CONNECTED, mConnected); 57302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); 57402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 57502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mCurrentFunctions != null) { 57602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String[] functions = mCurrentFunctions.split(","); 57702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < functions.length; i++) { 57802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(functions[i], true); 57902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 58046d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 58102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 582c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " connected: " + mConnected 583c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood + " configured: " + mConfigured); 5845ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 58546d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 58646d0adf8256a42416584765625852b6e48497c90Mike Lockwood 587bf91046872dd711019e8dec543441601576cc950Mike Lockwood private void updateAudioSourceFunction() { 588bf91046872dd711019e8dec543441601576cc950Mike Lockwood boolean enabled = containsFunction(mCurrentFunctions, 589bf91046872dd711019e8dec543441601576cc950Mike Lockwood UsbManager.USB_FUNCTION_AUDIO_SOURCE); 590bf91046872dd711019e8dec543441601576cc950Mike Lockwood if (enabled != mAudioSourceEnabled) { 591bf91046872dd711019e8dec543441601576cc950Mike Lockwood // send a sticky broadcast containing current USB state 592bf91046872dd711019e8dec543441601576cc950Mike Lockwood Intent intent = new Intent(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG); 593bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 594bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 595bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.putExtra("state", (enabled ? 1 : 0)); 596bf91046872dd711019e8dec543441601576cc950Mike Lockwood if (enabled) { 597bf91046872dd711019e8dec543441601576cc950Mike Lockwood try { 598bf91046872dd711019e8dec543441601576cc950Mike Lockwood Scanner scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH)); 599bf91046872dd711019e8dec543441601576cc950Mike Lockwood int card = scanner.nextInt(); 600bf91046872dd711019e8dec543441601576cc950Mike Lockwood int device = scanner.nextInt(); 601bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.putExtra("card", card); 602bf91046872dd711019e8dec543441601576cc950Mike Lockwood intent.putExtra("device", device); 603bf91046872dd711019e8dec543441601576cc950Mike Lockwood } catch (FileNotFoundException e) { 604bf91046872dd711019e8dec543441601576cc950Mike Lockwood Slog.e(TAG, "could not open audio source PCM file", e); 605bf91046872dd711019e8dec543441601576cc950Mike Lockwood } 6069d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood } 6075ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 608bf91046872dd711019e8dec543441601576cc950Mike Lockwood mAudioSourceEnabled = enabled; 6099d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood } 6109d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood } 6119d5a4be05b6d51ebb768e5fbcfa27ed9a39269b3Mike Lockwood 61202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood @Override 61302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void handleMessage(Message msg) { 61402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood switch (msg.what) { 61502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_UPDATE_STATE: 61602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mConnected = (msg.arg1 == 1); 61702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mConfigured = (msg.arg2 == 1); 618d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateUsbNotification(); 619d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 62002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (containsFunction(mCurrentFunctions, 62102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood UsbManager.USB_FUNCTION_ACCESSORY)) { 62202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateCurrentAccessory(); 623c62f918e0eabd5c036ba43172d36f587157feed6Mike Lockwood } else if (!mConnected) { 62402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // restore defaults when USB is disconnected 62568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setEnabledFunctions(mDefaultFunctions, false); 62602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 627d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 62802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateUsbState(); 629bf91046872dd711019e8dec543441601576cc950Mike Lockwood updateAudioSourceFunction(); 63002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 63102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 63202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_ENABLE_ADB: 63302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(msg.arg1 == 1); 63402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 635166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood case MSG_SET_CURRENT_FUNCTIONS: 636166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood String functions = (String)msg.obj; 637f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood boolean makeDefault = (msg.arg1 == 1); 638166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood setEnabledFunctions(functions, makeDefault); 63902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 64002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_SYSTEM_READY: 641d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateUsbNotification(); 642d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 64302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateUsbState(); 644bf91046872dd711019e8dec543441601576cc950Mike Lockwood updateAudioSourceFunction(); 645d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood break; 646d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood case MSG_BOOT_COMPLETED: 647d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood mBootCompleted = true; 648d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mCurrentAccessory != null) { 649fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey getCurrentSettings().accessoryAttached(mCurrentAccessory); 65002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 6514e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 6524e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.setAdbEnabled(mAdbEnabled); 6534e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 65402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 65527bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey case MSG_USER_SWITCHED: { 65627bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey final boolean mtpActive = 65727bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP) 65827bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey || containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP); 65927bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey if (mtpActive && mCurrentUser != UserHandle.USER_NULL) { 66027bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey Slog.v(TAG, "Current user switched; resetting USB host stack for MTP"); 66127bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey setUsbConfig("none"); 66227bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey setUsbConfig(mCurrentFunctions); 66327bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey } 66427bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey mCurrentUser = msg.arg1; 66527bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey break; 66627bd34d9d9fe99f11b80aa0bbdb402fb47ef4158Jeff Sharkey } 66746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 66846d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 66946d0adf8256a42416584765625852b6e48497c90Mike Lockwood 67002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public UsbAccessory getCurrentAccessory() { 67102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return mCurrentAccessory; 67202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 67302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 674d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private void updateUsbNotification() { 675d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mNotificationManager == null || !mUseUsbNotification) return; 676fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood int id = 0; 677a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood Resources r = mContext.getResources(); 678d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mConnected) { 679d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) { 680fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood id = com.android.internal.R.string.usb_mtp_notification_title; 681d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP)) { 682fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood id = com.android.internal.R.string.usb_ptp_notification_title; 683d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (containsFunction(mCurrentFunctions, 684d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood UsbManager.USB_FUNCTION_MASS_STORAGE)) { 685fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood id = com.android.internal.R.string.usb_cd_installer_notification_title; 6866e680dea3bc9e2d4ba1a09f428c303cd2a59c051Mike Lockwood } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) { 687fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood id = com.android.internal.R.string.usb_accessory_notification_title; 688d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else { 689a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood // There is a different notification for USB tethering so we don't need one here 6907ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn //if (!containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_RNDIS)) { 6917ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn // Slog.e(TAG, "No known USB function in updateUsbNotification"); 6927ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn //} 693d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 694a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood } 695a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood if (id != mUsbNotificationId) { 696a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood // clear notification if title needs changing 697fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood if (mUsbNotificationId != 0) { 69850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.cancelAsUser(null, mUsbNotificationId, 69950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle.ALL); 700fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood mUsbNotificationId = 0; 701a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood } 702fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood if (id != 0) { 703d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood CharSequence message = r.getText( 704d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.usb_notification_message); 705fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood CharSequence title = r.getText(id); 706d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 707d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Notification notification = new Notification(); 708d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.icon = com.android.internal.R.drawable.stat_sys_data_usb; 709d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.when = 0; 710d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.flags = Notification.FLAG_ONGOING_EVENT; 711d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.tickerText = title; 712d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.defaults = 0; // please be quiet 713d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.sound = null; 714d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.vibrate = null; 71549a2ad1f404622803faba0bc5937b8a39aba02b3Daniel Sandler notification.priority = Notification.PRIORITY_MIN; 716d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 717765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate Intent intent = Intent.makeRestartActivityTask( 718765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate new ComponentName("com.android.settings", 719765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate "com.android.settings.UsbSettings")); 72050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, 72150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn intent, 0, null, UserHandle.CURRENT); 722d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.setLatestEventInfo(mContext, title, message, pi); 72350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.notifyAsUser(null, id, notification, 72450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle.ALL); 725d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mUsbNotificationId = id; 726d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 727d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 728d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 729d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 730d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private void updateAdbNotification() { 731d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mNotificationManager == null) return; 732fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood final int id = com.android.internal.R.string.adb_active_notification_title; 733d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mAdbEnabled && mConnected) { 734d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if ("0".equals(SystemProperties.get("persist.adb.notify"))) return; 735d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 736d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (!mAdbNotificationShown) { 737d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Resources r = mContext.getResources(); 738fadd2b8e0ffea0d5b4bf3ca16af4d5cea001b561Mike Lockwood CharSequence title = r.getText(id); 739d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood CharSequence message = r.getText( 740d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.adb_active_notification_message); 741d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 742d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Notification notification = new Notification(); 743d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.icon = com.android.internal.R.drawable.stat_sys_adb; 744d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.when = 0; 745d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.flags = Notification.FLAG_ONGOING_EVENT; 746d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.tickerText = title; 747d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.defaults = 0; // please be quiet 748d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.sound = null; 749d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.vibrate = null; 750a25079e6bafcfd77135a852f0e838738d80606efDaniel Sandler notification.priority = Notification.PRIORITY_LOW; 751d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 752765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate Intent intent = Intent.makeRestartActivityTask( 753765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate new ComponentName("com.android.settings", 754765f97d5e608031bc1de4156c6e681e4d178c7eeChristopher Tate "com.android.settings.DevelopmentSettings")); 75550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, 75650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn intent, 0, null, UserHandle.CURRENT); 757d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.setLatestEventInfo(mContext, title, message, pi); 758d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mAdbNotificationShown = true; 75950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.notifyAsUser(null, id, notification, 76050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle.ALL); 761d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 762d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (mAdbNotificationShown) { 763d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mAdbNotificationShown = false; 76450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.cancelAsUser(null, id, UserHandle.ALL); 765d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 766d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 767d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 76802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void dump(FileDescriptor fd, PrintWriter pw) { 76902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" USB Device State:"); 77002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" Current Functions: " + mCurrentFunctions); 77102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" Default Functions: " + mDefaultFunctions); 77202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mConnected: " + mConnected); 77302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mConfigured: " + mConfigured); 77402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mCurrentAccessory: " + mCurrentAccessory); 7756ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood try { 7766ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Kernel state: " 7776ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); 7786ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Kernel function list: " 7796ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); 7806ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Mass storage backing file: " 7816ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(MASS_STORAGE_FILE_PATH), 0, null).trim()); 7826ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood } catch (IOException e) { 7836ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println("IOException: " + e); 7846ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood } 78502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 78646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 78746d0adf8256a42416584765625852b6e48497c90Mike Lockwood 78802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood /* returns the currently attached USB accessory */ 78946d0adf8256a42416584765625852b6e48497c90Mike Lockwood public UsbAccessory getCurrentAccessory() { 79002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return mHandler.getCurrentAccessory(); 79146d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 79246d0adf8256a42416584765625852b6e48497c90Mike Lockwood 79302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood /* opens the currently attached USB accessory */ 794abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { 795abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); 796abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood if (currentAccessory == null) { 797abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood throw new IllegalArgumentException("no accessory attached"); 79846d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 799abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood if (!currentAccessory.equals(accessory)) { 800abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood String error = accessory.toString() 801abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood + " does not match current accessory " 802abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood + currentAccessory; 803abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood throw new IllegalArgumentException(error); 804abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood } 805fc3f24b4b60c10e0d3f41f70df37e11ea311cc2cJeff Sharkey getCurrentSettings().checkPermission(accessory); 806abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood return nativeOpenAccessory(); 807abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood } 80802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 809166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood public void setCurrentFunctions(String functions, boolean makeDefault) { 810166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ") default: " + makeDefault); 811166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, makeDefault); 81202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 81346d0adf8256a42416584765625852b6e48497c90Mike Lockwood 81402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void setMassStorageBackingFile(String path) { 81502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (path == null) path = ""; 81602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood try { 81702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood FileUtils.stringToFile(MASS_STORAGE_FILE_PATH, path); 81802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } catch (IOException e) { 81902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "failed to write to " + MASS_STORAGE_FILE_PATH); 82046d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 82102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 82246d0adf8256a42416584765625852b6e48497c90Mike Lockwood 823afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private void readOemUsbOverrideConfig() { 824afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo String[] configList = mContext.getResources().getStringArray( 825afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo com.android.internal.R.array.config_oemUsbModeOverride); 826afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 827afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (configList != null) { 828afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo for (String config: configList) { 829afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo String[] items = config.split(":"); 830afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (items.length == 3) { 831afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (mOemModeMap == null) { 832afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo mOemModeMap = new HashMap<String, List<Pair<String, String>>>(); 833afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 834afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo List overrideList = mOemModeMap.get(items[0]); 835afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (overrideList == null) { 836afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo overrideList = new LinkedList<Pair<String, String>>(); 837afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo mOemModeMap.put(items[0], overrideList); 838afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 839afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo overrideList.add(new Pair<String, String>(items[1], items[2])); 840afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 841afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 842afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 843afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 844afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 845afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private boolean needsOemUsbOverride() { 846afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (mOemModeMap == null) return false; 847afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 848afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 849afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo return (mOemModeMap.get(bootMode) != null) ? true : false; 850afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 851afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 852afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo private String processOemUsbOverride(String usbFunctions) { 853afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if ((usbFunctions == null) || (mOemModeMap == null)) return usbFunctions; 854afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 855afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); 856afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 857afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo List<Pair<String, String>> overrides = mOemModeMap.get(bootMode); 858afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (overrides != null) { 859afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo for (Pair<String, String> pair: overrides) { 860afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo if (pair.first.equals(usbFunctions)) { 861afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo Slog.d(TAG, "OEM USB override: " + pair.first + " ==> " + pair.second); 862afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo return pair.second; 863afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 864afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 865afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 866afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo // return passed in functions as is. 867afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo return usbFunctions; 868afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo } 869afd8f1820eeee21e960be44b22113dc2cecacf98Kazuhiro Ondo 8704e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { 8714e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 8724e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey); 8734e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 8744e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 8754e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 8764e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public void denyUsbDebugging() { 8774e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 8784e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.denyUsbDebugging(); 8794e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 8804e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 8814e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 882cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby public void clearUsbDebuggingKeys() { 883cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby if (mDebuggingManager != null) { 884cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby mDebuggingManager.clearUsbDebuggingKeys(); 885cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby } else { 886cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby throw new RuntimeException("Cannot clear Usb Debugging keys, " 887cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby + "UsbDebuggingManager not enabled"); 888cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby } 889cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby } 890cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby 89146d0adf8256a42416584765625852b6e48497c90Mike Lockwood public void dump(FileDescriptor fd, PrintWriter pw) { 89202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mHandler != null) { 89302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.dump(fd, pw); 89446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 8954e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mDebuggingManager != null) { 8964e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mDebuggingManager.dump(fd, pw); 8974e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 89846d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 89946d0adf8256a42416584765625852b6e48497c90Mike Lockwood 90046d0adf8256a42416584765625852b6e48497c90Mike Lockwood private native String[] nativeGetAccessoryStrings(); 90146d0adf8256a42416584765625852b6e48497c90Mike Lockwood private native ParcelFileDescriptor nativeOpenAccessory(); 902d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private native boolean nativeIsStartRequested(); 903166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood private native int nativeGetAudioMode(); 90446d0adf8256a42416584765625852b6e48497c90Mike Lockwood} 905