Support for USB accessory URIs

If a USB accessory is attached and we have no application that supports it,
display a dialog offering the user the option to visit the accessory's website
if the accessory has a URI.

Bug: 4073248

Change-Id: I30e2a802493fb6e203532a7f79402379c40bc3b8
Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
Mike Lockwood
2011-03-10 12:12:31 -05:00
parent 0837fde9fd
commit 024b4f1494
4 changed files with 145 additions and 5 deletions

View File

@ -57,5 +57,14 @@
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true">
</activity>
<!-- started from UsbDeviceSettingsManager -->
<activity android:name=".usb.UsbAccessoryUriActivity"
android:exported="true"
android:permission="android.permission.MANAGE_USB"
android:theme="@*android:style/Theme.Holo.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true">
</activity>
</application>
</manifest>

View File

@ -122,4 +122,16 @@
<!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] -->
<string name="usb_accessory_permission_prompt">Allow the application %1$s to access the USB accessory?</string>
<!-- Prompt for the USB accessory URI dialog [CHAR LIMIT=80] -->
<string name="usb_accessory_uri_prompt">Additional information for this device may be found at: %1$s</string>
<!-- Title for USB accessory dialog. Used when the name of the accessory cannot be determined. [CHAR LIMIT=50] -->
<string name="title_usb_accessory">USB accessory</string>
<!-- View button label for USB dialogs. [CHAR LIMIT=15] -->
<string name="label_view">View</string>
<!-- Ignore button label for USB dialogs. [CHAR LIMIT=15] -->
<string name="label_ignore">Ignore</string>
</resources>

View File

@ -0,0 +1,100 @@
/*
* 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.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.util.Log;
import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;
import com.android.systemui.R;
/**
* If the attached USB accessory has a URL associated with it, and that URL is valid,
* show this dialog to the user to allow them to optionally visit that URL for more
* information or software downloads.
* Otherwise (no valid URL) this activity does nothing at all, finishing immediately.
*/
public class UsbAccessoryUriActivity extends AlertActivity
implements DialogInterface.OnClickListener {
private static final String TAG = "UsbAccessoryUriActivity";
private UsbAccessory mAccessory;
private Uri mUri;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Intent intent = getIntent();
mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
String uriString = intent.getStringExtra("uri");
mUri = (uriString == null ? null : Uri.parse(uriString));
// sanity check before displaying dialog
if (mUri == null) {
Log.e(TAG, "could not parse Uri " + uriString);
finish();
return;
}
String scheme = mUri.getScheme();
if (!"http".equals(scheme) && !"https".equals(scheme)) {
Log.e(TAG, "Uri not http or https: " + mUri);
finish();
return;
}
final AlertController.AlertParams ap = mAlertParams;
ap.mTitle = mAccessory.getDescription();
if (ap.mTitle == null || ap.mTitle.length() == 0) {
ap.mTitle = getString(R.string.title_usb_accessory);
}
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.mPositiveButtonListener = this;
ap.mNegativeButtonListener = this;
setupAlert();
}
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) {
// launch the browser
Intent intent = new Intent(Intent.ACTION_VIEW, mUri);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "startActivity failed for " + mUri);
}
}
finish();
}
}

View File

@ -568,8 +568,31 @@ class UsbDeviceSettingsManager {
private void resolveActivity(Intent intent, ArrayList<ResolveInfo> matches,
String defaultPackage, UsbDevice device, UsbAccessory accessory) {
int count = matches.size();
// don't show the resolver activity if there are no choices available
if (count == 0) return;
if (count == 0) {
if (accessory != null) {
String uri = accessory.getUri();
if (uri != null && uri.length() > 0) {
// display URI to user
// start UsbResolverActivity so user can choose an activity
Intent dialogIntent = new Intent();
dialogIntent.setClassName("com.android.systemui",
"com.android.systemui.usb.UsbAccessoryUriActivity");
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialogIntent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
dialogIntent.putExtra("uri", uri);
try {
mContext.startActivity(dialogIntent);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "unable to start UsbAccessoryUriActivity");
}
}
}
// do nothing
return;
}
ResolveInfo defaultRI = null;
if (count == 1 && defaultPackage == null) {
@ -613,8 +636,6 @@ class UsbDeviceSettingsManager {
Log.e(TAG, "startActivity failed", e);
}
} else {
long identity = Binder.clearCallingIdentity();
// start UsbResolverActivity so user can choose an activity
Intent resolverIntent = new Intent();
resolverIntent.setClassName("com.android.systemui",
@ -626,8 +647,6 @@ class UsbDeviceSettingsManager {
mContext.startActivity(resolverIntent);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "unable to start UsbResolverActivity");
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}