Merge "Change UsbManager.requestPermission to only grant permission temporarily" into honeycomb-mr1
This commit is contained in:
committed by
Android (Google) Code Review
commit
2c3ed82600
@@ -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);
|
||||
}
|
||||
|
||||
@@ -108,6 +108,14 @@ public class UsbAccessory implements Parcelable {
|
||||
return false;
|
||||
}
|
||||
|
||||
@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 +
|
||||
|
||||
@@ -269,6 +269,11 @@ public final class UsbDevice implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UsbDevice[mName=" + mName + ",mVendorId=" + mVendorId +
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user