diff options
author | Nick Kralevich <nnk@google.com> | 2015-05-13 11:54:03 -0700 |
---|---|---|
committer | Nick Kralevich <nnk@google.com> | 2015-05-13 14:28:13 -0700 |
commit | fcf10f7c12cb3107bdfedce6f76a8c866d154f3c (patch) | |
tree | 54e502f36ee820d1fc74cc52e653b7547801df41 | |
parent | 2047ce824030a2ea6227a7544789281530b7892d (diff) | |
download | frameworks_base-fcf10f7c12cb3107bdfedce6f76a8c866d154f3c.zip frameworks_base-fcf10f7c12cb3107bdfedce6f76a8c866d154f3c.tar.gz frameworks_base-fcf10f7c12cb3107bdfedce6f76a8c866d154f3c.tar.bz2 |
Modify how USB connections are handled.
* Introduce a new "charger only" mode. In this mode, MTP is disabled,
and no file transfers can occur.
* Make charger only mode the default.
* Modify "persist.sys.usb.config" so it now only holds the adb status.
* Make the USB settings non-persistent. Unplugging the USB connection will
reset the device back to "charger only" mode.
* Fixup wording per UI guidelines.
TODO: Re-implement MDM restrictions for USB / MTP access controls.
Bug: 18905620
Change-Id: I99a50d9132a81e98187f431166fd9fef4d437e4f
9 files changed, 93 insertions, 152 deletions
diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java index 4dcb05e..a6ef25f 100644 --- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java +++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java @@ -50,7 +50,7 @@ public class UsbCommand extends Svc.Command { IUsbManager usbMgr = IUsbManager.Stub.asInterface(ServiceManager.getService( Context.USB_SERVICE)); try { - usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null), false); + usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null)); } catch (RemoteException e) { System.err.println("Error communicating with UsbManager: " + e); } diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl index e4ab3f2..881dc0f 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -83,7 +83,7 @@ interface IUsbManager void clearDefaults(String packageName, int userId); /* Sets the current USB function. */ - void setCurrentFunction(String function, boolean makeDefault); + void setCurrentFunction(String function); /* Allow USB debugging from the attached host. If alwaysAllow is true, add the * the public key to list of host keys that the user has approved. diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index a45d4ca..000d41f 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -228,6 +228,23 @@ public class UsbManager { */ public static final String EXTRA_PERMISSION_GRANTED = "permission"; + /** + * The persistent property which stores whether adb is enabled or not. Other values are ignored. + * Previously this value stored non-adb settings, but not anymore. + * TODO: rename this to something adb specific, rather than using usb. + * + * {@hide} + */ + public static final String ADB_PERSISTENT_PROPERTY = "persist.sys.usb.config"; + + /** + * The non-persistent property which stores the current USB settings. + * + * {@hide} + */ + public static final String USB_SETTINGS_PROPERTY = "sys.usb.config"; + + private final Context mContext; private final IUsbManager mService; @@ -410,21 +427,26 @@ public class UsbManager { } } + private static boolean propertyContainsFunction(String property, String function) { + String functions = SystemProperties.get(property, ""); + int index = functions.indexOf(function); + if (index < 0) return false; + if (index > 0 && functions.charAt(index - 1) != ',') return false; + int charAfter = index + function.length(); + if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false; + return true; + } + /** - * Returns the current default USB function. + * Returns true if the specified USB function is currently enabled. * - * @return name of the default function. + * @param function name of the USB function + * @return true if the USB function is enabled. * * {@hide} */ - public String getDefaultFunction() { - String functions = SystemProperties.get("persist.sys.usb.config", ""); - int commaIndex = functions.indexOf(','); - if (commaIndex > 0) { - return functions.substring(0, commaIndex); - } else { - return functions; - } + public boolean isFunctionEnabled(String function) { + return propertyContainsFunction(USB_SETTINGS_PROPERTY, function); } /** @@ -432,13 +454,12 @@ public class UsbManager { * If function is null, then the current function is set to the default function. * * @param function name of the USB function, or null to restore the default function - * @param makeDefault true if the function should be set as the new default function * * {@hide} */ - public void setCurrentFunction(String function, boolean makeDefault) { + public void setCurrentFunction(String function) { try { - mService.setCurrentFunction(function, makeDefault); + mService.setCurrentFunction(function); } catch (RemoteException e) { Log.e(TAG, "RemoteException in setCurrentFunction", e); } diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 5b564e1..39d7cac 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2916,18 +2916,20 @@ <!-- USB_STORAGE_ERROR dialog ok button--> <string name="dlg_ok">OK</string> + <!-- USB_PREFERENCES: Notification for when the user connected to the charger only. This is the title --> + <string name="usb_charging_notification_title">USB for charging</string> <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in MTP mode. This is the title --> - <string name="usb_mtp_notification_title">Connected as a media device</string> + <string name="usb_mtp_notification_title">USB for file transfer</string> <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in PTP mode. This is the title --> - <string name="usb_ptp_notification_title">Connected as a camera</string> + <string name="usb_ptp_notification_title">USB for photo transfer</string> <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in MIDI mode. This is the title --> - <string name="usb_midi_notification_title">Connected as a MIDI device</string> + <string name="usb_midi_notification_title">USB for MIDI</string> <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in mass storage mode (for installer CD image). This is the title --> <string name="usb_cd_installer_notification_title">Connected as an installer</string> <!-- USB_PREFERENCES: Notification for when a USB accessory is attached. This is the title --> <string name="usb_accessory_notification_title">Connected to a USB accessory</string> <!-- See USB_PREFERENCES. This is the message. --> - <string name="usb_notification_message">Touch for other USB options.</string> + <string name="usb_notification_message">Touch for more options.</string> <!-- External media format dialog strings --> <!-- This is the label for the activity, and should never be visible to the user. --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 8f949e1..0186c9d 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1790,6 +1790,7 @@ <java-symbol type="string" name="usb_accessory_notification_title" /> <java-symbol type="string" name="usb_cd_installer_notification_title" /> <java-symbol type="string" name="usb_mtp_notification_title" /> + <java-symbol type="string" name="usb_charging_notification_title" /> <java-symbol type="string" name="usb_notification_message" /> <java-symbol type="string" name="use_physical_keyboard" /> <java-symbol type="string" name="usb_ptp_notification_title" /> diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 4c08960..bb4ff1e 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -608,12 +608,12 @@ public class Tethering extends BaseNetworkObserver { tetherUsb(true); } else { mUsbTetherRequested = true; - usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false); + usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS); } } else { tetherUsb(false); if (mRndisEnabled) { - usbManager.setCurrentFunction(null, false); + usbManager.setCurrentFunction(null); } mUsbTetherRequested = false; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index ba5d666..aad8b57 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -5362,7 +5362,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if (UserManager.DISALLOW_USB_FILE_TRANSFER.equals(key)) { UsbManager manager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE); - manager.setCurrentFunction("none", false); + manager.setCurrentFunction("none"); } else if (UserManager.DISALLOW_SHARE_LOCATION.equals(key)) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF, diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index f84beb6..cb8f938 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -92,7 +92,6 @@ public class UsbDeviceManager { private static final int MSG_BOOT_COMPLETED = 4; private static final int MSG_USER_SWITCHED = 5; - private static final int AUDIO_MODE_NONE = 0; private static final int AUDIO_MODE_SOURCE = 1; // Delay for debouncing USB disconnects. @@ -107,8 +106,6 @@ public class UsbDeviceManager { // Request is cancelled if host does not configure device within 10 seconds. private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000; - private static final String BOOT_MODE_PROPERTY = "ro.bootmode"; - private UsbHandler mHandler; private boolean mBootCompleted; @@ -245,7 +242,7 @@ public class UsbDeviceManager { if (functions != null) { mAccessoryModeRequestTime = SystemClock.elapsedRealtime(); - setCurrentFunctions(functions, false); + setCurrentFunctions(functions); } } @@ -318,7 +315,6 @@ public class UsbDeviceManager { private boolean mConnected; private boolean mConfigured; private String mCurrentFunctions; - private String mDefaultFunctions; private UsbAccessory mCurrentAccessory; private int mUsbNotificationId; private boolean mAdbNotificationShown; @@ -343,25 +339,20 @@ public class UsbDeviceManager { public UsbHandler(Looper looper) { super(looper); try { + // Special note about persist.sys.usb.config: We only ever look at the adb value + // from that property. Other values are ignored. persist.sys.usb.config is now + // only used to determine if adb is enabled or not. + // TODO: rename persist.sys.usb.config to something more descriptive. // persist.sys.usb.config should never be unset. But if it is, set it to "adb" // so we have a chance of debugging what happened. - mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb"); - - // Check if USB mode needs to be overridden depending on OEM specific bootmode. - mDefaultFunctions = processOemUsbOverride(mDefaultFunctions); - // sanity check the sys.usb.config system property - // this may be necessary if we crashed while switching USB configurations - String config = SystemProperties.get("sys.usb.config", "none"); - if (!config.equals(mDefaultFunctions)) { - Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions); - SystemProperties.set("sys.usb.config", mDefaultFunctions); - } + mAdbEnabled = containsFunction( + SystemProperties.get(UsbManager.ADB_PERSISTENT_PROPERTY, "adb"), + UsbManager.USB_FUNCTION_ADB); - mCurrentFunctions = getDefaultFunctions(); + mCurrentFunctions = mAdbEnabled ? "adb" : "none"; String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); - mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB); // register observer to listen for settings changes mContentResolver.registerContentObserver( @@ -396,14 +387,6 @@ public class UsbDeviceManager { sendMessage(m); } - public void sendMessage(int what, Object arg0, boolean arg1) { - removeMessages(what); - Message m = Message.obtain(this, what); - m.obj = arg0; - m.arg1 = (arg1 ? 1 : 0); - sendMessage(m); - } - public void updateState(String state) { int connected, configured; @@ -443,7 +426,7 @@ public class UsbDeviceManager { private boolean setUsbConfig(String config) { if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); // set the new configuration - SystemProperties.set("sys.usb.config", config); + SystemProperties.set(UsbManager.USB_SETTINGS_PROPERTY, config); return waitForState(config); } @@ -453,9 +436,9 @@ public class UsbDeviceManager { mAdbEnabled = enable; // Due to the persist.sys.usb.config property trigger, changing adb state requires // persisting default function - setEnabledFunctions(mDefaultFunctions, true); + SystemProperties.set(UsbManager.ADB_PERSISTENT_PROPERTY, mAdbEnabled ? "adb" : "none"); // After persisting them use the lock-down aware function set - setEnabledFunctions(getDefaultFunctions(), false); + setEnabledFunctions(getDefaultFunctions()); updateAdbNotification(); } if (mDebuggingManager != null) { @@ -463,65 +446,31 @@ public class UsbDeviceManager { } } - private void setEnabledFunctions(String functions, boolean makeDefault) { - if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions - + " makeDefault: " + makeDefault); + private void setEnabledFunctions(String functions) { + if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions); - // Do not update persystent.sys.usb.config if the device is booted up - // with OEM specific mode. - if (functions != null && makeDefault && !needsOemUsbOverride()) { + if (functions == null) { + functions = "none"; + } - if (mAdbEnabled) { - functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); - } else { - functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); - } - if (!mDefaultFunctions.equals(functions)) { - if (!setUsbConfig("none")) { - Slog.e(TAG, "Failed to disable USB"); - // revert to previous configuration if we fail - setUsbConfig(mCurrentFunctions); - return; - } - // setting this property will also change the current USB state - // via a property trigger - SystemProperties.set("persist.sys.usb.config", functions); - if (waitForState(functions)) { - mCurrentFunctions = functions; - mDefaultFunctions = functions; - } else { - Slog.e(TAG, "Failed to switch persistent USB config to " + functions); - // revert to previous configuration if we fail - SystemProperties.set("persist.sys.usb.config", mDefaultFunctions); - } - } + if (mAdbEnabled) { + functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); } else { - if (functions == null) { - functions = mDefaultFunctions; + functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); + } + if (!mCurrentFunctions.equals(functions)) { + if (!setUsbConfig("none")) { + Slog.e(TAG, "Failed to disable USB"); + // revert to previous configuration if we fail + setUsbConfig(mCurrentFunctions); + return; } - - // Override with bootmode specific usb mode if needed - functions = processOemUsbOverride(functions); - - if (mAdbEnabled) { - functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); + if (setUsbConfig(functions)) { + mCurrentFunctions = functions; } else { - functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); - } - if (!mCurrentFunctions.equals(functions)) { - if (!setUsbConfig("none")) { - Slog.e(TAG, "Failed to disable USB"); - // revert to previous configuration if we fail - setUsbConfig(mCurrentFunctions); - return; - } - if (setUsbConfig(functions)) { - mCurrentFunctions = functions; - } else { - Slog.e(TAG, "Failed to switch USB config to " + functions); - // revert to previous configuration if we fail - setUsbConfig(mCurrentFunctions); - } + Slog.e(TAG, "Failed to switch USB config to " + functions); + // revert to previous configuration if we fail + setUsbConfig(mCurrentFunctions); } } } @@ -551,7 +500,7 @@ public class UsbDeviceManager { // make sure accessory mode is off // and restore default functions Slog.d(TAG, "exited USB accessory mode"); - setEnabledFunctions(getDefaultFunctions(), false); + setEnabledFunctions(getDefaultFunctions()); if (mCurrentAccessory != null) { if (mBootCompleted) { @@ -644,7 +593,7 @@ public class UsbDeviceManager { updateCurrentAccessory(); } else if (!mConnected) { // restore defaults when USB is disconnected - setEnabledFunctions(getDefaultFunctions(), false); + setEnabledFunctions(getDefaultFunctions()); } if (mBootCompleted) { updateUsbState(); @@ -657,10 +606,11 @@ public class UsbDeviceManager { break; case MSG_SET_CURRENT_FUNCTIONS: String functions = (String)msg.obj; - boolean makeDefault = (msg.arg1 == 1); - setEnabledFunctions(functions, makeDefault); + setEnabledFunctions(functions); break; case MSG_SYSTEM_READY: + setUsbConfig(mCurrentFunctions); + SystemProperties.set(UsbManager.ADB_PERSISTENT_PROPERTY, mAdbEnabled ? "adb" : "none"); updateUsbNotification(); updateAdbNotification(); updateUsbState(); @@ -669,6 +619,7 @@ public class UsbDeviceManager { break; case MSG_BOOT_COMPLETED: mBootCompleted = true; + setUsbConfig(mCurrentFunctions); if (mCurrentAccessory != null) { getCurrentSettings().accessoryAttached(mCurrentAccessory); } @@ -724,10 +675,7 @@ public class UsbDeviceManager { } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) { id = com.android.internal.R.string.usb_accessory_notification_title; } else { - // There is a different notification for USB tethering so we don't need one here - //if (!containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_RNDIS)) { - // Slog.e(TAG, "No known USB function in updateUsbNotification"); - //} + id = com.android.internal.R.string.usb_charging_notification_title; } } if (id != mUsbNotificationId) { @@ -754,7 +702,7 @@ public class UsbDeviceManager { Intent intent = Intent.makeRestartActivityTask( new ComponentName("com.android.settings", - "com.android.settings.UsbSettings")); + "com.android.settings.deviceinfo.UsbModeChooserActivity")); PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0, null, UserHandle.CURRENT); notification.color = mContext.getColor( @@ -810,18 +758,12 @@ public class UsbDeviceManager { } private String getDefaultFunctions() { - UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, - new UserHandle(mCurrentUser))) { - return "none"; - } - return mDefaultFunctions; + return "none"; } public void dump(FileDescriptor fd, PrintWriter pw) { pw.println(" USB Device State:"); pw.println(" Current Functions: " + mCurrentFunctions); - pw.println(" Default Functions: " + mDefaultFunctions); pw.println(" mConnected: " + mConnected); pw.println(" mConfigured: " + mConfigured); pw.println(" mCurrentAccessory: " + mCurrentAccessory); @@ -857,9 +799,9 @@ public class UsbDeviceManager { return nativeOpenAccessory(); } - public void setCurrentFunctions(String functions, boolean makeDefault) { - if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ") default: " + makeDefault); - mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, makeDefault); + public void setCurrentFunctions(String functions) { + if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ")"); + mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions); } private void readOemUsbOverrideConfig() { @@ -884,31 +826,6 @@ public class UsbDeviceManager { } } - private boolean needsOemUsbOverride() { - if (mOemModeMap == null) return false; - - String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); - return (mOemModeMap.get(bootMode) != null) ? true : false; - } - - private String processOemUsbOverride(String usbFunctions) { - if ((usbFunctions == null) || (mOemModeMap == null)) return usbFunctions; - - String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); - - List<Pair<String, String>> overrides = mOemModeMap.get(bootMode); - if (overrides != null) { - for (Pair<String, String> pair: overrides) { - if (pair.first.equals(usbFunctions)) { - Slog.d(TAG, "OEM USB override: " + pair.first + " ==> " + pair.second); - return pair.second; - } - } - } - // return passed in functions as is. - return usbFunctions; - } - public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { if (mDebuggingManager != null) { mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey); diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index e03884f..51281a2 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -252,19 +252,19 @@ public class UsbService extends IUsbManager.Stub { } @Override - public void setCurrentFunction(String function, boolean makeDefault) { + public void setCurrentFunction(String function) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); // If attempt to change USB function while file transfer is restricted, ensure that // the current function is set to "none", and return. UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) { - if (mDeviceManager != null) mDeviceManager.setCurrentFunctions("none", false); + if (mDeviceManager != null) mDeviceManager.setCurrentFunctions("none"); return; } if (mDeviceManager != null) { - mDeviceManager.setCurrentFunctions(function, makeDefault); + mDeviceManager.setCurrentFunctions(function); } else { throw new IllegalStateException("USB device mode not supported"); } |