From 638d7cb3ee0bb3596b01dc19eca9456fa72a36e0 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Mon, 14 Mar 2011 21:56:33 -0400 Subject: DO NOT MERGE: Backport more USB accessory changes from honeycomb Change-Id: I8459c5ab9fbf0b3cad752041484a5de44ca9badd Signed-off-by: Mike Lockwood --- core/java/android/hardware/usb/UsbAccessory.java | 29 ++++- .../src/com/android/future/usb/UsbAccessory.java | 24 +++- .../usb/src/com/android/future/usb/UsbManager.java | 9 +- libs/usb/tests/AccessoryChat/Android.mk | 2 +- libs/usb/tests/AccessoryChat/AndroidManifest.xml | 4 +- .../AccessoryChat/accessorychat/accessorychat.c | 15 ++- .../com/android/accessorychat/AccessoryChat.java | 3 +- packages/SystemUI/AndroidManifest.xml | 9 ++ packages/SystemUI/res/values/strings.xml | 12 +- .../systemui/usb/UsbAccessoryUriActivity.java | 2 +- .../android/systemui/usb/UsbConfirmActivity.java | 143 +++++++++++++++++++++ .../systemui/usb/UsbPermissionActivity.java | 14 +- .../android/systemui/usb/UsbResolverActivity.java | 14 +- .../server/usb/UsbDeviceSettingsManager.java | 21 ++- services/jni/com_android_server_UsbService.cpp | 3 +- 15 files changed, 264 insertions(+), 40 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java index 41aed99..8938463 100644 --- a/core/java/android/hardware/usb/UsbAccessory.java +++ b/core/java/android/hardware/usb/UsbAccessory.java @@ -34,18 +34,20 @@ public class UsbAccessory implements Parcelable { private final String mDescription; private final String mVersion; private final String mUri; + private final String mSerial; /** * UsbAccessory should only be instantiated by UsbService implementation * @hide */ public UsbAccessory(String manufacturer, String model, String description, - String version, String uri) { + String version, String uri, String serial) { mManufacturer = manufacturer; mModel = model; mDescription = description; mVersion = version; mUri = uri; + mSerial = serial; } /** @@ -58,6 +60,7 @@ public class UsbAccessory implements Parcelable { mDescription = strings[2]; mVersion = strings[3]; mUri = strings[4]; + mSerial = strings[5]; } /** @@ -107,6 +110,17 @@ public class UsbAccessory implements Parcelable { return mUri; } + /** + * Returns the unique serial number for the accessory. + * This is an optional serial number that can be used to differentiate + * between individual accessories of the same model and manufacturer + * + * @return the unique serial number + */ + public String getSerial() { + return mSerial; + } + private static boolean compare(String s1, String s2) { if (s1 == null) return (s2 == null); return s1.equals(s2); @@ -120,7 +134,8 @@ public class UsbAccessory implements Parcelable { compare(mModel, accessory.getModel()) && compare(mDescription, accessory.getDescription()) && compare(mVersion, accessory.getVersion()) && - compare(mUri, accessory.getUri())); + compare(mUri, accessory.getUri()) && + compare(mSerial, accessory.getSerial())); } return false; } @@ -131,7 +146,8 @@ public class UsbAccessory implements Parcelable { (mModel == null ? 0 : mModel.hashCode()) ^ (mDescription == null ? 0 : mDescription.hashCode()) ^ (mVersion == null ? 0 : mVersion.hashCode()) ^ - (mUri == null ? 0 : mUri.hashCode())); + (mUri == null ? 0 : mUri.hashCode()) ^ + (mSerial == null ? 0 : mSerial.hashCode())); } @Override @@ -140,7 +156,8 @@ public class UsbAccessory implements Parcelable { ", mModel=" + mModel + ", mDescription=" + mDescription + ", mVersion=" + mVersion + - ", mUri=" + mUri + "]"; + ", mUri=" + mUri + + ", mSerial=" + mSerial + "]"; } public static final Parcelable.Creator CREATOR = @@ -151,7 +168,8 @@ public class UsbAccessory implements Parcelable { String description = in.readString(); String version = in.readString(); String uri = in.readString(); - return new UsbAccessory(manufacturer, model, description, version, uri); + String serial = in.readString(); + return new UsbAccessory(manufacturer, model, description, version, uri, serial); } public UsbAccessory[] newArray(int size) { @@ -169,5 +187,6 @@ public class UsbAccessory implements Parcelable { parcel.writeString(mDescription); parcel.writeString(mVersion); parcel.writeString(mUri); + parcel.writeString(mSerial); } } diff --git a/libs/usb/src/com/android/future/usb/UsbAccessory.java b/libs/usb/src/com/android/future/usb/UsbAccessory.java index 3d0707f..0f965d7 100644 --- a/libs/usb/src/com/android/future/usb/UsbAccessory.java +++ b/libs/usb/src/com/android/future/usb/UsbAccessory.java @@ -19,13 +19,14 @@ package com.android.future.usb; /** * A class representing a USB accessory. */ -public final class UsbAccessory { +public class UsbAccessory { private final String mManufacturer; private final String mModel; private final String mDescription; private final String mVersion; private final String mUri; + private final String mSerial; /* package */ UsbAccessory(android.hardware.usb.UsbAccessory accessory) { mManufacturer = accessory.getManufacturer(); @@ -33,6 +34,7 @@ public final class UsbAccessory { mDescription = accessory.getDescription(); mVersion = accessory.getVersion(); mUri = accessory.getUri(); + mSerial = accessory.getSerial(); } /** @@ -82,6 +84,17 @@ public final class UsbAccessory { return mUri; } + /** + * Returns the unique serial number for the accessory. + * This is an optional serial number that can be used to differentiate + * between individual accessories of the same model and manufacturer + * + * @return the unique serial number + */ + public String getSerial() { + return mSerial; + } + private static boolean compare(String s1, String s2) { if (s1 == null) return (s2 == null); return s1.equals(s2); @@ -95,7 +108,8 @@ public final class UsbAccessory { compare(mModel, accessory.getModel()) && compare(mDescription, accessory.getDescription()) && compare(mVersion, accessory.getVersion()) && - compare(mUri, accessory.getUri())); + compare(mUri, accessory.getUri()) && + compare(mSerial, accessory.getSerial())); } return false; } @@ -106,7 +120,8 @@ public final class UsbAccessory { (mModel == null ? 0 : mModel.hashCode()) ^ (mDescription == null ? 0 : mDescription.hashCode()) ^ (mVersion == null ? 0 : mVersion.hashCode()) ^ - (mUri == null ? 0 : mUri.hashCode())); + (mUri == null ? 0 : mUri.hashCode()) ^ + (mSerial == null ? 0 : mSerial.hashCode())); } @Override @@ -115,6 +130,7 @@ public final class UsbAccessory { ", mModel=" + mModel + ", mDescription=" + mDescription + ", mVersion=" + mVersion + - ", mUri=" + mUri + "]"; + ", mUri=" + mUri + + ", mSerial=" + mSerial + "]"; } } diff --git a/libs/usb/src/com/android/future/usb/UsbManager.java b/libs/usb/src/com/android/future/usb/UsbManager.java index 840e1e3..d424b63 100644 --- a/libs/usb/src/com/android/future/usb/UsbManager.java +++ b/libs/usb/src/com/android/future/usb/UsbManager.java @@ -130,7 +130,8 @@ public class UsbManager { try { return mService.openAccessory(new android.hardware.usb.UsbAccessory( accessory.getManufacturer(),accessory.getModel(), - accessory.getDescription(), accessory.getVersion(), accessory.getUri())); + accessory.getDescription(), accessory.getVersion(), + accessory.getUri(), accessory.getSerial())); } catch (RemoteException e) { Log.e(TAG, "RemoteException in openAccessory" , e); return null; @@ -150,7 +151,8 @@ public class UsbManager { try { return mService.hasAccessoryPermission(new android.hardware.usb.UsbAccessory( accessory.getManufacturer(),accessory.getModel(), - accessory.getDescription(), accessory.getVersion(), accessory.getUri())); + accessory.getDescription(), accessory.getVersion(), + accessory.getUri(), accessory.getSerial())); } catch (RemoteException e) { Log.e(TAG, "RemoteException in hasPermission", e); return false; @@ -174,7 +176,8 @@ public class UsbManager { try { mService.requestAccessoryPermission(new android.hardware.usb.UsbAccessory( accessory.getManufacturer(),accessory.getModel(), - accessory.getDescription(), accessory.getVersion(), accessory.getUri()), + accessory.getDescription(), accessory.getVersion(), + accessory.getUri(), accessory.getSerial()), mContext.getPackageName(), pi); } catch (RemoteException e) { Log.e(TAG, "RemoteException in requestPermission", e); diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk index d555961..77b8424 100644 --- a/libs/usb/tests/AccessoryChat/Android.mk +++ b/libs/usb/tests/AccessoryChat/Android.mk @@ -21,7 +21,7 @@ LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_PACKAGE_NAME := AccessoryChatGB +LOCAL_PACKAGE_NAME := AccessoryChat LOCAL_JAVA_LIBRARIES := com.android.future.usb.accessory diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml index d6093ae..802b715 100644 --- a/libs/usb/tests/AccessoryChat/AndroidManifest.xml +++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml @@ -17,10 +17,10 @@ - + - + diff --git a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c index 3c0de69..85b52dd 100644 --- a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c +++ b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -65,9 +66,20 @@ static void* write_thread(void* arg) { return NULL; } +static void milli_sleep(int millis) { + struct timespec tm; + + tm.tv_sec = 0; + tm.tv_nsec = millis * 1000000; + nanosleep(&tm, NULL); +} + static void send_string(struct usb_device *device, int index, const char* string) { int ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR, ACCESSORY_SEND_STRING, 0, index, (void *)string, strlen(string) + 1, 0); + + // some devices can't handle back-to-back requests, so delay a bit + milli_sleep(10); } static int usb_device_added(const char *devname, void* client_data) { @@ -143,9 +155,10 @@ static int usb_device_added(const char *devname, void* client_data) { send_string(device, ACCESSORY_STRING_MANUFACTURER, "Google, Inc."); send_string(device, ACCESSORY_STRING_MODEL, "AccessoryChat"); - send_string(device, ACCESSORY_STRING_DESCRIPTION, "Sample Program"); + send_string(device, ACCESSORY_STRING_DESCRIPTION, "Accessory Chat"); send_string(device, ACCESSORY_STRING_VERSION, "1.0"); send_string(device, ACCESSORY_STRING_URI, "http://www.android.com"); + send_string(device, ACCESSORY_STRING_SERIAL, "1234567890"); 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 f9a5bf4..c3f4fa3 100644 --- a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java +++ b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java @@ -135,7 +135,8 @@ public class AccessoryChat extends Activity implements Runnable, TextView.OnEdit } private void openAccessory(UsbAccessory accessory) { - mFileDescriptor = mUsbManager.openAccessory(accessory); + Log.d(TAG, "openAccessory: " + accessory); + mFileDescriptor = mUsbManager.openAccessory(accessory); if (mFileDescriptor != null) { FileDescriptor fd = mFileDescriptor.getFileDescriptor(); mInputStream = new FileInputStream(fd); diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 571729b..a979d65 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -27,6 +27,15 @@ + + + + Allow the application %1$s to access the USB accessory? + + Open %1$s when this USB device is connected? + + + Open %1$s when this USB accessory is connected? + - Additional information for this device may be found at: %1$s + Additional information for this USB accessory may be found at: %1$s USB accessory @@ -63,7 +69,7 @@ View - - Ignore + + Use by default for this USB accessory diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java index eefb1c6..5007cf4 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java @@ -76,7 +76,7 @@ public class UsbAccessoryUriActivity extends AlertActivity } ap.mMessage = getString(R.string.usb_accessory_uri_prompt, mUri); ap.mPositiveButtonText = getString(R.string.label_view); - ap.mNegativeButtonText = getString(R.string.label_ignore); + ap.mNegativeButtonText = getString(android.R.string.cancel); ap.mPositiveButtonListener = this; ap.mNegativeButtonListener = this; diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java new file mode 100644 index 0000000..148bcb4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.usb; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.ComponentName; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.hardware.usb.IUsbManager; +import android.hardware.usb.UsbAccessory; +import android.hardware.usb.UsbManager; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.TextView; + +import com.android.internal.app.AlertActivity; +import com.android.internal.app.AlertController; + +import com.android.systemui.R; + +public class UsbConfirmActivity extends AlertActivity + implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener { + + private static final String TAG = "UsbConfirmActivity"; + + private CheckBox mAlwaysUse; + private TextView mClearDefaultHint; + private UsbAccessory mAccessory; + private ResolveInfo mResolveInfo; + private boolean mPermissionGranted; + private UsbDisconnectedReceiver mDisconnectedReceiver; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + Intent intent = getIntent(); + mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); + mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory); + mResolveInfo = (ResolveInfo)intent.getParcelableExtra("rinfo"); + + PackageManager packageManager = getPackageManager(); + String appName = mResolveInfo.loadLabel(packageManager).toString(); + + final AlertController.AlertParams ap = mAlertParams; + ap.mIcon = mResolveInfo.loadIcon(packageManager); + ap.mTitle = appName; + ap.mMessage = getString(R.string.usb_accessory_confirm_prompt, appName); + ap.mPositiveButtonText = getString(android.R.string.ok); + ap.mNegativeButtonText = getString(android.R.string.cancel); + ap.mPositiveButtonListener = this; + ap.mNegativeButtonListener = this; + + // add "always use" checkbox + LayoutInflater inflater = (LayoutInflater)getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null); + mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse); + mAlwaysUse.setText(R.string.always_use_accessory); + mAlwaysUse.setOnCheckedChangeListener(this); + mClearDefaultHint = (TextView)ap.mView.findViewById( + com.android.internal.R.id.clearDefaultHint); + mClearDefaultHint.setVisibility(View.GONE); + + setupAlert(); + + } + + @Override + protected void onDestroy() { + if (mDisconnectedReceiver != null) { + unregisterReceiver(mDisconnectedReceiver); + } + super.onDestroy(); + } + + public void onClick(DialogInterface dialog, int which) { + if (which == AlertDialog.BUTTON_POSITIVE) { + try { + IBinder b = ServiceManager.getService(USB_SERVICE); + IUsbManager service = IUsbManager.Stub.asInterface(b); + int uid = mResolveInfo.activityInfo.applicationInfo.uid; + boolean alwaysUse = mAlwaysUse.isChecked(); + Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED); + intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setComponent( + new ComponentName(mResolveInfo.activityInfo.packageName, + mResolveInfo.activityInfo.name)); + + // grant permission for the accessory + service.grantAccessoryPermission(mAccessory, uid); + // set or clear default setting + if (alwaysUse) { + service.setAccessoryPackage(mAccessory, + mResolveInfo.activityInfo.packageName); + } else { + service.setAccessoryPackage(mAccessory, null); + } + startActivity(intent); + } catch (Exception e) { + Log.e(TAG, "Unable to start activity", e); + } + } + finish(); + } + + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (mClearDefaultHint == null) return; + + if(isChecked) { + mClearDefaultHint.setVisibility(View.VISIBLE); + } else { + mClearDefaultHint.setVisibility(View.GONE); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java index c017676..ec7c13a 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java @@ -48,7 +48,7 @@ public class UsbPermissionActivity extends AlertActivity private static final String TAG = "UsbPermissionActivity"; - private CheckBox mAlwaysCheck; + private CheckBox mAlwaysUse; private TextView mClearDefaultHint; private UsbAccessory mAccessory; private PendingIntent mPendingIntent; @@ -83,8 +83,8 @@ public class UsbPermissionActivity extends AlertActivity ap.mIcon = aInfo.loadIcon(packageManager); ap.mTitle = appName; ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName); - ap.mPositiveButtonText = getString(com.android.internal.R.string.ok); - ap.mNegativeButtonText = getString(com.android.internal.R.string.cancel); + ap.mPositiveButtonText = getString(android.R.string.ok); + ap.mNegativeButtonText = getString(android.R.string.cancel); ap.mPositiveButtonListener = this; ap.mNegativeButtonListener = this; @@ -92,9 +92,9 @@ public class UsbPermissionActivity extends AlertActivity LayoutInflater inflater = (LayoutInflater)getSystemService( Context.LAYOUT_INFLATER_SERVICE); ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null); - mAlwaysCheck = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse); - mAlwaysCheck.setText(com.android.internal.R.string.alwaysUse); - mAlwaysCheck.setOnCheckedChangeListener(this); + mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse); + mAlwaysUse.setText(R.string.always_use_accessory); + mAlwaysUse.setOnCheckedChangeListener(this); mClearDefaultHint = (TextView)ap.mView.findViewById( com.android.internal.R.id.clearDefaultHint); mClearDefaultHint.setVisibility(View.GONE); @@ -115,7 +115,7 @@ public class UsbPermissionActivity extends AlertActivity intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory); if (mPermissionGranted) { service.grantAccessoryPermission(mAccessory, mUid); - if (mAlwaysCheck.isChecked()) { + if (mAlwaysUse.isChecked()) { service.setAccessoryPackage(mAccessory, mPackageName); } } diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java index 2de56e5..082c839 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java @@ -30,6 +30,9 @@ import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; +import android.widget.CheckBox; + +import com.android.systemui.R; import java.util.ArrayList; @@ -54,11 +57,12 @@ public class UsbResolverActivity extends ResolverActivity { ArrayList rList = intent.getParcelableArrayListExtra(EXTRA_RESOLVE_INFOS); CharSequence title = getResources().getText(com.android.internal.R.string.chooseUsbActivity); super.onCreate(savedInstanceState, target, title, null, rList, - true, /* Set alwaysUseOption to true to enable "always use this app" checkbox. */ - true /* Set alwaysChoose to display activity when only one choice is available. - This is necessary because this activity is needed for the user to allow - the application permission to access the device */ - ); + true /* Set alwaysUseOption to true to enable "always use this app" checkbox. */ ); + + CheckBox alwaysUse = (CheckBox)findViewById(com.android.internal.R.id.alwaysUse); + if (alwaysUse != null) { + alwaysUse.setText(R.string.always_use_accessory); + } mAccessory = (UsbAccessory)target.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); if (mAccessory == null) { diff --git a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java index 8f6de2f..616bdca 100644 --- a/services/java/com/android/server/usb/UsbDeviceSettingsManager.java +++ b/services/java/com/android/server/usb/UsbDeviceSettingsManager.java @@ -430,17 +430,26 @@ class UsbDeviceSettingsManager { Log.e(TAG, "startActivity failed", e); } } else { - // start UsbResolverActivity so user can choose an activity Intent resolverIntent = new Intent(); - resolverIntent.setClassName("com.android.systemui", - "com.android.systemui.usb.UsbResolverActivity"); resolverIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - resolverIntent.putExtra(Intent.EXTRA_INTENT, intent); - resolverIntent.putParcelableArrayListExtra("rlist", matches); + + if (count == 1) { + // start UsbConfirmActivity if there is only one choice + resolverIntent.setClassName("com.android.systemui", + "com.android.systemui.usb.UsbConfirmActivity"); + resolverIntent.putExtra("rinfo", matches.get(0)); + resolverIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory); + } else { + // start UsbResolverActivity so user can choose an activity + resolverIntent.setClassName("com.android.systemui", + "com.android.systemui.usb.UsbResolverActivity"); + resolverIntent.putParcelableArrayListExtra("rlist", matches); + resolverIntent.putExtra(Intent.EXTRA_INTENT, intent); + } try { mContext.startActivity(resolverIntent); } catch (ActivityNotFoundException e) { - Log.e(TAG, "unable to start UsbResolverActivity"); + Log.e(TAG, "unable to start activity " + resolverIntent); } } } diff --git a/services/jni/com_android_server_UsbService.cpp b/services/jni/com_android_server_UsbService.cpp index 2ce0eaa..92c5008 100644 --- a/services/jni/com_android_server_UsbService.cpp +++ b/services/jni/com_android_server_UsbService.cpp @@ -78,13 +78,14 @@ static jobjectArray android_server_UsbService_getAccessoryStrings(JNIEnv *env, j return NULL; } jclass stringClass = env->FindClass("java/lang/String"); - jobjectArray strArray = env->NewObjectArray(5, stringClass, NULL); + jobjectArray strArray = env->NewObjectArray(6, stringClass, NULL); if (!strArray) goto out; set_accessory_string(env, fd, ACCESSORY_GET_STRING_MANUFACTURER, strArray, 0); set_accessory_string(env, fd, ACCESSORY_GET_STRING_MODEL, strArray, 1); set_accessory_string(env, fd, ACCESSORY_GET_STRING_DESCRIPTION, strArray, 2); set_accessory_string(env, fd, ACCESSORY_GET_STRING_VERSION, strArray, 3); set_accessory_string(env, fd, ACCESSORY_GET_STRING_URI, strArray, 4); + set_accessory_string(env, fd, ACCESSORY_GET_STRING_SERIAL, strArray, 5); out: close(fd); -- cgit v1.1