diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java index a6ef25fc4479d..4dcb05e4f85da 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)); + usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null), false); } 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 6e4c9de1c8ef7..00b0bffdd1f53 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -87,15 +87,13 @@ interface IUsbManager /* Returns true if the specified USB function is enabled. */ boolean isFunctionEnabled(String function); - /* Sets the current USB function. */ - void setCurrentFunction(String function); - - /* Sets whether USB data (for example, MTP exposed pictures) should be made - * available on the USB connection. Unlocking data should only be done with - * user involvement, since exposing pictures or other data could leak sensitive - * user information. + /* Sets the current USB function as well as whether USB data + * (for example, MTP exposed pictures) should be made available + * on the USB connection. Unlocking data should only be done with + * user involvement, since exposing pictures or other data could + * leak sensitive user information. */ - void setUsbDataUnlocked(boolean unlock); + void setCurrentFunction(String function, boolean usbDataUnlocked); /* 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 cb2720ab98489..3df57bcb704f8 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -530,33 +530,23 @@ public class UsbManager { * {@link #USB_FUNCTION_MIDI}, {@link #USB_FUNCTION_MTP}, {@link #USB_FUNCTION_PTP}, * or {@link #USB_FUNCTION_RNDIS}. *

+ * Also sets whether USB data (for example, MTP exposed pictures) should be made available + * on the USB connection when in device mode. Unlocking usb data should only be done with + * user involvement, since exposing pictures or other data could leak sensitive + * user information. + *

* Note: This function is asynchronous and may fail silently without applying * the requested changes. *

* * @param function name of the USB function, or null to restore the default function + * @param usbDataUnlocked whether user data is accessible * * {@hide} */ - public void setCurrentFunction(String function) { + public void setCurrentFunction(String function, boolean usbDataUnlocked) { try { - mService.setCurrentFunction(function); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Sets whether USB data (for example, MTP exposed pictures) should be made available - * on the USB connection when in device mode. Unlocking usb data should only be done with - * user involvement, since exposing pictures or other data could leak sensitive - * user information. - * - * {@hide} - */ - public void setUsbDataUnlocked(boolean unlocked) { - try { - mService.setUsbDataUnlocked(unlocked); + mService.setCurrentFunction(function, usbDataUnlocked); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index da9c5474b66bf..921fd23db82ff 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -897,7 +897,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } } else { mUsbTetherRequested = true; - usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS); + usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false); } } else { final long ident = Binder.clearCallingIdentity(); @@ -907,7 +907,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering Binder.restoreCallingIdentity(ident); } if (mRndisEnabled) { - usbManager.setCurrentFunction(null); + usbManager.setCurrentFunction(null, false); } mUsbTetherRequested = false; } diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 8560651fa7ec5..15a1e760f5283 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -109,9 +109,8 @@ public class UsbDeviceManager { private static final int MSG_SYSTEM_READY = 3; private static final int MSG_BOOT_COMPLETED = 4; private static final int MSG_USER_SWITCHED = 5; - private static final int MSG_SET_USB_DATA_UNLOCKED = 6; - private static final int MSG_UPDATE_USER_RESTRICTIONS = 7; - private static final int MSG_UPDATE_HOST_STATE = 8; + private static final int MSG_UPDATE_USER_RESTRICTIONS = 6; + private static final int MSG_UPDATE_HOST_STATE = 7; private static final int AUDIO_MODE_SOURCE = 1; @@ -288,7 +287,7 @@ public class UsbDeviceManager { if (functions != null) { mAccessoryModeRequestTime = SystemClock.elapsedRealtime(); - setCurrentFunctions(functions); + setCurrentFunctions(functions, false); } } @@ -337,14 +336,22 @@ public class UsbDeviceManager { // Restore default functions. mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_NONE); - if (UsbManager.USB_FUNCTION_NONE.equals(mCurrentFunctions)) { - mCurrentFunctions = UsbManager.USB_FUNCTION_MTP; - } mCurrentFunctionsApplied = mCurrentFunctions.equals( SystemProperties.get(USB_STATE_PROPERTY)); mAdbEnabled = UsbManager.containsFunction(getDefaultFunctions(), UsbManager.USB_FUNCTION_ADB); - setEnabledFunctions(null, false); + + /** + * Remove MTP from persistent config, to bring usb to a good state + * after fixes to b/31814300. This block can be removed after the update + */ + String persisted = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY); + if (UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_MTP)) { + SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, + UsbManager.removeFunction(persisted, UsbManager.USB_FUNCTION_MTP)); + } + + setEnabledFunctions(null, false, false); String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); @@ -376,6 +383,14 @@ public class UsbDeviceManager { sendMessage(m); } + public void sendMessage(int what, Object arg, boolean arg1) { + removeMessages(what); + Message m = Message.obtain(this, what); + m.obj = arg; + m.arg1 = (arg1 ? 1 : 0); + sendMessage(m); + } + public void updateState(String state) { int connected, configured; @@ -440,29 +455,24 @@ public class UsbDeviceManager { return waitForState(config); } - private void setUsbDataUnlocked(boolean enable) { - if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked: " + enable); - mUsbDataUnlocked = enable; - updateUsbNotification(); - updateUsbStateBroadcastIfNeeded(); - setEnabledFunctions(mCurrentFunctions, true); - } - private void setAdbEnabled(boolean enable) { if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); if (enable != mAdbEnabled) { mAdbEnabled = enable; + String oldFunctions = mCurrentFunctions; - // Due to the persist.sys.usb.config property trigger, changing adb state requires - // persisting default function - String oldFunctions = getDefaultFunctions(); - String newFunctions = applyAdbFunction(oldFunctions); - if (!oldFunctions.equals(newFunctions)) { - SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunctions); + // Persist the adb setting + String newFunction = applyAdbFunction(SystemProperties.get( + USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_NONE)); + SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunction); + + // Remove mtp from the config if file transfer is not enabled + if (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) && + !mUsbDataUnlocked && enable) { + oldFunctions = UsbManager.USB_FUNCTION_NONE; } - // After persisting them use the lock-down aware function set - setEnabledFunctions(mCurrentFunctions, false); + setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked); updateAdbNotification(); } @@ -474,10 +484,17 @@ public class UsbDeviceManager { /** * Evaluates USB function policies and applies the change accordingly. */ - private void setEnabledFunctions(String functions, boolean forceRestart) { + private void setEnabledFunctions(String functions, boolean forceRestart, + boolean usbDataUnlocked) { if (DEBUG) Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", " + "forceRestart=" + forceRestart); + if (usbDataUnlocked != mUsbDataUnlocked) { + mUsbDataUnlocked = usbDataUnlocked; + updateUsbNotification(); + forceRestart = true; + } + // Try to set the enabled functions. final String oldFunctions = mCurrentFunctions; final boolean oldFunctionsApplied = mCurrentFunctionsApplied; @@ -514,7 +531,8 @@ public class UsbDeviceManager { } private boolean trySetEnabledFunctions(String functions, boolean forceRestart) { - if (functions == null) { + if (functions == null || applyAdbFunction(functions) + .equals(UsbManager.USB_FUNCTION_NONE)) { functions = getDefaultFunctions(); } functions = applyAdbFunction(functions); @@ -579,7 +597,7 @@ public class UsbDeviceManager { // make sure accessory mode is off // and restore default functions Slog.d(TAG, "exited USB accessory mode"); - setEnabledFunctions(null, false); + setEnabledFunctions(null, false, false); if (mCurrentAccessory != null) { if (mBootCompleted) { @@ -596,10 +614,6 @@ public class UsbDeviceManager { if (mBroadcastedIntent == null) { for (String key : keySet) { if (intent.getBooleanExtra(key, false)) { - // MTP function is enabled by default. - if (UsbManager.USB_FUNCTION_MTP.equals(key)) { - continue; - } return true; } } @@ -712,10 +726,7 @@ public class UsbDeviceManager { case MSG_UPDATE_STATE: mConnected = (msg.arg1 == 1); mConfigured = (msg.arg2 == 1); - if (!mConnected) { - // When a disconnect occurs, relock access to sensitive user data - mUsbDataUnlocked = false; - } + updateUsbNotification(); updateAdbNotification(); if (UsbManager.containsFunction(mCurrentFunctions, @@ -723,7 +734,7 @@ public class UsbDeviceManager { updateCurrentAccessory(); } else if (!mConnected) { // restore defaults when USB is disconnected - setEnabledFunctions(null, false); + setEnabledFunctions(null, false, false); } if (mBootCompleted) { updateUsbStateBroadcastIfNeeded(); @@ -746,13 +757,10 @@ public class UsbDeviceManager { break; case MSG_SET_CURRENT_FUNCTIONS: String functions = (String)msg.obj; - setEnabledFunctions(functions, false); + setEnabledFunctions(functions, false, msg.arg1 == 1); break; case MSG_UPDATE_USER_RESTRICTIONS: - setEnabledFunctions(mCurrentFunctions, false); - break; - case MSG_SET_USB_DATA_UNLOCKED: - setUsbDataUnlocked(msg.arg1 == 1); + setEnabledFunctions(mCurrentFunctions, false, mUsbDataUnlocked); break; case MSG_SYSTEM_READY: updateUsbNotification(); @@ -780,8 +788,7 @@ public class UsbDeviceManager { Slog.v(TAG, "Current user switched to " + mCurrentUser + "; resetting USB host stack for MTP or PTP"); // avoid leaking sensitive data from previous user - mUsbDataUnlocked = false; - setEnabledFunctions(mCurrentFunctions, true); + setEnabledFunctions(mCurrentFunctions, true, false); } mCurrentUser = msg.arg1; } @@ -965,14 +972,10 @@ public class UsbDeviceManager { return UsbManager.containsFunction(SystemProperties.get(USB_CONFIG_PROPERTY), function); } - public void setCurrentFunctions(String functions) { - if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ")"); - mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions); - } - - public void setUsbDataUnlocked(boolean unlocked) { - if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked(" + unlocked + ")"); - mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked); + public void setCurrentFunctions(String functions, boolean usbDataUnlocked) { + if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ", " + + usbDataUnlocked + ")"); + mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, usbDataUnlocked); } private void readOemUsbOverrideConfig() { diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index d6dbe90584f51..daccc00ad80c5 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -287,7 +287,7 @@ public class UsbService extends IUsbManager.Stub { } @Override - public void setCurrentFunction(String function) { + public void setCurrentFunction(String function, boolean usbDataUnlocked) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); if (!isSupportedCurrentFunction(function)) { @@ -297,7 +297,7 @@ public class UsbService extends IUsbManager.Stub { } if (mDeviceManager != null) { - mDeviceManager.setCurrentFunctions(function); + mDeviceManager.setCurrentFunctions(function, usbDataUnlocked); } else { throw new IllegalStateException("USB device mode not supported"); } @@ -319,12 +319,6 @@ public class UsbService extends IUsbManager.Stub { return false; } - @Override - public void setUsbDataUnlocked(boolean unlocked) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); - mDeviceManager.setUsbDataUnlocked(unlocked); - } - @Override public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);