summaryrefslogtreecommitdiffstats
path: root/libs/usb
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2011-03-11 20:00:53 -0500
committerMike Lockwood <lockwood@android.com>2011-03-11 20:02:43 -0500
commit2cc0377200b94b2f68f34e34554f2aa39e09cbce (patch)
tree5c31638c6a2905e5dfc13ae210b4c4837112df1d /libs/usb
parent68f66b945e7a69549689becd2e656d9056f1e7f5 (diff)
downloadframeworks_base-2cc0377200b94b2f68f34e34554f2aa39e09cbce.zip
frameworks_base-2cc0377200b94b2f68f34e34554f2aa39e09cbce.tar.gz
frameworks_base-2cc0377200b94b2f68f34e34554f2aa39e09cbce.tar.bz2
DO NOT MERGE: backport recent USB accessory changes from honeycomb
Bug: 4082651 Change-Id: Ie7c2fc796dd3c64f803acbd14210e5949683f4ed Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'libs/usb')
-rw-r--r--libs/usb/src/com/android/future/usb/UsbAccessory.java44
-rw-r--r--libs/usb/src/com/android/future/usb/UsbManager.java68
-rw-r--r--libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c11
-rw-r--r--libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java77
4 files changed, 167 insertions, 33 deletions
diff --git a/libs/usb/src/com/android/future/usb/UsbAccessory.java b/libs/usb/src/com/android/future/usb/UsbAccessory.java
index cdd2b73..3d0707f 100644
--- a/libs/usb/src/com/android/future/usb/UsbAccessory.java
+++ b/libs/usb/src/com/android/future/usb/UsbAccessory.java
@@ -23,14 +23,16 @@ public final class UsbAccessory {
private final String mManufacturer;
private final String mModel;
- private final String mType;
+ private final String mDescription;
private final String mVersion;
+ private final String mUri;
/* package */ UsbAccessory(android.hardware.usb.UsbAccessory accessory) {
mManufacturer = accessory.getManufacturer();
mModel = accessory.getModel();
- mType = accessory.getType();
+ mDescription = accessory.getDescription();
mVersion = accessory.getVersion();
+ mUri = accessory.getUri();
}
/**
@@ -52,12 +54,12 @@ public final class UsbAccessory {
}
/**
- * Returns the type of the accessory.
+ * Returns a user visible description of the accessory.
*
- * @return the accessory type
+ * @return the accessory description
*/
- public String getType() {
- return mType;
+ public String getDescription() {
+ return mDescription;
}
/**
@@ -69,6 +71,17 @@ public final class UsbAccessory {
return mVersion;
}
+ /**
+ * Returns the URI for the accessory.
+ * This is an optional URI that might show information about the accessory
+ * or provide the option to download an application for the accessory
+ *
+ * @return the accessory URI
+ */
+ public String getUri() {
+ return mUri;
+ }
+
private static boolean compare(String s1, String s2) {
if (s1 == null) return (s2 == null);
return s1.equals(s2);
@@ -80,17 +93,28 @@ public final class UsbAccessory {
UsbAccessory accessory = (UsbAccessory)obj;
return (compare(mManufacturer, accessory.getManufacturer()) &&
compare(mModel, accessory.getModel()) &&
- compare(mType, accessory.getType()) &&
- compare(mVersion, accessory.getVersion()));
+ compare(mDescription, accessory.getDescription()) &&
+ compare(mVersion, accessory.getVersion()) &&
+ compare(mUri, accessory.getUri()));
}
return false;
}
@Override
+ public int hashCode() {
+ return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^
+ (mModel == null ? 0 : mModel.hashCode()) ^
+ (mDescription == null ? 0 : mDescription.hashCode()) ^
+ (mVersion == null ? 0 : mVersion.hashCode()) ^
+ (mUri == null ? 0 : mUri.hashCode()));
+ }
+
+ @Override
public String toString() {
return "UsbAccessory[mManufacturer=" + mManufacturer +
", mModel=" + mModel +
- ", mType=" + mType +
- ", mVersion=" + mVersion + "]";
+ ", mDescription=" + mDescription +
+ ", mVersion=" + mVersion +
+ ", mUri=" + mUri + "]";
}
}
diff --git a/libs/usb/src/com/android/future/usb/UsbManager.java b/libs/usb/src/com/android/future/usb/UsbManager.java
index f74b291..840e1e3 100644
--- a/libs/usb/src/com/android/future/usb/UsbManager.java
+++ b/libs/usb/src/com/android/future/usb/UsbManager.java
@@ -17,6 +17,7 @@
package com.android.future.usb;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.IUsbManager;
@@ -55,28 +56,39 @@ public class UsbManager {
public static final String ACTION_USB_ACCESSORY_DETACHED =
"android.hardware.usb.action.USB_ACCESSORY_DETACHED";
+ /**
+ * Name of extra added to the {@link android.app.PendingIntent}
+ * passed into {#requestPermission} or {#requestPermission}
+ * containing a boolean value indicating whether the user granted permission or not.
+ */
+ public static final String EXTRA_PERMISSION_GRANTED = "permission";
+
+ private final Context mContext;
private final IUsbManager mService;
- private UsbManager(IUsbManager service) {
+ private UsbManager(Context context, IUsbManager service) {
+ mContext = context;
mService = service;
}
/**
* Returns a new instance of this class.
*
+ * @param context the caller's {@link android.content.Context}
* @return UsbManager instance.
*/
- public static UsbManager getInstance() {
+ public static UsbManager getInstance(Context context) {
IBinder b = ServiceManager.getService(Context.USB_SERVICE);
- return new UsbManager(IUsbManager.Stub.asInterface(b));
+ return new UsbManager(context, IUsbManager.Stub.asInterface(b));
}
/**
* Returns the {@link com.google.android.usb.UsbAccessory} for
* a {@link #ACTION_USB_ACCESSORY_ATTACHED} or {@link #ACTION_USB_ACCESSORY_ATTACHED}
- * broadcast Intent
+ * broadcast Intent. This can also be used to retrieve the accessory from the result
+ * of a call to {#requestPermission}.
*
- * @return UsbAccessory for the broadcast.
+ * @return UsbAccessory for the intent.
*/
public static UsbAccessory getAccessory(Intent intent) {
android.hardware.usb.UsbAccessory accessory =
@@ -118,10 +130,54 @@ public class UsbManager {
try {
return mService.openAccessory(new android.hardware.usb.UsbAccessory(
accessory.getManufacturer(),accessory.getModel(),
- accessory.getType(), accessory.getVersion()));
+ accessory.getDescription(), accessory.getVersion(), accessory.getUri()));
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in openAccessory" , e);
return null;
}
}
+
+ /**
+ * 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
+ */
+ public boolean hasPermission(UsbAccessory accessory) {
+ try {
+ return mService.hasAccessoryPermission(new android.hardware.usb.UsbAccessory(
+ accessory.getManufacturer(),accessory.getModel(),
+ accessory.getDescription(), accessory.getVersion(), accessory.getUri()));
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in hasPermission", e);
+ return false;
+ }
+ }
+
+ /**
+ * 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.
+ * The boolean extra {@link #EXTRA_PERMISSION_GRANTED} will be attached to the
+ * PendingIntent to indicate success or failure.
+ * If successful, this grants the caller permission to access the device only
+ * until the device is disconnected.
+ *
+ * @param accessory to request permissions for
+ * @param pi PendingIntent for returning result
+ */
+ public void requestPermission(UsbAccessory accessory, PendingIntent pi) {
+ try {
+ mService.requestAccessoryPermission(new android.hardware.usb.UsbAccessory(
+ accessory.getManufacturer(),accessory.getModel(),
+ accessory.getDescription(), accessory.getVersion(), accessory.getUri()),
+ mContext.getPackageName(), pi);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in requestPermission", e);
+ }
+ }
}
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
index 94cc0ce..3c0de69 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
+++ b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
@@ -133,10 +133,19 @@ static int usb_device_added(const char *devname, void* client_data) {
} else {
printf("Found possible android device - attempting to switch to accessory mode\n");
+ uint16_t protocol;
+ ret = usb_device_control_transfer(device, USB_DIR_IN | USB_TYPE_VENDOR,
+ ACCESSORY_GET_PROTOCOL, 0, 0, &protocol, sizeof(protocol), 0);
+ if (ret == 2)
+ printf("device supports protocol version %d\n", protocol);
+ else
+ fprintf(stderr, "failed to read protocol version\n");
+
send_string(device, ACCESSORY_STRING_MANUFACTURER, "Google, Inc.");
send_string(device, ACCESSORY_STRING_MODEL, "AccessoryChat");
- send_string(device, ACCESSORY_STRING_TYPE, "Sample Program");
+ send_string(device, ACCESSORY_STRING_DESCRIPTION, "Sample Program");
send_string(device, ACCESSORY_STRING_VERSION, "1.0");
+ send_string(device, ACCESSORY_STRING_URI, "http://www.android.com");
ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
ACCESSORY_START, 0, 0, 0, 0, 0);
diff --git a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
index 5cf02c7..f9a5bf4 100644
--- a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
+++ b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
@@ -17,9 +17,11 @@
package com.android.accessorychat;
import android.app.Activity;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -42,18 +44,47 @@ import java.io.IOException;
public class AccessoryChat extends Activity implements Runnable, TextView.OnEditorActionListener {
private static final String TAG = "AccessoryChat";
- TextView mLog;
- EditText mEditText;
- ParcelFileDescriptor mFileDescriptor;
- FileInputStream mInputStream;
- FileOutputStream mOutputStream;
+
+ private static final String ACTION_USB_PERMISSION =
+ "com.android.accessorychat.action.USB_PERMISSION";
+
+ private TextView mLog;
+ private EditText mEditText;
+ private ParcelFileDescriptor mFileDescriptor;
+ private FileInputStream mInputStream;
+ private FileOutputStream mOutputStream;
+ private UsbManager mUsbManager;
+ private PendingIntent mPermissionIntent;
+ private boolean mPermissionRequestPending;
private static final int MESSAGE_LOG = 1;
+ private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
+ synchronized (this) {
+ UsbAccessory accessory = UsbManager.getAccessory(intent);
+ if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
+ openAccessory(accessory);
+ } else {
+ Log.d(TAG, "permission denied for accessory " + accessory);
+ }
+ mPermissionRequestPending = false;
+ }
+ }
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mUsbManager = UsbManager.getInstance(this);
+ mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
+ IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
+ registerReceiver(mUsbReceiver, filter);
+
setContentView(R.layout.accessory_chat);
mLog = (TextView)findViewById(R.id.log);
mEditText = (EditText)findViewById(R.id.message);
@@ -66,21 +97,20 @@ public class AccessoryChat extends Activity implements Runnable, TextView.OnEdit
Intent intent = getIntent();
Log.d(TAG, "intent: " + intent);
- UsbManager manager = UsbManager.getInstance();
- UsbAccessory[] accessories = manager.getAccessoryList();
+ UsbAccessory[] accessories = mUsbManager.getAccessoryList();
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
- mFileDescriptor = manager.openAccessory(accessory);
- if (mFileDescriptor != null) {
- FileDescriptor fd = mFileDescriptor.getFileDescriptor();
- mInputStream = new FileInputStream(fd);
- mOutputStream = new FileOutputStream(fd);
- Thread thread = new Thread(null, this, "AccessoryChat");
- thread.start();
+ if (mUsbManager.hasPermission(accessory)) {
+ openAccessory(accessory);
} else {
- Log.d(TAG, "openAccessory fail");
+ synchronized (mUsbReceiver) {
+ if (!mPermissionRequestPending) {
+ mUsbManager.requestPermission(accessory, mPermissionIntent);
+ mPermissionRequestPending = true;
+ }
+ }
}
- } else {
+ } else {
Log.d(TAG, "mAccessory is null");
}
}
@@ -100,9 +130,24 @@ public class AccessoryChat extends Activity implements Runnable, TextView.OnEdit
@Override
public void onDestroy() {
+ unregisterReceiver(mUsbReceiver);
super.onDestroy();
}
+ private void openAccessory(UsbAccessory accessory) {
+ mFileDescriptor = mUsbManager.openAccessory(accessory);
+ if (mFileDescriptor != null) {
+ FileDescriptor fd = mFileDescriptor.getFileDescriptor();
+ mInputStream = new FileInputStream(fd);
+ mOutputStream = new FileOutputStream(fd);
+ Thread thread = new Thread(null, this, "AccessoryChat");
+ thread.start();
+ Log.d(TAG, "openAccessory succeeded");
+ } else {
+ Log.d(TAG, "openAccessory fail");
+ }
+ }
+
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE && mOutputStream != null) {
try {