summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2015-06-10 21:11:31 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-06-10 21:11:38 +0000
commit5ac4a5fa38fe1bea0007235840fb77ba3648a1d3 (patch)
tree1726be6d9eefb463c75463a1fe94ac3c8833432d
parenta6dd714a5ab620cf5b84c2d1f680ddacf763559d (diff)
parent674019065bceb4150190bfb1aa63cda9de0a8560 (diff)
downloadframeworks_base-5ac4a5fa38fe1bea0007235840fb77ba3648a1d3.zip
frameworks_base-5ac4a5fa38fe1bea0007235840fb77ba3648a1d3.tar.gz
frameworks_base-5ac4a5fa38fe1bea0007235840fb77ba3648a1d3.tar.bz2
Merge "Fix USB access control when adb is disabled." into mnc-dev
-rw-r--r--core/java/android/hardware/usb/IUsbManager.aidl10
-rw-r--r--core/java/android/hardware/usb/UsbManager.java40
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java40
-rw-r--r--services/usb/java/com/android/server/usb/UsbService.java12
4 files changed, 99 insertions, 3 deletions
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 881dc0f..31a6a96 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -85,6 +85,16 @@ interface IUsbManager
/* 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.
+ */
+ void setUsbDataUnlocked(boolean unlock);
+
+ /* Returns true iff sensitive user data is exposed on the USB connection. */
+ boolean isUsbDataUnlocked();
+
/* 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 000d41f..c83f466 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -142,6 +142,16 @@ public class UsbManager {
public static final String USB_CONFIGURED = "configured";
/**
+ * Boolean extra indicating whether confidential user data, such as photos, should be
+ * made available on the USB connection. This variable will only be set when the user
+ * has explicitly asked for this data to be unlocked.
+ * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
+ *
+ * {@hide}
+ */
+ public static final String USB_DATA_UNLOCKED = "unlocked";
+
+ /**
* Name of the USB mass storage USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
@@ -464,4 +474,34 @@ public class UsbManager {
Log.e(TAG, "RemoteException in setCurrentFunction", e);
}
}
+
+ /**
+ * Sets whether USB data (for example, MTP exposed pictures) should be made available
+ * on the USB connection. 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);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in setUsbDataUnlocked", e);
+ }
+ }
+
+ /**
+ * Returns {@code true} iff access to sensitive USB data is currently allowed.
+ *
+ * {@hide}
+ */
+ public boolean isUsbDataUnlocked() {
+ try {
+ return mService.isUsbDataUnlocked();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in isUsbDataUnlocked", e);
+ }
+ return false;
+ }
+
}
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);