am b0976320
: Merge "DO NOT MERGE: Backport more USB accessory changes from honeycomb" into gingerbread
* commit 'b09763209980ff9210cc353f2410598220ec0480': DO NOT MERGE: Backport more USB accessory changes from honeycomb
This commit is contained in:
@ -34,18 +34,20 @@ public class UsbAccessory implements Parcelable {
|
|||||||
private final String mDescription;
|
private final String mDescription;
|
||||||
private final String mVersion;
|
private final String mVersion;
|
||||||
private final String mUri;
|
private final String mUri;
|
||||||
|
private final String mSerial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UsbAccessory should only be instantiated by UsbService implementation
|
* UsbAccessory should only be instantiated by UsbService implementation
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public UsbAccessory(String manufacturer, String model, String description,
|
public UsbAccessory(String manufacturer, String model, String description,
|
||||||
String version, String uri) {
|
String version, String uri, String serial) {
|
||||||
mManufacturer = manufacturer;
|
mManufacturer = manufacturer;
|
||||||
mModel = model;
|
mModel = model;
|
||||||
mDescription = description;
|
mDescription = description;
|
||||||
mVersion = version;
|
mVersion = version;
|
||||||
mUri = uri;
|
mUri = uri;
|
||||||
|
mSerial = serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,6 +60,7 @@ public class UsbAccessory implements Parcelable {
|
|||||||
mDescription = strings[2];
|
mDescription = strings[2];
|
||||||
mVersion = strings[3];
|
mVersion = strings[3];
|
||||||
mUri = strings[4];
|
mUri = strings[4];
|
||||||
|
mSerial = strings[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,6 +110,17 @@ public class UsbAccessory implements Parcelable {
|
|||||||
return mUri;
|
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) {
|
private static boolean compare(String s1, String s2) {
|
||||||
if (s1 == null) return (s2 == null);
|
if (s1 == null) return (s2 == null);
|
||||||
return s1.equals(s2);
|
return s1.equals(s2);
|
||||||
@ -120,7 +134,8 @@ public class UsbAccessory implements Parcelable {
|
|||||||
compare(mModel, accessory.getModel()) &&
|
compare(mModel, accessory.getModel()) &&
|
||||||
compare(mDescription, accessory.getDescription()) &&
|
compare(mDescription, accessory.getDescription()) &&
|
||||||
compare(mVersion, accessory.getVersion()) &&
|
compare(mVersion, accessory.getVersion()) &&
|
||||||
compare(mUri, accessory.getUri()));
|
compare(mUri, accessory.getUri()) &&
|
||||||
|
compare(mSerial, accessory.getSerial()));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -131,7 +146,8 @@ public class UsbAccessory implements Parcelable {
|
|||||||
(mModel == null ? 0 : mModel.hashCode()) ^
|
(mModel == null ? 0 : mModel.hashCode()) ^
|
||||||
(mDescription == null ? 0 : mDescription.hashCode()) ^
|
(mDescription == null ? 0 : mDescription.hashCode()) ^
|
||||||
(mVersion == null ? 0 : mVersion.hashCode()) ^
|
(mVersion == null ? 0 : mVersion.hashCode()) ^
|
||||||
(mUri == null ? 0 : mUri.hashCode()));
|
(mUri == null ? 0 : mUri.hashCode()) ^
|
||||||
|
(mSerial == null ? 0 : mSerial.hashCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -140,7 +156,8 @@ public class UsbAccessory implements Parcelable {
|
|||||||
", mModel=" + mModel +
|
", mModel=" + mModel +
|
||||||
", mDescription=" + mDescription +
|
", mDescription=" + mDescription +
|
||||||
", mVersion=" + mVersion +
|
", mVersion=" + mVersion +
|
||||||
", mUri=" + mUri + "]";
|
", mUri=" + mUri +
|
||||||
|
", mSerial=" + mSerial + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Parcelable.Creator<UsbAccessory> CREATOR =
|
public static final Parcelable.Creator<UsbAccessory> CREATOR =
|
||||||
@ -151,7 +168,8 @@ public class UsbAccessory implements Parcelable {
|
|||||||
String description = in.readString();
|
String description = in.readString();
|
||||||
String version = in.readString();
|
String version = in.readString();
|
||||||
String uri = 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) {
|
public UsbAccessory[] newArray(int size) {
|
||||||
@ -169,5 +187,6 @@ public class UsbAccessory implements Parcelable {
|
|||||||
parcel.writeString(mDescription);
|
parcel.writeString(mDescription);
|
||||||
parcel.writeString(mVersion);
|
parcel.writeString(mVersion);
|
||||||
parcel.writeString(mUri);
|
parcel.writeString(mUri);
|
||||||
|
parcel.writeString(mSerial);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,14 @@ package com.android.future.usb;
|
|||||||
/**
|
/**
|
||||||
* A class representing a USB accessory.
|
* A class representing a USB accessory.
|
||||||
*/
|
*/
|
||||||
public final class UsbAccessory {
|
public class UsbAccessory {
|
||||||
|
|
||||||
private final String mManufacturer;
|
private final String mManufacturer;
|
||||||
private final String mModel;
|
private final String mModel;
|
||||||
private final String mDescription;
|
private final String mDescription;
|
||||||
private final String mVersion;
|
private final String mVersion;
|
||||||
private final String mUri;
|
private final String mUri;
|
||||||
|
private final String mSerial;
|
||||||
|
|
||||||
/* package */ UsbAccessory(android.hardware.usb.UsbAccessory accessory) {
|
/* package */ UsbAccessory(android.hardware.usb.UsbAccessory accessory) {
|
||||||
mManufacturer = accessory.getManufacturer();
|
mManufacturer = accessory.getManufacturer();
|
||||||
@ -33,6 +34,7 @@ public final class UsbAccessory {
|
|||||||
mDescription = accessory.getDescription();
|
mDescription = accessory.getDescription();
|
||||||
mVersion = accessory.getVersion();
|
mVersion = accessory.getVersion();
|
||||||
mUri = accessory.getUri();
|
mUri = accessory.getUri();
|
||||||
|
mSerial = accessory.getSerial();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,6 +84,17 @@ public final class UsbAccessory {
|
|||||||
return mUri;
|
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) {
|
private static boolean compare(String s1, String s2) {
|
||||||
if (s1 == null) return (s2 == null);
|
if (s1 == null) return (s2 == null);
|
||||||
return s1.equals(s2);
|
return s1.equals(s2);
|
||||||
@ -95,7 +108,8 @@ public final class UsbAccessory {
|
|||||||
compare(mModel, accessory.getModel()) &&
|
compare(mModel, accessory.getModel()) &&
|
||||||
compare(mDescription, accessory.getDescription()) &&
|
compare(mDescription, accessory.getDescription()) &&
|
||||||
compare(mVersion, accessory.getVersion()) &&
|
compare(mVersion, accessory.getVersion()) &&
|
||||||
compare(mUri, accessory.getUri()));
|
compare(mUri, accessory.getUri()) &&
|
||||||
|
compare(mSerial, accessory.getSerial()));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -106,7 +120,8 @@ public final class UsbAccessory {
|
|||||||
(mModel == null ? 0 : mModel.hashCode()) ^
|
(mModel == null ? 0 : mModel.hashCode()) ^
|
||||||
(mDescription == null ? 0 : mDescription.hashCode()) ^
|
(mDescription == null ? 0 : mDescription.hashCode()) ^
|
||||||
(mVersion == null ? 0 : mVersion.hashCode()) ^
|
(mVersion == null ? 0 : mVersion.hashCode()) ^
|
||||||
(mUri == null ? 0 : mUri.hashCode()));
|
(mUri == null ? 0 : mUri.hashCode()) ^
|
||||||
|
(mSerial == null ? 0 : mSerial.hashCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -115,6 +130,7 @@ public final class UsbAccessory {
|
|||||||
", mModel=" + mModel +
|
", mModel=" + mModel +
|
||||||
", mDescription=" + mDescription +
|
", mDescription=" + mDescription +
|
||||||
", mVersion=" + mVersion +
|
", mVersion=" + mVersion +
|
||||||
", mUri=" + mUri + "]";
|
", mUri=" + mUri +
|
||||||
|
", mSerial=" + mSerial + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,8 @@ public class UsbManager {
|
|||||||
try {
|
try {
|
||||||
return mService.openAccessory(new android.hardware.usb.UsbAccessory(
|
return mService.openAccessory(new android.hardware.usb.UsbAccessory(
|
||||||
accessory.getManufacturer(),accessory.getModel(),
|
accessory.getManufacturer(),accessory.getModel(),
|
||||||
accessory.getDescription(), accessory.getVersion(), accessory.getUri()));
|
accessory.getDescription(), accessory.getVersion(),
|
||||||
|
accessory.getUri(), accessory.getSerial()));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "RemoteException in openAccessory" , e);
|
Log.e(TAG, "RemoteException in openAccessory" , e);
|
||||||
return null;
|
return null;
|
||||||
@ -150,7 +151,8 @@ public class UsbManager {
|
|||||||
try {
|
try {
|
||||||
return mService.hasAccessoryPermission(new android.hardware.usb.UsbAccessory(
|
return mService.hasAccessoryPermission(new android.hardware.usb.UsbAccessory(
|
||||||
accessory.getManufacturer(),accessory.getModel(),
|
accessory.getManufacturer(),accessory.getModel(),
|
||||||
accessory.getDescription(), accessory.getVersion(), accessory.getUri()));
|
accessory.getDescription(), accessory.getVersion(),
|
||||||
|
accessory.getUri(), accessory.getSerial()));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "RemoteException in hasPermission", e);
|
Log.e(TAG, "RemoteException in hasPermission", e);
|
||||||
return false;
|
return false;
|
||||||
@ -174,7 +176,8 @@ public class UsbManager {
|
|||||||
try {
|
try {
|
||||||
mService.requestAccessoryPermission(new android.hardware.usb.UsbAccessory(
|
mService.requestAccessoryPermission(new android.hardware.usb.UsbAccessory(
|
||||||
accessory.getManufacturer(),accessory.getModel(),
|
accessory.getManufacturer(),accessory.getModel(),
|
||||||
accessory.getDescription(), accessory.getVersion(), accessory.getUri()),
|
accessory.getDescription(), accessory.getVersion(),
|
||||||
|
accessory.getUri(), accessory.getSerial()),
|
||||||
mContext.getPackageName(), pi);
|
mContext.getPackageName(), pi);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "RemoteException in requestPermission", e);
|
Log.e(TAG, "RemoteException in requestPermission", e);
|
||||||
|
@ -21,7 +21,7 @@ LOCAL_MODULE_TAGS := tests
|
|||||||
|
|
||||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||||
|
|
||||||
LOCAL_PACKAGE_NAME := AccessoryChatGB
|
LOCAL_PACKAGE_NAME := AccessoryChat
|
||||||
|
|
||||||
LOCAL_JAVA_LIBRARIES := com.android.future.usb.accessory
|
LOCAL_JAVA_LIBRARIES := com.android.future.usb.accessory
|
||||||
|
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.android.accessorychat">
|
package="com.android.accessorychat">
|
||||||
|
|
||||||
<application>
|
<application android:label="Accessory Chat">
|
||||||
<uses-library android:name="com.android.future.usb.accessory" />
|
<uses-library android:name="com.android.future.usb.accessory" />
|
||||||
|
|
||||||
<activity android:name="AccessoryChat" android:label="Accessory Chat GB">
|
<activity android:name="AccessoryChat" android:label="Accessory Chat">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include <usbhost/usbhost.h>
|
#include <usbhost/usbhost.h>
|
||||||
#include <linux/usb/f_accessory.h>
|
#include <linux/usb/f_accessory.h>
|
||||||
@ -65,9 +66,20 @@ static void* write_thread(void* arg) {
|
|||||||
return NULL;
|
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) {
|
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,
|
int ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
|
||||||
ACCESSORY_SEND_STRING, 0, index, (void *)string, strlen(string) + 1, 0);
|
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) {
|
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_MANUFACTURER, "Google, Inc.");
|
||||||
send_string(device, ACCESSORY_STRING_MODEL, "AccessoryChat");
|
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_VERSION, "1.0");
|
||||||
send_string(device, ACCESSORY_STRING_URI, "http://www.android.com");
|
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,
|
ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
|
||||||
ACCESSORY_START, 0, 0, 0, 0, 0);
|
ACCESSORY_START, 0, 0, 0, 0, 0);
|
||||||
|
@ -135,6 +135,7 @@ public class AccessoryChat extends Activity implements Runnable, TextView.OnEdit
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void openAccessory(UsbAccessory accessory) {
|
private void openAccessory(UsbAccessory accessory) {
|
||||||
|
Log.d(TAG, "openAccessory: " + accessory);
|
||||||
mFileDescriptor = mUsbManager.openAccessory(accessory);
|
mFileDescriptor = mUsbManager.openAccessory(accessory);
|
||||||
if (mFileDescriptor != null) {
|
if (mFileDescriptor != null) {
|
||||||
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
|
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
|
||||||
|
@ -26,6 +26,15 @@
|
|||||||
android:excludeFromRecents="true">
|
android:excludeFromRecents="true">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<!-- started from UsbDeviceSettingsManager -->
|
||||||
|
<activity android:name=".usb.UsbConfirmActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:permission="android.permission.MANAGE_USB"
|
||||||
|
android:theme="@*android:style/Theme.Dialog.Alert"
|
||||||
|
android:finishOnCloseSystemDialogs="true"
|
||||||
|
android:excludeFromRecents="true">
|
||||||
|
</activity>
|
||||||
|
|
||||||
<!-- started from UsbDeviceSettingsManager -->
|
<!-- started from UsbDeviceSettingsManager -->
|
||||||
<activity android:name=".usb.UsbPermissionActivity"
|
<activity android:name=".usb.UsbPermissionActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
@ -54,8 +54,14 @@
|
|||||||
<!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] -->
|
<!-- 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>
|
<string name="usb_accessory_permission_prompt">Allow the application %1$s to access the USB accessory?</string>
|
||||||
|
|
||||||
|
<!-- Prompt for the USB device confirm dialog [CHAR LIMIT=80] -->
|
||||||
|
<string name="usb_device_confirm_prompt">Open %1$s when this USB device is connected?</string>
|
||||||
|
|
||||||
|
<!-- Prompt for the USB accessory confirm dialog [CHAR LIMIT=80] -->
|
||||||
|
<string name="usb_accessory_confirm_prompt">Open %1$s when this USB accessory is connected?</string>
|
||||||
|
|
||||||
<!-- Prompt for the USB accessory URI dialog [CHAR LIMIT=80] -->
|
<!-- 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>
|
<string name="usb_accessory_uri_prompt">Additional information for this USB accessory 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] -->
|
<!-- 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>
|
<string name="title_usb_accessory">USB accessory</string>
|
||||||
@ -63,7 +69,7 @@
|
|||||||
<!-- View button label for USB dialogs. [CHAR LIMIT=15] -->
|
<!-- View button label for USB dialogs. [CHAR LIMIT=15] -->
|
||||||
<string name="label_view">View</string>
|
<string name="label_view">View</string>
|
||||||
|
|
||||||
<!-- Ignore button label for USB dialogs. [CHAR LIMIT=15] -->
|
<!-- Checkbox label for USB accessory dialogs. [CHAR LIMIT=50] -->
|
||||||
<string name="label_ignore">Ignore</string>
|
<string name="always_use_accessory">Use by default for this USB accessory</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -76,7 +76,7 @@ public class UsbAccessoryUriActivity extends AlertActivity
|
|||||||
}
|
}
|
||||||
ap.mMessage = getString(R.string.usb_accessory_uri_prompt, mUri);
|
ap.mMessage = getString(R.string.usb_accessory_uri_prompt, mUri);
|
||||||
ap.mPositiveButtonText = getString(R.string.label_view);
|
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.mPositiveButtonListener = this;
|
||||||
ap.mNegativeButtonListener = this;
|
ap.mNegativeButtonListener = this;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -48,7 +48,7 @@ public class UsbPermissionActivity extends AlertActivity
|
|||||||
|
|
||||||
private static final String TAG = "UsbPermissionActivity";
|
private static final String TAG = "UsbPermissionActivity";
|
||||||
|
|
||||||
private CheckBox mAlwaysCheck;
|
private CheckBox mAlwaysUse;
|
||||||
private TextView mClearDefaultHint;
|
private TextView mClearDefaultHint;
|
||||||
private UsbAccessory mAccessory;
|
private UsbAccessory mAccessory;
|
||||||
private PendingIntent mPendingIntent;
|
private PendingIntent mPendingIntent;
|
||||||
@ -83,8 +83,8 @@ public class UsbPermissionActivity extends AlertActivity
|
|||||||
ap.mIcon = aInfo.loadIcon(packageManager);
|
ap.mIcon = aInfo.loadIcon(packageManager);
|
||||||
ap.mTitle = appName;
|
ap.mTitle = appName;
|
||||||
ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName);
|
ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName);
|
||||||
ap.mPositiveButtonText = getString(com.android.internal.R.string.ok);
|
ap.mPositiveButtonText = getString(android.R.string.ok);
|
||||||
ap.mNegativeButtonText = getString(com.android.internal.R.string.cancel);
|
ap.mNegativeButtonText = getString(android.R.string.cancel);
|
||||||
ap.mPositiveButtonListener = this;
|
ap.mPositiveButtonListener = this;
|
||||||
ap.mNegativeButtonListener = this;
|
ap.mNegativeButtonListener = this;
|
||||||
|
|
||||||
@ -92,9 +92,9 @@ public class UsbPermissionActivity extends AlertActivity
|
|||||||
LayoutInflater inflater = (LayoutInflater)getSystemService(
|
LayoutInflater inflater = (LayoutInflater)getSystemService(
|
||||||
Context.LAYOUT_INFLATER_SERVICE);
|
Context.LAYOUT_INFLATER_SERVICE);
|
||||||
ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
|
ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
|
||||||
mAlwaysCheck = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
|
mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
|
||||||
mAlwaysCheck.setText(com.android.internal.R.string.alwaysUse);
|
mAlwaysUse.setText(R.string.always_use_accessory);
|
||||||
mAlwaysCheck.setOnCheckedChangeListener(this);
|
mAlwaysUse.setOnCheckedChangeListener(this);
|
||||||
mClearDefaultHint = (TextView)ap.mView.findViewById(
|
mClearDefaultHint = (TextView)ap.mView.findViewById(
|
||||||
com.android.internal.R.id.clearDefaultHint);
|
com.android.internal.R.id.clearDefaultHint);
|
||||||
mClearDefaultHint.setVisibility(View.GONE);
|
mClearDefaultHint.setVisibility(View.GONE);
|
||||||
@ -115,7 +115,7 @@ public class UsbPermissionActivity extends AlertActivity
|
|||||||
intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
|
intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
|
||||||
if (mPermissionGranted) {
|
if (mPermissionGranted) {
|
||||||
service.grantAccessoryPermission(mAccessory, mUid);
|
service.grantAccessoryPermission(mAccessory, mUid);
|
||||||
if (mAlwaysCheck.isChecked()) {
|
if (mAlwaysUse.isChecked()) {
|
||||||
service.setAccessoryPackage(mAccessory, mPackageName);
|
service.setAccessoryPackage(mAccessory, mPackageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,9 @@ import android.os.Parcelable;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
|
||||||
|
import com.android.systemui.R;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -54,11 +57,12 @@ public class UsbResolverActivity extends ResolverActivity {
|
|||||||
ArrayList<ResolveInfo> rList = intent.getParcelableArrayListExtra(EXTRA_RESOLVE_INFOS);
|
ArrayList<ResolveInfo> rList = intent.getParcelableArrayListExtra(EXTRA_RESOLVE_INFOS);
|
||||||
CharSequence title = getResources().getText(com.android.internal.R.string.chooseUsbActivity);
|
CharSequence title = getResources().getText(com.android.internal.R.string.chooseUsbActivity);
|
||||||
super.onCreate(savedInstanceState, target, title, null, rList,
|
super.onCreate(savedInstanceState, target, title, null, rList,
|
||||||
true, /* Set alwaysUseOption to true to enable "always use this app" checkbox. */
|
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
|
CheckBox alwaysUse = (CheckBox)findViewById(com.android.internal.R.id.alwaysUse);
|
||||||
the application permission to access the device */
|
if (alwaysUse != null) {
|
||||||
);
|
alwaysUse.setText(R.string.always_use_accessory);
|
||||||
|
}
|
||||||
|
|
||||||
mAccessory = (UsbAccessory)target.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
|
mAccessory = (UsbAccessory)target.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
|
||||||
if (mAccessory == null) {
|
if (mAccessory == null) {
|
||||||
|
@ -430,17 +430,26 @@ class UsbDeviceSettingsManager {
|
|||||||
Log.e(TAG, "startActivity failed", e);
|
Log.e(TAG, "startActivity failed", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// start UsbResolverActivity so user can choose an activity
|
|
||||||
Intent resolverIntent = new Intent();
|
Intent resolverIntent = new Intent();
|
||||||
|
resolverIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
|
||||||
|
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",
|
resolverIntent.setClassName("com.android.systemui",
|
||||||
"com.android.systemui.usb.UsbResolverActivity");
|
"com.android.systemui.usb.UsbResolverActivity");
|
||||||
resolverIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
resolverIntent.putExtra(Intent.EXTRA_INTENT, intent);
|
|
||||||
resolverIntent.putParcelableArrayListExtra("rlist", matches);
|
resolverIntent.putParcelableArrayListExtra("rlist", matches);
|
||||||
|
resolverIntent.putExtra(Intent.EXTRA_INTENT, intent);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
mContext.startActivity(resolverIntent);
|
mContext.startActivity(resolverIntent);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Log.e(TAG, "unable to start UsbResolverActivity");
|
Log.e(TAG, "unable to start activity " + resolverIntent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,13 +78,14 @@ static jobjectArray android_server_UsbService_getAccessoryStrings(JNIEnv *env, j
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
jclass stringClass = env->FindClass("java/lang/String");
|
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;
|
if (!strArray) goto out;
|
||||||
set_accessory_string(env, fd, ACCESSORY_GET_STRING_MANUFACTURER, strArray, 0);
|
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_MODEL, strArray, 1);
|
||||||
set_accessory_string(env, fd, ACCESSORY_GET_STRING_DESCRIPTION, strArray, 2);
|
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_VERSION, strArray, 3);
|
||||||
set_accessory_string(env, fd, ACCESSORY_GET_STRING_URI, strArray, 4);
|
set_accessory_string(env, fd, ACCESSORY_GET_STRING_URI, strArray, 4);
|
||||||
|
set_accessory_string(env, fd, ACCESSORY_GET_STRING_SERIAL, strArray, 5);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close(fd);
|
close(fd);
|
||||||
|
Reference in New Issue
Block a user