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

Commit e18a4067 authored by Mike Lockwood's avatar Mike Lockwood Committed by Android Git Automerger
Browse files

am 094c9900: am 2c3ed826: Merge "Change UsbManager.requestPermission to only...

am 094c9900: am 2c3ed826: Merge "Change UsbManager.requestPermission to only grant permission temporarily" into honeycomb-mr1

* commit '094c9900':
  Change UsbManager.requestPermission to only grant permission temporarily
parents f9f60879 094c9900
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