Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c3ed826 authored by Mike Lockwood's avatar Mike Lockwood Committed by Android (Google) Code Review
Browse files

Merge "Change UsbManager.requestPermission to only grant permission temporarily" into honeycomb-mr1

parents 5fa7aac8 c6f23e85
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);
}
+8 −0
Original line number Diff line number Diff line
@@ -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 +
+5 −0
Original line number Diff line number Diff line
@@ -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 +
+14 −2
Original line number Diff line number Diff line
@@ -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
+65 −182
Original line number Diff line number Diff line
@@ -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 (String deviceName : mDevicePermissionMap.keySet()) {
                pw.print("    " + deviceName + ": ");
                SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName);
                int count = uidList.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);
                    pw.print(Integer.toString(uidList.keyAt(i)) + " ");
                }
                pw.println("");
            }
            pw.println("  Accessory permissions:");
            count = mAccessoryPermissionMap.size();
            for (UsbAccessory accessory : mAccessoryPermissionMap.keySet()) {
                pw.print("    " + accessory + ": ");
                SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
                int count = uidList.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);
                    pw.print(Integer.toString(uidList.keyAt(i)) + " ");
                }
                pw.println("");
            }
            pw.println("  Device preferences:");
            for (DeviceFilter filter : mDevicePreferenceMap.keySet()) {
Loading