summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2011-03-09 12:05:20 -0500
committerMike Lockwood <lockwood@android.com>2011-03-09 12:33:00 -0500
commitc6f23e8521dedac7a07119031913235be3ca37c3 (patch)
tree0e25041664958b4f96b41475f25f95b13b8d6b6d
parentea44c7c71431adbce348cf9ef3f22d9561bb7fc1 (diff)
downloadframeworks_base-c6f23e8521dedac7a07119031913235be3ca37c3.zip
frameworks_base-c6f23e8521dedac7a07119031913235be3ca37c3.tar.gz
frameworks_base-c6f23e8521dedac7a07119031913235be3ca37c3.tar.bz2
Change UsbManager.requestPermission to only grant permission temporarily
If the user approves an application to access a USB device or accessory without choosing it as the default application, then permission is granted only until the device or accessory is disconnected. Only applications chosen as the default choice have permissions assigned persistently. BUG: 4061035 Change-Id: Ic4f6271a91b2fc56bbeef82c579e26d88c63ae56 Signed-off-by: Mike Lockwood <lockwood@android.com>
-rw-r--r--core/java/android/hardware/usb/IUsbManager.aidl4
-rw-r--r--core/java/android/hardware/usb/UsbAccessory.java8
-rw-r--r--core/java/android/hardware/usb/UsbDevice.java5
-rw-r--r--core/java/android/hardware/usb/UsbManager.java16
-rw-r--r--services/java/com/android/server/usb/UsbDeviceSettingsManager.java247
-rw-r--r--services/java/com/android/server/usb/UsbService.java8
6 files changed, 98 insertions, 190 deletions
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index c79a458..495fa21 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -77,8 +77,8 @@ interface IUsbManager
void grantAccessoryPermission(in UsbAccessory accessory, int uid);
/* Returns true if the USB manager has default preferences or permissions for the package */
- boolean hasDefaults(String packageName, int uid);
+ boolean hasDefaults(String packageName);
/* Clears default preferences and permissions for the package */
- oneway void clearDefaults(String packageName, int uid);
+ oneway void clearDefaults(String packageName);
}
diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
index 6cd9178..7d66caa 100644
--- a/core/java/android/hardware/usb/UsbAccessory.java
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -109,6 +109,14 @@ public class UsbAccessory implements Parcelable {
}
@Override
+ public int hashCode() {
+ return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^
+ (mModel == null ? 0 : mModel.hashCode()) ^
+ (mType == null ? 0 : mType.hashCode()) ^
+ (mVersion == null ? 0 : mVersion.hashCode()));
+ }
+
+ @Override
public String toString() {
return "UsbAccessory[mManufacturer=" + mManufacturer +
", mModel=" + mModel +
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 37bd82b..39254b38 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -270,6 +270,11 @@ public final class UsbDevice implements Parcelable {
}
@Override
+ public int hashCode() {
+ return mName.hashCode();
+ }
+
+ @Override
public String toString() {
return "UsbDevice[mName=" + mName + ",mVendorId=" + mVendorId +
",mProductId=" + mProductId + ",mClass=" + mClass +
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 9f1b8ea..5df0ac7 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -281,6 +281,9 @@ public class UsbManager {
/**
* Returns true if the caller has permission to access the device.
+ * Permission might have been granted temporarily via
+ * {@link #requestPermission(android.hardware.usb.UsbDevice} or
+ * by the user choosing the caller as the default application for the device.
*
* @param device to check permissions for
* @return true if caller has permission
@@ -296,6 +299,9 @@ public class UsbManager {
/**
* Returns true if the caller has permission to access the accessory.
+ * Permission might have been granted temporarily via
+ * {@link #requestPermission(android.hardware.usb.UsbAccessory} or
+ * by the user choosing the caller as the default application for the accessory.
*
* @param accessory to check permissions for
* @return true if caller has permission
@@ -310,10 +316,13 @@ public class UsbManager {
}
/**
- * Requests permission for the given package to access the device.
+ * Requests temporary permission for the given package to access the device.
* This may result in a system dialog being displayed to the user
* if permission had not already been granted.
* Success or failure is returned via the {@link android.app.PendingIntent} pi.
+ * If successful, this grants the caller permission to access the device only
+ * until the device is disconnected.
+ *
* The following extras will be added to pi:
* <ul>
* <li> {@link #EXTRA_DEVICE} containing the device passed into this call
@@ -333,10 +342,13 @@ public class UsbManager {
}
/**
- * Requests permission for the given package to access the accessory.
+ * Requests temporary permission for the given package to access the accessory.
* This may result in a system dialog being displayed to the user
* if permission had not already been granted.
* Success or failure is returned via the {@link android.app.PendingIntent} pi.
+ * If successful, this grants the caller permission to access the device only
+ * until the device is disconnected.
+ *
* The following extras will be added to pi:
* <ul>
* <li> {@link #EXTRA_ACCESSORY} containing the accessory passed into this call
diff --git a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
index 29e6f94..25eac6f 100644
--- a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java
@@ -35,7 +35,7 @@ import android.os.Binder;
import android.os.FileUtils;
import android.os.Process;
import android.util.Log;
-import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.Xml;
import com.android.internal.content.PackageMonitor;
@@ -65,16 +65,16 @@ class UsbDeviceSettingsManager {
private final Context mContext;
- // maps UID to user approved USB devices
- private final SparseArray<ArrayList<DeviceFilter>> mDevicePermissionMap =
- new SparseArray<ArrayList<DeviceFilter>>();
- // maps UID to user approved USB accessories
- private final SparseArray<ArrayList<AccessoryFilter>> mAccessoryPermissionMap =
- new SparseArray<ArrayList<AccessoryFilter>>();
+ // Temporary mapping USB device name to list of UIDs with permissions for the device
+ private final HashMap<String, SparseBooleanArray> mDevicePermissionMap =
+ new HashMap<String, SparseBooleanArray>();
+ // Temporary mapping UsbAccessory to list of UIDs with permissions for the accessory
+ private final HashMap<UsbAccessory, SparseBooleanArray> mAccessoryPermissionMap =
+ new HashMap<UsbAccessory, SparseBooleanArray>();
// Maps DeviceFilter to user preferred application package
private final HashMap<DeviceFilter, String> mDevicePreferenceMap =
new HashMap<DeviceFilter, String>();
- // Maps DeviceFilter to user preferred application package
+ // Maps AccessoryFilter to user preferred application package
private final HashMap<AccessoryFilter, String> mAccessoryPreferenceMap =
new HashMap<AccessoryFilter, String>();
@@ -354,15 +354,6 @@ class UsbDeviceSettingsManager {
}
}
}
-
- public void onUidRemoved(int uid) {
- synchronized (mLock) {
- // clear all permissions for the UID
- if (clearUidDefaultsLocked(uid)) {
- writeSettingsLocked();
- }
- }
- }
}
MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
@@ -374,44 +365,6 @@ class UsbDeviceSettingsManager {
mPackageMonitor.register(context, true);
}
- private void readDevicePermission(XmlPullParser parser)
- throws XmlPullParserException, IOException {
- int uid = -1;
- ArrayList<DeviceFilter> filters = new ArrayList<DeviceFilter>();
- int count = parser.getAttributeCount();
- for (int i = 0; i < count; i++) {
- if ("uid".equals(parser.getAttributeName(i))) {
- uid = Integer.parseInt(parser.getAttributeValue(i));
- break;
- }
- }
- XmlUtils.nextElement(parser);
- while ("usb-device".equals(parser.getName())) {
- filters.add(DeviceFilter.read(parser));
- XmlUtils.nextElement(parser);
- }
- mDevicePermissionMap.put(uid, filters);
- }
-
- private void readAccessoryPermission(XmlPullParser parser)
- throws XmlPullParserException, IOException {
- int uid = -1;
- ArrayList<AccessoryFilter> filters = new ArrayList<AccessoryFilter>();
- int count = parser.getAttributeCount();
- for (int i = 0; i < count; i++) {
- if ("uid".equals(parser.getAttributeName(i))) {
- uid = Integer.parseInt(parser.getAttributeValue(i));
- break;
- }
- }
- XmlUtils.nextElement(parser);
- while ("usb-accessory".equals(parser.getName())) {
- filters.add(AccessoryFilter.read(parser));
- XmlUtils.nextElement(parser);
- }
- mAccessoryPermissionMap.put(uid, filters);
- }
-
private void readPreference(XmlPullParser parser)
throws XmlPullParserException, IOException {
String packageName = null;
@@ -443,11 +396,7 @@ class UsbDeviceSettingsManager {
XmlUtils.nextElement(parser);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
String tagName = parser.getName();
- if ("device-permission".equals(tagName)) {
- readDevicePermission(parser);
- } else if ("accessory-permission".equals(tagName)) {
- readAccessoryPermission(parser);
- } else if ("preference".equals(tagName)) {
+ if ("preference".equals(tagName)) {
readPreference(parser);
} else {
XmlUtils.nextElement(parser);
@@ -480,32 +429,6 @@ class UsbDeviceSettingsManager {
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "settings");
- int count = mDevicePermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mDevicePermissionMap.keyAt(i);
- ArrayList<DeviceFilter> filters = mDevicePermissionMap.valueAt(i);
- serializer.startTag(null, "device-permission");
- serializer.attribute(null, "uid", Integer.toString(uid));
- int filterCount = filters.size();
- for (int j = 0; j < filterCount; j++) {
- filters.get(j).write(serializer);
- }
- serializer.endTag(null, "device-permission");
- }
-
- count = mAccessoryPermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mAccessoryPermissionMap.keyAt(i);
- ArrayList<AccessoryFilter> filters = mAccessoryPermissionMap.valueAt(i);
- serializer.startTag(null, "accessory-permission");
- serializer.attribute(null, "uid", Integer.toString(uid));
- int filterCount = filters.size();
- for (int j = 0; j < filterCount; j++) {
- filters.get(j).write(serializer);
- }
- serializer.endTag(null, "accessory-permission");
- }
-
for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
serializer.startTag(null, "preference");
serializer.attribute(null, "package", mDevicePreferenceMap.get(filter));
@@ -621,6 +544,9 @@ class UsbDeviceSettingsManager {
}
public void deviceDetached(UsbDevice device) {
+ // clear temporary permissions for the device
+ mDevicePermissionMap.remove(device.getDeviceName());
+
Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED);
intent.putExtra(UsbManager.EXTRA_DEVICE, device);
Log.d(TAG, "usbDeviceRemoved, sending " + intent);
@@ -644,6 +570,16 @@ class UsbDeviceSettingsManager {
resolveActivity(intent, matches, defaultPackage, null, accessory);
}
+ public void accessoryDetached(UsbAccessory accessory) {
+ // clear temporary permissions for the accessory
+ mAccessoryPermissionMap.remove(accessory);
+
+ Intent intent = new Intent(
+ UsbManager.ACTION_USB_ACCESSORY_DETACHED);
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
+ mContext.sendBroadcast(intent);
+ }
+
private void resolveActivity(Intent intent, ArrayList<ResolveInfo> matches,
String defaultPackage, UsbDevice device, UsbAccessory accessory) {
int count = matches.size();
@@ -659,13 +595,6 @@ class UsbDeviceSettingsManager {
rInfo.activityInfo.applicationInfo != null &&
(rInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
defaultRI = rInfo;
- int uid = rInfo.activityInfo.applicationInfo.uid;
- // grant permission
- if (device != null) {
- grantDevicePermission(device, uid);
- } else if (accessory != null) {
- grantAccessoryPermission(accessory, uid);
- }
}
}
@@ -682,6 +611,13 @@ class UsbDeviceSettingsManager {
}
if (defaultRI != null) {
+ // grant permission for default activity
+ if (device != null) {
+ grantDevicePermission(device, defaultRI.activityInfo.applicationInfo.uid);
+ } else if (accessory != null) {
+ grantAccessoryPermission(accessory, defaultRI.activityInfo.applicationInfo.uid);
+ }
+
// start default activity directly
try {
intent.setComponent(
@@ -711,47 +647,24 @@ class UsbDeviceSettingsManager {
}
}
- public void accessoryDetached(UsbAccessory accessory) {
- Intent intent = new Intent(
- UsbManager.ACTION_USB_ACCESSORY_DETACHED);
- intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
- mContext.sendBroadcast(intent);
- }
-
public boolean hasPermission(UsbDevice device) {
synchronized (mLock) {
- ArrayList<DeviceFilter> filterList =
- mDevicePermissionMap.get(Binder.getCallingUid());
- if (filterList != null) {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- DeviceFilter filter = filterList.get(i);
- if (filter.equals(device)) {
- // permission allowed
- return true;
- }
- }
+ SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());
+ if (uidList == null) {
+ return false;
}
+ return uidList.get(Binder.getCallingUid());
}
- return false;
}
public boolean hasPermission(UsbAccessory accessory) {
synchronized (mLock) {
- ArrayList<AccessoryFilter> filterList =
- mAccessoryPermissionMap.get(Binder.getCallingUid());
- if (filterList != null) {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- AccessoryFilter filter = filterList.get(i);
- if (filter.equals(accessory)) {
- // permission allowed
- return true;
- }
- }
+ SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
+ if (uidList == null) {
+ return false;
}
+ return uidList.get(Binder.getCallingUid());
}
- return false;
}
public void checkPermission(UsbDevice device) {
@@ -873,73 +786,43 @@ class UsbDeviceSettingsManager {
public void grantDevicePermission(UsbDevice device, int uid) {
synchronized (mLock) {
- ArrayList<DeviceFilter> filterList = mDevicePermissionMap.get(uid);
- if (filterList == null) {
- filterList = new ArrayList<DeviceFilter>();
- mDevicePermissionMap.put(uid, filterList);
- } else {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- if (filterList.get(i).equals(device)) return;
- }
+ String deviceName = device.getDeviceName();
+ SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName);
+ if (uidList == null) {
+ uidList = new SparseBooleanArray(1);
+ mDevicePermissionMap.put(deviceName, uidList);
}
- filterList.add(new DeviceFilter(device));
- writeSettingsLocked();
+ uidList.put(uid, true);
}
}
public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
synchronized (mLock) {
- ArrayList<AccessoryFilter> filterList = mAccessoryPermissionMap.get(uid);
- if (filterList == null) {
- filterList = new ArrayList<AccessoryFilter>();
- mAccessoryPermissionMap.put(uid, filterList);
- } else {
- int count = filterList.size();
- for (int i = 0; i < count; i++) {
- if (filterList.get(i).equals(accessory)) return;
- }
+ SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
+ if (uidList == null) {
+ uidList = new SparseBooleanArray(1);
+ mAccessoryPermissionMap.put(accessory, uidList);
}
- filterList.add(new AccessoryFilter(accessory));
- writeSettingsLocked();
+ uidList.put(uid, true);
}
}
- public boolean hasDefaults(String packageName, int uid) {
+ public boolean hasDefaults(String packageName) {
synchronized (mLock) {
- if (mDevicePermissionMap.get(uid) != null) return true;
- if (mAccessoryPermissionMap.get(uid) != null) return true;
if (mDevicePreferenceMap.values().contains(packageName)) return true;
if (mAccessoryPreferenceMap.values().contains(packageName)) return true;
return false;
}
}
- public void clearDefaults(String packageName, int uid) {
+ public void clearDefaults(String packageName) {
synchronized (mLock) {
- boolean packageCleared = clearPackageDefaultsLocked(packageName);
- boolean uidCleared = clearUidDefaultsLocked(uid);
- if (packageCleared || uidCleared) {
+ if (clearPackageDefaultsLocked(packageName)) {
writeSettingsLocked();
}
}
}
- private boolean clearUidDefaultsLocked(int uid) {
- boolean cleared = false;
- int index = mDevicePermissionMap.indexOfKey(uid);
- if (index >= 0) {
- mDevicePermissionMap.removeAt(index);
- cleared = true;
- }
- index = mAccessoryPermissionMap.indexOfKey(uid);
- if (index >= 0) {
- mAccessoryPermissionMap.removeAt(index);
- cleared = true;
- }
- return cleared;
- }
-
private boolean clearPackageDefaultsLocked(String packageName) {
boolean cleared = false;
synchronized (mLock) {
@@ -972,24 +855,24 @@ class UsbDeviceSettingsManager {
public void dump(FileDescriptor fd, PrintWriter pw) {
synchronized (mLock) {
pw.println(" Device permissions:");
- int count = mDevicePermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mDevicePermissionMap.keyAt(i);
- pw.println(" " + "uid " + uid + ":");
- ArrayList<DeviceFilter> filters = mDevicePermissionMap.valueAt(i);
- for (DeviceFilter filter : filters) {
- pw.println(" " + filter);
+ for (String deviceName : mDevicePermissionMap.keySet()) {
+ pw.print(" " + deviceName + ": ");
+ SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName);
+ int count = uidList.size();
+ for (int i = 0; i < count; i++) {
+ pw.print(Integer.toString(uidList.keyAt(i)) + " ");
}
+ pw.println("");
}
pw.println(" Accessory permissions:");
- count = mAccessoryPermissionMap.size();
- for (int i = 0; i < count; i++) {
- int uid = mAccessoryPermissionMap.keyAt(i);
- pw.println(" " + "uid " + uid + ":");
- ArrayList<AccessoryFilter> filters = mAccessoryPermissionMap.valueAt(i);
- for (AccessoryFilter filter : filters) {
- pw.println(" " + filter);
+ for (UsbAccessory accessory : mAccessoryPermissionMap.keySet()) {
+ pw.print(" " + accessory + ": ");
+ SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
+ int count = uidList.size();
+ for (int i = 0; i < count; i++) {
+ pw.print(Integer.toString(uidList.keyAt(i)) + " ");
}
+ pw.println("");
}
pw.println(" Device preferences:");
for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
diff --git a/services/java/com/android/server/usb/UsbService.java b/services/java/com/android/server/usb/UsbService.java
index d0a2492..71f2a9b 100644
--- a/services/java/com/android/server/usb/UsbService.java
+++ b/services/java/com/android/server/usb/UsbService.java
@@ -483,14 +483,14 @@ public class UsbService extends IUsbManager.Stub {
mDeviceManager.grantAccessoryPermission(accessory, uid);
}
- public boolean hasDefaults(String packageName, int uid) {
+ public boolean hasDefaults(String packageName) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- return mDeviceManager.hasDefaults(packageName, uid);
+ return mDeviceManager.hasDefaults(packageName);
}
- public void clearDefaults(String packageName, int uid) {
+ public void clearDefaults(String packageName) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- mDeviceManager.clearDefaults(packageName, uid);
+ mDeviceManager.clearDefaults(packageName);
}
/*