summaryrefslogtreecommitdiffstats
path: root/services/usb
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2015-06-10 09:38:42 -0700
committerNick Kralevich <nnk@google.com>2015-06-10 10:29:48 -0700
commit674019065bceb4150190bfb1aa63cda9de0a8560 (patch)
tree9f9ed636f52c916afd9b1dd9805e1c9a94aa8757 /services/usb
parent89124000c618f24b948505cd79f654aacbdff957 (diff)
downloadframeworks_base-674019065bceb4150190bfb1aa63cda9de0a8560.zip
frameworks_base-674019065bceb4150190bfb1aa63cda9de0a8560.tar.gz
frameworks_base-674019065bceb4150190bfb1aa63cda9de0a8560.tar.bz2
Fix USB access control when adb is disabled.
When adb is disabled, the default usb mode would be "none", which would turn off the driver and prevent UsbDeviceManager from receiving any new USB connect / disconnect messages. This prevents the user from ever enabling MTP and sharing data when adb is turned off. As discussed in bug 21429947, we work around this problem by keeping the USB driver in MTP mode most of the time, so that we continue to receive USB connect / disconnect messages. To avoid leaking confidential user photos, this change introduces an unlocked state. Setting the mtp enabled function is now decoupled from exposing data on the USB connection. Only if MTP is enabled and USB data has been unlocked is confidential user data allowed to be shared. Bug: 21429947 Change-Id: Iefb5c7e22dc4962bf5226f2ed3d0155b5c7b413c
Diffstat (limited to 'services/usb')
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java40
-rw-r--r--services/usb/java/com/android/server/usb/UsbService.java12
2 files changed, 49 insertions, 3 deletions
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index d6a7dd1..588f8c6 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -91,6 +91,7 @@ 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 AUDIO_MODE_SOURCE = 1;
@@ -314,6 +315,7 @@ public class UsbDeviceManager {
// current USB state
private boolean mConnected;
private boolean mConfigured;
+ private boolean mUsbDataUnlocked;
private String mCurrentFunctions;
private UsbAccessory mCurrentAccessory;
private int mUsbNotificationId;
@@ -350,7 +352,7 @@ public class UsbDeviceManager {
SystemProperties.get(UsbManager.ADB_PERSISTENT_PROPERTY, "adb"),
UsbManager.USB_FUNCTION_ADB);
- mCurrentFunctions = mAdbEnabled ? "adb" : "none";
+ mCurrentFunctions = mAdbEnabled ? "adb" : UsbManager.USB_FUNCTION_MTP;
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
updateState(state);
@@ -459,6 +461,15 @@ public class UsbDeviceManager {
}
}
+ /**
+ * Stop and start the USB driver. This is needed to close all outstanding
+ * USB connections.
+ */
+ private void restartCurrentFunction() {
+ setUsbConfig("none");
+ setUsbConfig(mCurrentFunctions);
+ }
+
private void setEnabledFunctions(String functions) {
if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions);
@@ -531,6 +542,7 @@ public class UsbDeviceManager {
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(UsbManager.USB_CONNECTED, mConnected);
intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured);
+ intent.putExtra(UsbManager.USB_DATA_UNLOCKED, mUsbDataUnlocked);
if (mCurrentFunctions != null) {
String[] functions = mCurrentFunctions.split(",");
@@ -599,6 +611,10 @@ 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 (containsFunction(mCurrentFunctions,
@@ -621,6 +637,12 @@ public class UsbDeviceManager {
String functions = (String)msg.obj;
setEnabledFunctions(functions);
break;
+ case MSG_SET_USB_DATA_UNLOCKED:
+ mUsbDataUnlocked = (msg.arg1 == 1);
+ updateUsbNotification();
+ updateUsbState();
+ restartCurrentFunction();
+ break;
case MSG_SYSTEM_READY:
setUsbConfig(mCurrentFunctions);
updatePersistentProperty();
@@ -676,7 +698,9 @@ public class UsbDeviceManager {
int id = 0;
Resources r = mContext.getResources();
if (mConnected) {
- if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) {
+ if (!mUsbDataUnlocked) {
+ id = com.android.internal.R.string.usb_charging_notification_title;
+ } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) {
id = com.android.internal.R.string.usb_mtp_notification_title;
} else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP)) {
id = com.android.internal.R.string.usb_ptp_notification_title;
@@ -771,7 +795,7 @@ public class UsbDeviceManager {
}
private String getDefaultFunctions() {
- return "none";
+ return UsbManager.USB_FUNCTION_MTP;
}
public void dump(FileDescriptor fd, PrintWriter pw) {
@@ -817,6 +841,16 @@ public class UsbDeviceManager {
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 boolean isUsbDataUnlocked() {
+ if (DEBUG) Slog.d(TAG, "isUsbDataUnlocked() -> " + mHandler.mUsbDataUnlocked);
+ return mHandler.mUsbDataUnlocked;
+ }
+
private void readOemUsbOverrideConfig() {
String[] configList = mContext.getResources().getStringArray(
com.android.internal.R.array.config_oemUsbModeOverride);
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 51281a2..7a3426c 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -271,6 +271,18 @@ public class UsbService extends IUsbManager.Stub {
}
@Override
+ public void setUsbDataUnlocked(boolean unlocked) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ mDeviceManager.setUsbDataUnlocked(unlocked);
+ }
+
+ @Override
+ public boolean isUsbDataUnlocked() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ return mDeviceManager.isUsbDataUnlocked();
+ }
+
+ @Override
public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey);