summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul McLean <pmclean@google.com>2019-09-23 08:28:41 -0600
committerPaul McLean <pmclean@google.com>2019-10-03 11:54:05 -0600
commitd33645321723b04823ba03c4ce1d10b0ef56e6a5 (patch)
tree16160bef3a1f823fc27ccc423b7f39bd75001c03
parent4252183449824d77f5c4035e8c12bf504619a5b1 (diff)
Adding additional prompt to UsbPermissionsDialg for audio devices.
To support, adding members to UsbDevice to mark devices as having audio playback and audio capture capabilities. Bug: 136080195 Test: Run "UsbAccess" test bed. Connect audio and non-audio USB devices and see the additional prompt shown/not-shown. Change-Id: Ie7c614d9ed30a163c350b18a54b8a9115698779d
-rw-r--r--core/java/android/hardware/usb/UsbDevice.java52
-rw-r--r--packages/SystemUI/res/values/strings.xml7
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java18
-rw-r--r--services/usb/java/com/android/server/usb/UsbHostManager.java2
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java39
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java7
6 files changed, 101 insertions, 24 deletions
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 08c9eea6e012..43336682e45f 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -60,6 +60,9 @@ public class UsbDevice implements Parcelable {
private final int mClass;
private final int mSubclass;
private final int mProtocol;
+ private final boolean mHasAudioPlayback;
+ private final boolean mHasAudioCapture;
+
/** All interfaces on the device. Initialized on first call to getInterfaceList */
@UnsupportedAppUsage
@@ -73,7 +76,8 @@ public class UsbDevice implements Parcelable {
private UsbDevice(@NonNull String name, int vendorId, int productId, int Class, int subClass,
int protocol, @Nullable String manufacturerName, @Nullable String productName,
@NonNull String version, @NonNull UsbConfiguration[] configurations,
- @NonNull IUsbSerialReader serialNumberReader) {
+ @NonNull IUsbSerialReader serialNumberReader,
+ boolean hasAudioPlayback, boolean hasAudioCapture) {
mName = Preconditions.checkNotNull(name);
mVendorId = vendorId;
mProductId = productId;
@@ -85,6 +89,8 @@ public class UsbDevice implements Parcelable {
mVersion = Preconditions.checkStringNotEmpty(version);
mConfigurations = Preconditions.checkArrayElementsNotNull(configurations, "configurations");
mSerialNumberReader = Preconditions.checkNotNull(serialNumberReader);
+ mHasAudioPlayback = hasAudioPlayback;
+ mHasAudioCapture = hasAudioCapture;
// Make sure the binder belongs to the system
if (ActivityThread.isSystem()) {
@@ -214,6 +220,16 @@ public class UsbDevice implements Parcelable {
return mConfigurations.length;
}
+ /** @hide */
+ public boolean getHasAudioPlayback() {
+ return mHasAudioPlayback;
+ }
+
+ /** @hide */
+ public boolean getHasAudioCapture() {
+ return mHasAudioCapture;
+ }
+
/**
* Returns the {@link UsbConfiguration} at the given index.
*
@@ -286,12 +302,14 @@ public class UsbDevice implements Parcelable {
@Override
public String toString() {
- StringBuilder builder = new StringBuilder("UsbDevice[mName=" + mName +
- ",mVendorId=" + mVendorId + ",mProductId=" + mProductId +
- ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
- ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName +
- ",mVersion=" + mVersion + ",mSerialNumberReader=" + mSerialNumberReader
- + ",mConfigurations=[");
+ StringBuilder builder = new StringBuilder("UsbDevice[mName=" + mName
+ + ",mVendorId=" + mVendorId + ",mProductId=" + mProductId
+ + ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol
+ + ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName
+ + ",mVersion=" + mVersion + ",mSerialNumberReader=" + mSerialNumberReader
+ + ", mHasAudioPlayback=" + mHasAudioPlayback
+ + ", mHasAudioCapture=" + mHasAudioCapture
+ + ", mConfigurations=[");
for (int i = 0; i < mConfigurations.length; i++) {
builder.append("\n");
builder.append(mConfigurations[i].toString());
@@ -316,9 +334,13 @@ public class UsbDevice implements Parcelable {
IUsbSerialReader.Stub.asInterface(in.readStrongBinder());
UsbConfiguration[] configurations = in.readParcelableArray(
UsbConfiguration.class.getClassLoader(), UsbConfiguration.class);
+ // Capabilities
+ boolean hasAudioPlayback = in.readInt() == 1;
+ boolean hasAudioCapture = in.readInt() == 1;
UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
- manufacturerName, productName, version, configurations,
- serialNumberReader);
+ manufacturerName, productName, version, configurations, serialNumberReader,
+ hasAudioPlayback, hasAudioCapture);
+
return device;
}
@@ -343,6 +365,8 @@ public class UsbDevice implements Parcelable {
parcel.writeString(mVersion);
parcel.writeStrongBinder(mSerialNumberReader.asBinder());
parcel.writeParcelableArray(mConfigurations, 0);
+ parcel.writeInt(mHasAudioPlayback ? 1 : 0);
+ parcel.writeInt(mHasAudioCapture ? 1 : 0);
}
public static int getDeviceId(String name) {
@@ -370,6 +394,8 @@ public class UsbDevice implements Parcelable {
private final @Nullable String mProductName;
private final @NonNull String mVersion;
private final @NonNull UsbConfiguration[] mConfigurations;
+ private final boolean mHasAudioPlayback;
+ private final boolean mHasAudioCapture;
// Temporary storage for serial number. Serial number reader need to be wrapped in a
// IUsbSerialReader as they might be used as PII.
@@ -378,7 +404,8 @@ public class UsbDevice implements Parcelable {
public Builder(@NonNull String name, int vendorId, int productId, int Class, int subClass,
int protocol, @Nullable String manufacturerName, @Nullable String productName,
@NonNull String version, @NonNull UsbConfiguration[] configurations,
- @Nullable String serialNumber) {
+ @Nullable String serialNumber,
+ boolean hasAudioPlayback, boolean hasAudioCapture) {
mName = Preconditions.checkNotNull(name);
mVendorId = vendorId;
mProductId = productId;
@@ -390,6 +417,8 @@ public class UsbDevice implements Parcelable {
mVersion = Preconditions.checkStringNotEmpty(version);
mConfigurations = configurations;
this.serialNumber = serialNumber;
+ mHasAudioPlayback = hasAudioPlayback;
+ mHasAudioCapture = hasAudioCapture;
}
/**
@@ -401,7 +430,8 @@ public class UsbDevice implements Parcelable {
*/
public UsbDevice build(@NonNull IUsbSerialReader serialReader) {
return new UsbDevice(mName, mVendorId, mProductId, mClass, mSubclass, mProtocol,
- mManufacturerName, mProductName, mVersion, mConfigurations, serialReader);
+ mManufacturerName, mProductName, mVersion, mConfigurations, serialReader,
+ mHasAudioPlayback, mHasAudioCapture);
}
}
}
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 97e2f0f6562b..0be84eec7149 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -118,10 +118,13 @@
<string name="status_bar_use_physical_keyboard">Physical keyboard</string>
<!-- Prompt for the USB device permission dialog [CHAR LIMIT=80] -->
- <string name="usb_device_permission_prompt">Allow <xliff:g id="application">%1$s</xliff:g> to access <xliff:g id="usb_device">%2$s</xliff:g>?</string>
+ <string name="usb_device_permission_prompt">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?</string>
+
+ <!-- Checkbox label for USB device dialogs with warning text for USB device dialogs. [CHAR LIMIT=200]-->
+ <string name="usb_device_permission_prompt_warn">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device.</string>
<!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] -->
- <string name="usb_accessory_permission_prompt">Allow <xliff:g id="application">%1$s</xliff:g> to access <xliff:g id="usb_accessory">%2$s</xliff:g>?</string>
+ <string name="usb_accessory_permission_prompt">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_accessory" example="USB Dock">%2$s</xliff:g>?</string>
<!-- Prompt for the USB device confirm dialog [CHAR LIMIT=80] -->
<string name="usb_device_confirm_prompt">Open <xliff:g id="application">%1$s</xliff:g> to handle <xliff:g id="usb_device">%2$s</xliff:g>?</string>
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
index a46f018af816..cd1f0cc13297 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -21,6 +21,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.hardware.usb.IUsbManager;
@@ -84,14 +85,27 @@ public class UsbPermissionActivity extends AlertActivity
final AlertController.AlertParams ap = mAlertParams;
ap.mTitle = appName;
if (mDevice == null) {
+ // Accessory Case
+
ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName,
mAccessory.getDescription());
mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
} else {
- ap.mMessage = getString(R.string.usb_device_permission_prompt, appName,
- mDevice.getProductName());
+ boolean hasRecordPermission =
+ PermissionChecker.checkPermission(
+ this, android.Manifest.permission.RECORD_AUDIO, -1, aInfo.uid,
+ mPackageName)
+ == android.content.pm.PackageManager.PERMISSION_GRANTED;
+ boolean isAudioCaptureDevice = mDevice.getHasAudioCapture();
+ boolean useRecordWarning = isAudioCaptureDevice && !hasRecordPermission;
+
+ int strID = useRecordWarning
+ ? R.string.usb_device_permission_prompt_warn
+ : R.string.usb_device_permission_prompt;
+ ap.mMessage = getString(strID, appName, mDevice.getProductName());
mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
}
+
ap.mPositiveButtonText = getString(android.R.string.ok);
ap.mNegativeButtonText = getString(android.R.string.cancel);
ap.mPositiveButtonListener = this;
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index e899dff5e5a2..047fcecd5a5b 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -386,7 +386,7 @@ public class UsbHostManager {
return false;
}
- UsbDevice.Builder newDeviceBuilder = parser.toAndroidUsbDevice();
+ UsbDevice.Builder newDeviceBuilder = parser.toAndroidUsbDeviceBuilder();
if (newDeviceBuilder == null) {
Slog.e(TAG, "Couldn't create UsbDevice object.");
// Tracking
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index 6ffbd43a7b1a..8e7babb40fc0 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -309,17 +309,17 @@ public final class UsbDescriptorParser {
/**
* @hide
*/
- public UsbDevice.Builder toAndroidUsbDevice() {
+ public UsbDevice.Builder toAndroidUsbDeviceBuilder() {
if (mDeviceDescriptor == null) {
Log.e(TAG, "toAndroidUsbDevice() ERROR - No Device Descriptor");
return null;
}
- UsbDevice.Builder device = mDeviceDescriptor.toAndroid(this);
- if (device == null) {
+ UsbDevice.Builder builder = mDeviceDescriptor.toAndroid(this);
+ if (builder == null) {
Log.e(TAG, "toAndroidUsbDevice() ERROR Creating Device");
}
- return device;
+ return builder;
}
/**
@@ -524,6 +524,37 @@ public final class UsbDescriptorParser {
/**
* @hide
*/
+ public boolean hasAudioTerminal(int subType) {
+ for (UsbDescriptor descriptor : mDescriptors) {
+ if (descriptor instanceof UsbACInterface) {
+ if (((UsbACInterface) descriptor).getSubclass()
+ == UsbDescriptor.AUDIO_AUDIOCONTROL
+ && ((UsbACInterface) descriptor).getSubtype()
+ == subType) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @hide
+ */
+ public boolean hasAudioPlayback() {
+ return hasAudioTerminal(UsbACInterface.ACI_OUTPUT_TERMINAL);
+ }
+
+ /**
+ * @hide
+ */
+ public boolean hasAudioCapture() {
+ return hasAudioTerminal(UsbACInterface.ACI_INPUT_TERMINAL);
+ }
+
+ /**
+ * @hide
+ */
public boolean hasHIDInterface() {
ArrayList<UsbDescriptor> descriptors =
getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_HID);
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
index e6e10fef9f9a..9735502a4f69 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
@@ -156,11 +156,10 @@ public final class UsbDeviceDescriptor extends UsbDescriptor {
for (int index = 0; index < mConfigDescriptors.size(); index++) {
configs[index] = mConfigDescriptors.get(index).toAndroid(parser);
}
- UsbDevice.Builder device = new UsbDevice.Builder(parser.getDeviceAddr(), mVendorID,
- mProductID, mDevClass, mDevSubClass, mProtocol, mfgName, prodName, versionString,
- configs, serialStr);
- return device;
+ return new UsbDevice.Builder(parser.getDeviceAddr(), mVendorID,
+ mProductID, mDevClass, mDevSubClass, mProtocol, mfgName, prodName, versionString,
+ configs, serialStr, parser.hasAudioPlayback(), parser.hasAudioCapture());
}
@Override