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

Commit 02eb8746 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

UsbManager: Enhancements for managing USB devices and accessories



When a USB device or accessory is connected, the UsbService now asks the
user which application to associate with the device or accessory.
Applications interested in devices or accessories must specify the
devices they work with via meta-data attached to their manifest.
Permission to communicate with the device is assigned when the user chooses
the activity to use for the device.
The user has the option of clicking the "always use this application" checkbox
to make the assignment automatic in the future.
The user may later clear this preference and revoke permission for an application
to have permission to communicate with the device by clicking the "Clear defaults"
button for the activity in the Manage Applications panel in Settings.

Added class UsbResolveActivity (a subclass or ResolveActivity for choosing
an activity for a USB device or accessory)

Added UsbDeviceManager, which manages the mapping between USB devices/accessories
and applications, including default applications for devices and accessories,
and manages application permissions.

Add interface to allow Settings to clear device and accessory
preferences and permissions for an application.

Remove obsolete ACCESS_USB permission.

Add new signatureOrSystem MANAGE_USB permission to allow administrating
preferences and permissions.

Moved UsbService.java to a "usb" subdirectory, along with new classes
UsbResolveActivity and UsbDeviceManager.

Change-Id: I92554381e9779e68ce380daaee4e1401fb875703
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent 12511f64
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -111,17 +111,6 @@
 visibility="public"
>
</field>
<field name="ACCESS_USB"
 type="java.lang.String"
 transient="false"
 volatile="false"
 value="&quot;android.permission.ACCESS_USB&quot;"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="ACCESS_WIFI_STATE"
 type="java.lang.String"
 transient="false"
+34 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.hardware;

import android.hardware.UsbAccessory;
import android.hardware.UsbDevice;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;

@@ -25,7 +26,39 @@ interface IUsbManager
{
    /* Returns a list of all currently attached USB devices */
    void getDeviceList(out Bundle devices);

    /* Returns a file descriptor for communicating with the USB device.
     * The native fd can be passed to usb_device_new() in libusbhost.
     */
    ParcelFileDescriptor openDevice(String deviceName);

    /* Returns the currently attached USB accessory */
    UsbAccessory getCurrentAccessory();
    ParcelFileDescriptor openAccessory();

    /* Returns a file descriptor for communicating with the USB accessory.
     * This file descriptor can be used with standard Java file operations.
     */
    ParcelFileDescriptor openAccessory(in UsbAccessory accessory);

    /* Sets the default package for a USB device
     * (or clears it if the package name is null)
     */
    oneway void setDevicePackage(in UsbDevice device, String packageName);

    /* Sets the default package for a USB device
     * (or clears it if the package name is null)
     */
    void setAccessoryPackage(in UsbAccessory accessory, String packageName);

    /* Grants permission for the given UID to access the device */
    void grantDevicePermission(in UsbDevice device, int uid);

    /* Grants permission for the given UID to access the accessory */
    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);

    /* Clears default preferences and permissions for the package */
    oneway void clearDefaults(String packageName, int uid);
}
+17 −0
Original line number Diff line number Diff line
@@ -95,6 +95,23 @@ public final class UsbAccessory implements Parcelable {
        return mVersion;
    }

    private static boolean compare(String s1, String s2) {
        if (s1 == null) return (s2 == null);
        return s1.equals(s2);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof UsbAccessory) {
            UsbAccessory accessory = (UsbAccessory)obj;
            return (compare(mManufacturer, accessory.getManufacturer()) &&
                    compare(mModel, accessory.getModel()) &&
                    compare(mType, accessory.getType()) &&
                    compare(mVersion, accessory.getVersion()));
        }
        return false;
    }

    @Override
    public String toString() {
        return "UsbAccessory[mManufacturer=" + mManufacturer +
+6 −5
Original line number Diff line number Diff line
@@ -163,14 +163,15 @@ public class UsbManager {

    /**
     * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} and
     * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts.
     * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts
     * containing the UsbDevice object for the device.
     */

    public static final String EXTRA_DEVICE = "device";

    /**
     * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
     * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} and
     * {@link #ACTION_USB_ACCESSORY_DETACHED} broadcasts
     * containing the UsbAccessory object for the accessory.
     */
    public static final String EXTRA_ACCESSORY = "accessory";
@@ -244,7 +245,7 @@ public class UsbManager {
                return new UsbAccessory[] { accessory };
            }
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException in openAccessory" , e);
            Log.e(TAG, "RemoteException in getAccessoryList" , e);
            return null;
        }
    }
@@ -257,7 +258,7 @@ public class UsbManager {
     */
    public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
        try {
            return mService.openAccessory();
            return mService.openAccessory(accessory);
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException in openAccessory" , e);
            return null;
+16 −5
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ public class ResolverActivity extends AlertActivity implements

    protected void onCreate(Bundle savedInstanceState, Intent intent,
            CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
            boolean alwaysUseOption) {
            boolean alwaysUseOption, boolean alwaysChoose) {
        super.onCreate(savedInstanceState);
        mPm = getPackageManager();
        intent.setComponent(null);
@@ -90,9 +90,10 @@ public class ResolverActivity extends AlertActivity implements
            mClearDefaultHint.setVisibility(View.GONE);
        }
        mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList);
        if (mAdapter.getCount() > 1) {
        int count = mAdapter.getCount();
        if (count > 1 || (count == 1 && alwaysChoose)) {
            ap.mAdapter = mAdapter;
        } else if (mAdapter.getCount() == 1) {
        } else if (count == 1) {
            startActivity(mAdapter.intentForPosition(0));
            finish();
            return;
@@ -103,11 +104,22 @@ public class ResolverActivity extends AlertActivity implements
        setupAlert();
    }

    protected void onCreate(Bundle savedInstanceState, Intent intent,
            CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
            boolean alwaysUseOption) {
        onCreate(savedInstanceState, intent, title, initialIntents, rList, alwaysUseOption, false);
      }

    public void onClick(DialogInterface dialog, int which) {
        ResolveInfo ri = mAdapter.resolveInfoForPosition(which);
        Intent intent = mAdapter.intentForPosition(which);
        boolean alwaysCheck = (mAlwaysCheck != null && mAlwaysCheck.isChecked());
        onIntentSelected(ri, intent, alwaysCheck);
        finish();
    }

        if ((mAlwaysCheck != null) && mAlwaysCheck.isChecked()) {
    protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
        if (alwaysCheck) {
            // Build a reasonable intent filter, based on what matched.
            IntentFilter filter = new IntentFilter();

@@ -190,7 +202,6 @@ public class ResolverActivity extends AlertActivity implements
        if (intent != null) {
            startActivity(intent);
        }
        finish();
    }

    private final class DisplayResolveInfo {
Loading