UsbDeviceManager.java revision 68736cbf938935f7d7e1eb2b3f9ec911fcb0da72
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 1946d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.app.PendingIntent; 20541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.app.Notification; 21541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.app.NotificationManager; 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; 3346d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.net.Uri; 3446d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Binder; 3546d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Bundle; 3602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.FileUtils; 3746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Handler; 3802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.HandlerThread; 3902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.Looper; 4046d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Message; 4146d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.Parcelable; 4246d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.ParcelFileDescriptor; 4302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.Process; 4402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.storage.StorageManager; 4502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwoodimport android.os.storage.StorageVolume; 46541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwoodimport android.os.SystemProperties; 4746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.os.UEventObserver; 4846d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.provider.Settings; 4946d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport android.util.Slog; 5046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 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; 5646d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.util.ArrayList; 5746d0adf8256a42416584765625852b6e48497c90Mike Lockwoodimport java.util.List; 5846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 5946d0adf8256a42416584765625852b6e48497c90Mike Lockwood/** 6046d0adf8256a42416584765625852b6e48497c90Mike Lockwood * UsbDeviceManager manages USB state in device mode. 6146d0adf8256a42416584765625852b6e48497c90Mike Lockwood */ 6246d0adf8256a42416584765625852b6e48497c90Mike Lockwoodpublic class UsbDeviceManager { 6302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 6446d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final String TAG = UsbDeviceManager.class.getSimpleName(); 65fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood private static final boolean DEBUG = false; 6646d0adf8256a42416584765625852b6e48497c90Mike Lockwood 6702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String USB_STATE_MATCH = 6802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "DEVPATH=/devices/virtual/android_usb/android0"; 6902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String ACCESSORY_START_MATCH = 7002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "DEVPATH=/devices/virtual/misc/usb_accessory"; 7102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String FUNCTIONS_PATH = 7202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "/sys/class/android_usb/android0/functions"; 7302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String STATE_PATH = 7402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood "/sys/class/android_usb/android0/state"; 7502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final String MASS_STORAGE_FILE_PATH = 76629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood "/sys/class/android_usb/android0/f_mass_storage/lun/file"; 77629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood private static final String RNDIS_ETH_ADDR_PATH = 78629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood "/sys/class/android_usb/android0/f_rndis/ethaddr"; 7946d0adf8256a42416584765625852b6e48497c90Mike Lockwood 8046d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final int MSG_UPDATE_STATE = 0; 8102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static final int MSG_ENABLE_ADB = 1; 82f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private static final int MSG_SET_CURRENT_FUNCTION = 2; 83f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private static final int MSG_SYSTEM_READY = 3; 84d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private static final int MSG_BOOT_COMPLETED = 4; 8546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 8646d0adf8256a42416584765625852b6e48497c90Mike Lockwood // Delay for debouncing USB disconnects. 8746d0adf8256a42416584765625852b6e48497c90Mike Lockwood // We often get rapid connect/disconnect events when enabling USB functions, 8846d0adf8256a42416584765625852b6e48497c90Mike Lockwood // which need debouncing. 8946d0adf8256a42416584765625852b6e48497c90Mike Lockwood private static final int UPDATE_DELAY = 1000; 9046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 9102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private UsbHandler mHandler; 92d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private boolean mBootCompleted; 9346d0adf8256a42416584765625852b6e48497c90Mike Lockwood 9446d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final Context mContext; 9502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private final ContentResolver mContentResolver; 9646d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final UsbSettingsManager mSettingsManager; 97541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private NotificationManager mNotificationManager; 9846d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final boolean mHasUsbAccessory; 995787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood private boolean mUseUsbNotification; 100541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private boolean mAdbEnabled; 101541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 102541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood private class AdbSettingsObserver extends ContentObserver { 103541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood public AdbSettingsObserver() { 104541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood super(null); 105541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 106541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood @Override 107541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood public void onChange(boolean selfChange) { 10802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood boolean enable = (Settings.Secure.getInt(mContentResolver, 10902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Settings.Secure.ADB_ENABLED, 0) > 0); 11002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.sendMessage(MSG_ENABLE_ADB, enable); 111541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 112541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood } 113541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 11446d0adf8256a42416584765625852b6e48497c90Mike Lockwood /* 11546d0adf8256a42416584765625852b6e48497c90Mike Lockwood * Listens for uevent messages from the kernel to monitor the USB state 11646d0adf8256a42416584765625852b6e48497c90Mike Lockwood */ 11746d0adf8256a42416584765625852b6e48497c90Mike Lockwood private final UEventObserver mUEventObserver = new UEventObserver() { 11846d0adf8256a42416584765625852b6e48497c90Mike Lockwood @Override 11946d0adf8256a42416584765625852b6e48497c90Mike Lockwood public void onUEvent(UEventObserver.UEvent event) { 120fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString()); 12146d0adf8256a42416584765625852b6e48497c90Mike Lockwood 12202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String state = event.get("USB_STATE"); 12302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String accessory = event.get("ACCESSORY"); 12402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (state != null) { 12502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.updateState(state); 12602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("START".equals(accessory)) { 127fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.d(TAG, "got accessory start"); 128f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood setCurrentFunction(UsbManager.USB_FUNCTION_ACCESSORY, false); 12946d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 13046d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 13146d0adf8256a42416584765625852b6e48497c90Mike Lockwood }; 13246d0adf8256a42416584765625852b6e48497c90Mike Lockwood 13346d0adf8256a42416584765625852b6e48497c90Mike Lockwood public UsbDeviceManager(Context context, UsbSettingsManager settingsManager) { 13446d0adf8256a42416584765625852b6e48497c90Mike Lockwood mContext = context; 135541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood mContentResolver = context.getContentResolver(); 13646d0adf8256a42416584765625852b6e48497c90Mike Lockwood mSettingsManager = settingsManager; 13746d0adf8256a42416584765625852b6e48497c90Mike Lockwood PackageManager pm = mContext.getPackageManager(); 13846d0adf8256a42416584765625852b6e48497c90Mike Lockwood mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); 139629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood initRndisAddress(); 14046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 14102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // create a thread for our Handler 14202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood HandlerThread thread = new HandlerThread("UsbDeviceManager", 1433fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood Process.THREAD_PRIORITY_BACKGROUND); 14402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood thread.start(); 1453fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood mHandler = new UsbHandler(thread.getLooper()); 146d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 147d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (nativeIsStartRequested()) { 148d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "accessory attached at boot"); 149d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood setCurrentFunction(UsbManager.USB_FUNCTION_ACCESSORY, false); 150d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } 15102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 15202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 15302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void systemReady() { 154d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "systemReady"); 15502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 15602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mNotificationManager = (NotificationManager) 15702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mContext.getSystemService(Context.NOTIFICATION_SERVICE); 15846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 1595787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood // We do not show the USB notification if the primary volume supports mass storage. 1605787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood // The legacy mass storage UI will be used instead. 1615787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood boolean massStorageSupported = false; 1625787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood StorageManager storageManager = (StorageManager) 1635787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood mContext.getSystemService(Context.STORAGE_SERVICE); 1645787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood StorageVolume[] volumes = storageManager.getVolumeList(); 1655787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood if (volumes.length > 0) { 1665787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood massStorageSupported = volumes[0].allowMassStorage(); 1675787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood } 1685787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood mUseUsbNotification = !massStorageSupported; 1695787a2d5b4e5bd60087eb7fbb13c97c7d0ba113eMike Lockwood 17002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // make sure the ADB_ENABLED setting value matches the current state 17102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Settings.Secure.putInt(mContentResolver, Settings.Secure.ADB_ENABLED, mAdbEnabled ? 1 : 0); 172541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 17302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.sendEmptyMessage(MSG_SYSTEM_READY); 17402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 175541c9949ae9c05636d3e0442aa5080815121a042Mike Lockwood 176629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood private static void initRndisAddress() { 177629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // configure RNDIS ethernet address based on our serial number using the same algorithm 178629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // we had been previously using in kernel board files 179629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood final int ETH_ALEN = 6; 180629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood int address[] = new int[ETH_ALEN]; 181629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // first byte is 0x02 to signify a locally administered address 182629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[0] = 0x02; 183629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood 184629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF"); 185629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood int serialLength = serial.length(); 186629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood // XOR the USB serial across the remaining 5 bytes 187629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood for (int i = 0; i < serialLength; i++) { 188629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[i % (ETH_ALEN - 1) + 1] ^= (int)serial.charAt(i); 189629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 190629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood String addrString = String.format("%02X:%02X:%02X:%02X:%02X:%02X", 191629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood address[0], address[1], address[2], address[3], address[4], address[5]); 192629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood try { 193629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString); 194629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } catch (IOException e) { 195629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood Slog.e(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH); 196629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 197629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood } 198629b149ff584bc247f68014a676101d1d5787d27Mike Lockwood 19902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static String addFunction(String functions, String function) { 20002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (!containsFunction(functions, function)) { 20102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (functions.length() > 0) { 20202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood functions += ","; 20346d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 20402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood functions += function; 20546d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 20602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return functions; 20746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 20846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 20902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static String removeFunction(String functions, String function) { 21002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String[] split = functions.split(","); 21102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < split.length; i++) { 21202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (function.equals(split[i])) { 21302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood split[i] = null; 21402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 21502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 21602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood StringBuilder builder = new StringBuilder(); 21702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < split.length; i++) { 21802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String s = split[i]; 21902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (s != null) { 22002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (builder.length() > 0) { 22102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood builder.append(","); 22202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 22302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood builder.append(s); 22402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 22502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 22602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return builder.toString(); 22702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 22846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 22902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private static boolean containsFunction(String functions, String function) { 23002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int index = functions.indexOf(function); 23102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (index < 0) return false; 23202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (index > 0 && functions.charAt(index - 1) != ',') return false; 23302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int charAfter = index + function.length(); 23402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false; 23502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return true; 23602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 23702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 23802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private final class UsbHandler extends Handler { 23902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 24002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // current USB state 24102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private boolean mConnected; 24202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private boolean mConfigured; 24302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private String mCurrentFunctions; 24402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private String mDefaultFunctions; 24502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private UsbAccessory mCurrentAccessory; 246d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private int mUsbNotificationId; 247d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private boolean mAdbNotificationShown; 248d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 249d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() { 250d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood public void onReceive(Context context, Intent intent) { 251d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (DEBUG) Slog.d(TAG, "boot completed"); 252d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); 253d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } 254d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood }; 255d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 256d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private static final int NOTIFICATION_NONE = 0; 257d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private static final int NOTIFICATION_MTP = 1; 258d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private static final int NOTIFICATION_PTP = 2; 259d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private static final int NOTIFICATION_INSTALLER = 3; 2606e680dea3bc9e2d4ba1a09f428c303cd2a59c051Mike Lockwood private static final int NOTIFICATION_ACCESSORY = 4; 2616e680dea3bc9e2d4ba1a09f428c303cd2a59c051Mike Lockwood private static final int NOTIFICATION_ADB = 5; 26202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 2633fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood public UsbHandler(Looper looper) { 2643fd13eb6322e09f1ffe5476e28d55732da391151Mike Lockwood super(looper); 26502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood try { 266c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood // persist.sys.usb.config should never be unset. But if it is, set it to "adb" 267c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood // so we have a chance of debugging what happened. 268c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb"); 269de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood // sanity check the sys.usb.config system property 270de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood // this may be necessary if we crashed while switching USB configurations 271de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood String config = SystemProperties.get("sys.usb.config", "none"); 272c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood if (!config.equals(mDefaultFunctions)) { 273c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions); 274c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood SystemProperties.set("sys.usb.config", mDefaultFunctions); 275de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood } 276de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood 277c264afeb5528733a215a472e761b51cc59bba454Mike Lockwood mCurrentFunctions = mDefaultFunctions; 27802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); 27902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateState(state); 28002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB); 28102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 28202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // Upgrade step for previous versions that used persist.service.adb.enable 28302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String value = SystemProperties.get("persist.service.adb.enable", ""); 28402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (value.length() > 0) { 28502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood char enable = value.charAt(0); 28602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (enable == '1') { 28702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(true); 28802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if (enable == '0') { 28902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(false); 29002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 29102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood SystemProperties.set("persist.service.adb.enable", ""); 29202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 29302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 29402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // register observer to listen for settings changes 29502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mContentResolver.registerContentObserver( 29602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Settings.Secure.getUriFor(Settings.Secure.ADB_ENABLED), 29702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood false, new AdbSettingsObserver()); 29802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 29902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // Watch for USB configuration changes 30002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mUEventObserver.startObserving(USB_STATE_MATCH); 30102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mUEventObserver.startObserving(ACCESSORY_START_MATCH); 302d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood 303d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood mContext.registerReceiver(mBootCompletedReceiver, 304d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); 30502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } catch (Exception e) { 30602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "Error initializing UsbHandler", e); 30702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 30846d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 30902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 31002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void sendMessage(int what, boolean arg) { 31102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(what); 31202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message m = Message.obtain(this, what); 31302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood m.arg1 = (arg ? 1 : 0); 31402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessage(m); 31546d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 31646d0adf8256a42416584765625852b6e48497c90Mike Lockwood 31702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void sendMessage(int what, Object arg) { 31802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(what); 31902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message m = Message.obtain(this, what); 32002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood m.obj = arg; 32102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessage(m); 32202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 32302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 324f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood public void sendMessage(int what, Object arg0, boolean arg1) { 325f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood removeMessages(what); 326f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood Message m = Message.obtain(this, what); 327f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood m.obj = arg0; 328f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood m.arg1 = (arg1 ? 1 : 0); 329f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood sendMessage(m); 330f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood } 331f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood 33202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void updateState(String state) { 33302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood int connected, configured; 33402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 33502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if ("DISCONNECTED".equals(state)) { 33602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 0; 33702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 0; 33802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("CONNECTED".equals(state)) { 33902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 1; 34002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 0; 34102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if ("CONFIGURED".equals(state)) { 34202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood connected = 1; 34302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood configured = 1; 34402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else { 34502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "unknown state " + state); 34602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return; 34702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 34802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood removeMessages(MSG_UPDATE_STATE); 34902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Message msg = Message.obtain(this, MSG_UPDATE_STATE); 35002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood msg.arg1 = connected; 35102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood msg.arg2 = configured; 35202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // debounce disconnects to avoid problems bringing up USB tethering 35302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0); 35402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 35502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 356f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private boolean waitForState(String state) { 35702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // wait for the transition to complete. 35802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // give up after 1 second. 35902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < 20; i++) { 36068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // State transition is done when sys.usb.state is set to the new configuration 361f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood if (state.equals(SystemProperties.get("sys.usb.state"))) return true; 36202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood try { 36302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // try again in 50ms 36402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Thread.sleep(50); 36502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } catch (InterruptedException e) { 36602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 36702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 368fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.e(TAG, "waitForState(" + state + ") FAILED"); 36902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return false; 37002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 37102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 372f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood private boolean setUsbConfig(String config) { 373fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); 374f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // set the new configuration 375f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood SystemProperties.set("sys.usb.config", config); 376f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood return waitForState(config); 377f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood } 378f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood 37902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void setAdbEnabled(boolean enable) { 380de296f64483713fdf164f3e8bf41dc12d1cff59eMike Lockwood if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); 38102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (enable != mAdbEnabled) { 38202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mAdbEnabled = enable; 383f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // Due to the persist.sys.usb.config property trigger, changing adb state requires 384f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood // switching to default function 38568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setEnabledFunctions(mDefaultFunctions, false); 386d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 38702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 38802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 38902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 39068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood private void setEnabledFunctions(String functions, boolean makeDefault) { 39102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mAdbEnabled) { 39268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); 39302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else { 39468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); 39568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 39668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood 39768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (functions != null && makeDefault) { 39868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!mDefaultFunctions.equals(functions)) { 39968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!setUsbConfig("none")) { 40068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to disable USB"); 40168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 40268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 40368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood return; 40468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 40568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // setting this property will also change the current USB state 40668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // via a property trigger 40768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood SystemProperties.set("persist.sys.usb.config", functions); 40868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (waitForState(functions)) { 40968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mCurrentFunctions = functions; 41068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mDefaultFunctions = functions; 41168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 41268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to switch persistent USB config to " + functions); 41368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 41468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood SystemProperties.set("persist.sys.usb.config", mDefaultFunctions); 41568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 41668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 41768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 41868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (functions == null) { 41968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood functions = mDefaultFunctions; 42068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 42168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!mCurrentFunctions.equals(functions)) { 42268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (!setUsbConfig("none")) { 42368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to disable USB"); 42468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 42568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 42668736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood return; 42768736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 42868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood if (setUsbConfig(functions)) { 42968736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood mCurrentFunctions = functions; 43068736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } else { 43168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood Slog.e(TAG, "Failed to switch USB config to " + functions); 43268736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood // revert to previous configuration if we fail 43368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setUsbConfig(mCurrentFunctions); 43468736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 43568736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood } 43602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 43702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 43802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 43902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void updateCurrentAccessory() { 44002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (!mHasUsbAccessory) return; 44102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 44202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mConfigured) { 44302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String[] strings = nativeGetAccessoryStrings(); 44402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (strings != null) { 44502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mCurrentAccessory = new UsbAccessory(strings); 446fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory); 44702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // defer accessoryAttached if system is not ready 448d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 44902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mSettingsManager.accessoryAttached(mCurrentAccessory); 450d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood } // else handle in mBootCompletedReceiver 45102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else { 452fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.e(TAG, "nativeGetAccessoryStrings failed"); 45302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 45402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } else if (!mConnected) { 45502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // make sure accessory mode is off 45602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // and restore default functions 457fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood Slog.d(TAG, "exited USB accessory mode"); 45868736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setEnabledFunctions(mDefaultFunctions, false); 45902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 46002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mCurrentAccessory != null) { 461d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 46202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mSettingsManager.accessoryDetached(mCurrentAccessory); 46302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 46402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mCurrentAccessory = null; 46546d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 46646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 46746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 46846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 46902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood private void updateUsbState() { 47002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // send a sticky broadcast containing current USB state 47102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 47202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 47302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(UsbManager.USB_CONNECTED, mConnected); 47402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); 47502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 47602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mCurrentFunctions != null) { 47702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood String[] functions = mCurrentFunctions.split(","); 47802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood for (int i = 0; i < functions.length; i++) { 47902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood intent.putExtra(functions[i], true); 48002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 48146d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 48202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 48302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mContext.sendStickyBroadcast(intent); 48446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 48546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 48602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood @Override 48702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void handleMessage(Message msg) { 48802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood switch (msg.what) { 48902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_UPDATE_STATE: 49002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mConnected = (msg.arg1 == 1); 49102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mConfigured = (msg.arg2 == 1); 492d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateUsbNotification(); 493d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 49402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (containsFunction(mCurrentFunctions, 49502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood UsbManager.USB_FUNCTION_ACCESSORY)) { 49602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateCurrentAccessory(); 49702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 49802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 49902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (!mConnected) { 50002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood // restore defaults when USB is disconnected 50168736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setEnabledFunctions(mDefaultFunctions, false); 50202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 503d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mBootCompleted) { 50402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateUsbState(); 50502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 50602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 50702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_ENABLE_ADB: 50802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood setAdbEnabled(msg.arg1 == 1); 50902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 510f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood case MSG_SET_CURRENT_FUNCTION: 511f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood String function = (String)msg.obj; 512f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood boolean makeDefault = (msg.arg1 == 1); 51368736cbf938935f7d7e1eb2b3f9ec911fcb0da72Mike Lockwood setEnabledFunctions(function, makeDefault); 51402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 51502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood case MSG_SYSTEM_READY: 516d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateUsbNotification(); 517d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood updateAdbNotification(); 51802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood updateUsbState(); 519d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood break; 520d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood case MSG_BOOT_COMPLETED: 521d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood mBootCompleted = true; 522d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood if (mCurrentAccessory != null) { 52302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mSettingsManager.accessoryAttached(mCurrentAccessory); 52402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 52502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood break; 52646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 52746d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 52846d0adf8256a42416584765625852b6e48497c90Mike Lockwood 52902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public UsbAccessory getCurrentAccessory() { 53002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return mCurrentAccessory; 53102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 53202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 533d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private void updateUsbNotification() { 534d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mNotificationManager == null || !mUseUsbNotification) return; 535a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood int id = NOTIFICATION_NONE; 536a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood Resources r = mContext.getResources(); 537a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood CharSequence title = null; 538d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mConnected) { 539d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) { 540d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood title = r.getText( 541d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.usb_mtp_notification_title); 542d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood id = NOTIFICATION_MTP; 543d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP)) { 544d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood title = r.getText( 545d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.usb_ptp_notification_title); 546d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood id = NOTIFICATION_PTP; 547d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (containsFunction(mCurrentFunctions, 548d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood UsbManager.USB_FUNCTION_MASS_STORAGE)) { 549d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood title = r.getText( 550d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.usb_cd_installer_notification_title); 551d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood id = NOTIFICATION_INSTALLER; 5526e680dea3bc9e2d4ba1a09f428c303cd2a59c051Mike Lockwood } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) { 5536e680dea3bc9e2d4ba1a09f428c303cd2a59c051Mike Lockwood title = r.getText( 5546e680dea3bc9e2d4ba1a09f428c303cd2a59c051Mike Lockwood com.android.internal.R.string.usb_accessory_notification_title); 5556e680dea3bc9e2d4ba1a09f428c303cd2a59c051Mike Lockwood id = NOTIFICATION_ACCESSORY; 556d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else { 557a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood // There is a different notification for USB tethering so we don't need one here 558a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood if (!containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_RNDIS)) { 559a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood Slog.e(TAG, "No known USB function in updateUsbNotification"); 560d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 561d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 562a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood } 563a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood if (id != mUsbNotificationId) { 564a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood // clear notification if title needs changing 565a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood if (mUsbNotificationId != NOTIFICATION_NONE) { 566a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood mNotificationManager.cancel(mUsbNotificationId); 567a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood mUsbNotificationId = NOTIFICATION_NONE; 568a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood } 569a5010431bfcdff88ac9d96e68d8308071c13472bMike Lockwood if (id != NOTIFICATION_NONE) { 570d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood CharSequence message = r.getText( 571d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.usb_notification_message); 572d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 573d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Notification notification = new Notification(); 574d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.icon = com.android.internal.R.drawable.stat_sys_data_usb; 575d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.when = 0; 576d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.flags = Notification.FLAG_ONGOING_EVENT; 577d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.tickerText = title; 578d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.defaults = 0; // please be quiet 579d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.sound = null; 580d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.vibrate = null; 581d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 582c50bff85281fa9661310465e88fd62890ccc9240Mike Lockwood Intent intent = new Intent( 583c50bff85281fa9661310465e88fd62890ccc9240Mike Lockwood Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS); 584d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 585d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 586c50bff85281fa9661310465e88fd62890ccc9240Mike Lockwood intent.setComponent(new ComponentName("com.android.settings", 587c50bff85281fa9661310465e88fd62890ccc9240Mike Lockwood "com.android.settings.UsbSettings")); 588d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood PendingIntent pi = PendingIntent.getActivity(mContext, 0, 589d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood intent, 0); 590d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.setLatestEventInfo(mContext, title, message, pi); 591d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mNotificationManager.notify(id, notification); 592d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mUsbNotificationId = id; 593d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 594d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 595d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 596d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 597d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood private void updateAdbNotification() { 598d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mNotificationManager == null) return; 599d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (mAdbEnabled && mConnected) { 600d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if ("0".equals(SystemProperties.get("persist.adb.notify"))) return; 601d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 602d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood if (!mAdbNotificationShown) { 603d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Resources r = mContext.getResources(); 604d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood CharSequence title = r.getText( 605d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.adb_active_notification_title); 606d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood CharSequence message = r.getText( 607d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood com.android.internal.R.string.adb_active_notification_message); 608d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 609d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Notification notification = new Notification(); 610d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.icon = com.android.internal.R.drawable.stat_sys_adb; 611d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.when = 0; 612d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.flags = Notification.FLAG_ONGOING_EVENT; 613d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.tickerText = title; 614d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.defaults = 0; // please be quiet 615d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.sound = null; 616d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.vibrate = null; 617d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 618d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Intent intent = new Intent( 619d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS); 620d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 621d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 622d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood intent.setComponent(new ComponentName("com.android.settings", 623d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood "com.android.settings.DevelopmentSettings")); 624d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood PendingIntent pi = PendingIntent.getActivity(mContext, 0, 625d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood intent, 0); 626d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood notification.setLatestEventInfo(mContext, title, message, pi); 627d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mAdbNotificationShown = true; 628d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mNotificationManager.notify(NOTIFICATION_ADB, notification); 629d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 630d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } else if (mAdbNotificationShown) { 631d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mAdbNotificationShown = false; 632d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood mNotificationManager.cancel(NOTIFICATION_ADB); 633d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 634d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood } 635d8404d2fdd7036435748548a6791063fb6d6c909Mike Lockwood 63602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void dump(FileDescriptor fd, PrintWriter pw) { 63702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" USB Device State:"); 63802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" Current Functions: " + mCurrentFunctions); 63902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" Default Functions: " + mDefaultFunctions); 64002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mConnected: " + mConnected); 64102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mConfigured: " + mConfigured); 64202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood pw.println(" mCurrentAccessory: " + mCurrentAccessory); 6436ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood try { 6446ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Kernel state: " 6456ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); 6466ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Kernel function list: " 6476ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); 6486ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println(" Mass storage backing file: " 6496ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood + FileUtils.readTextFile(new File(MASS_STORAGE_FILE_PATH), 0, null).trim()); 6506ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood } catch (IOException e) { 6516ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood pw.println("IOException: " + e); 6526ea146c239f2468563b4e8766b446d14ae4a1ff5Mike Lockwood } 65302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 65446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 65546d0adf8256a42416584765625852b6e48497c90Mike Lockwood 65602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood /* returns the currently attached USB accessory */ 65746d0adf8256a42416584765625852b6e48497c90Mike Lockwood public UsbAccessory getCurrentAccessory() { 65802e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood return mHandler.getCurrentAccessory(); 65946d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 66046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 66102e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood /* opens the currently attached USB accessory */ 662abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { 663abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood UsbAccessory currentAccessory = mHandler.getCurrentAccessory(); 664abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood if (currentAccessory == null) { 665abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood throw new IllegalArgumentException("no accessory attached"); 66646d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 667abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood if (!currentAccessory.equals(accessory)) { 668abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood String error = accessory.toString() 669abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood + " does not match current accessory " 670abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood + currentAccessory; 671abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood throw new IllegalArgumentException(error); 672abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood } 673abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood mSettingsManager.checkPermission(accessory); 674abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood return nativeOpenAccessory(); 675abc4ac6d48c52bd8b69026441bf261e5c68c24f4Mike Lockwood } 67602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood 677f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood public void setCurrentFunction(String function, boolean makeDefault) { 678fdc0c2984d05e32954608f46514c4cbe3a5a9424Mike Lockwood if (DEBUG) Slog.d(TAG, "setCurrentFunction(" + function + ") default: " + makeDefault); 679f59717ddb5ef324ee3fdb12b83e7d1b709793d28Mike Lockwood mHandler.sendMessage(MSG_SET_CURRENT_FUNCTION, function, makeDefault); 68002e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 68146d0adf8256a42416584765625852b6e48497c90Mike Lockwood 68202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood public void setMassStorageBackingFile(String path) { 68302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (path == null) path = ""; 68402e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood try { 68502e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood FileUtils.stringToFile(MASS_STORAGE_FILE_PATH, path); 68602e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } catch (IOException e) { 68702e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood Slog.e(TAG, "failed to write to " + MASS_STORAGE_FILE_PATH); 68846d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 68902e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood } 69046d0adf8256a42416584765625852b6e48497c90Mike Lockwood 69146d0adf8256a42416584765625852b6e48497c90Mike Lockwood public void dump(FileDescriptor fd, PrintWriter pw) { 69202e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood if (mHandler != null) { 69302e4569b5f126ca916a7473117ddd17d4f2ccbbbMike Lockwood mHandler.dump(fd, pw); 69446d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 69546d0adf8256a42416584765625852b6e48497c90Mike Lockwood } 69646d0adf8256a42416584765625852b6e48497c90Mike Lockwood 69746d0adf8256a42416584765625852b6e48497c90Mike Lockwood private native String[] nativeGetAccessoryStrings(); 69846d0adf8256a42416584765625852b6e48497c90Mike Lockwood private native ParcelFileDescriptor nativeOpenAccessory(); 699d462ecf8f82076d21c85bdeeefbd16a1a91d2805Mike Lockwood private native boolean nativeIsStartRequested(); 70046d0adf8256a42416584765625852b6e48497c90Mike Lockwood} 701