diff options
12 files changed, 387 insertions, 82 deletions
diff --git a/Android.bp b/Android.bp index 2ab91a1503e8..bfd961ea8d1c 100644 --- a/Android.bp +++ b/Android.bp @@ -194,6 +194,7 @@ java_defaults { "core/java/android/hardware/radio/ITunerCallback.aidl", "core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl", "core/java/android/hardware/usb/IUsbManager.aidl", + "core/java/android/hardware/usb/IUsbSerialReader.aidl", "core/java/android/net/ICaptivePortal.aidl", "core/java/android/net/IConnectivityManager.aidl", "core/java/android/net/IIpConnectivityMetrics.aidl", diff --git a/core/java/android/hardware/usb/IUsbSerialReader.aidl b/core/java/android/hardware/usb/IUsbSerialReader.aidl new file mode 100644 index 000000000000..787d5cdf8281 --- /dev/null +++ b/core/java/android/hardware/usb/IUsbSerialReader.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2018 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 android.hardware.usb; + +/** @hide */ +interface IUsbSerialReader +{ + /* Returns a serial for the accessory/device */ + String getSerial(String packageName); +} diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java index 4aeb40c167a0..b418d43d1990 100644 --- a/core/java/android/hardware/usb/UsbAccessory.java +++ b/core/java/android/hardware/usb/UsbAccessory.java @@ -18,8 +18,11 @@ package android.hardware.usb; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityThread; import android.os.Parcel; import android.os.Parcelable; +import android.os.RemoteException; + import com.android.internal.util.Preconditions; /** @@ -54,7 +57,7 @@ public class UsbAccessory implements Parcelable { private final @Nullable String mDescription; private final @Nullable String mVersion; private final @Nullable String mUri; - private final @Nullable String mSerial; + private final @NonNull IUsbSerialReader mSerialNumberReader; /** @hide */ public static final int MANUFACTURER_STRING = 0; @@ -75,22 +78,38 @@ public class UsbAccessory implements Parcelable { */ public UsbAccessory(@NonNull String manufacturer, @NonNull String model, @Nullable String description, @Nullable String version, @Nullable String uri, - @Nullable String serial) { + @NonNull IUsbSerialReader serialNumberReader) { mManufacturer = Preconditions.checkNotNull(manufacturer); mModel = Preconditions.checkNotNull(model); mDescription = description; mVersion = version; mUri = uri; - mSerial = serial; + mSerialNumberReader = serialNumberReader; + + // Make sure the binder belongs to the system + if (ActivityThread.isSystem()) { + Preconditions.checkArgument(mSerialNumberReader instanceof IUsbSerialReader.Stub); + } } /** - * UsbAccessory should only be instantiated by UsbService implementation + * DO NOT USE. Only for backwards compatibility with + * {@link com.android.future.usb.UsbAccessory}. + * * @hide + * @deprecated use {@link UsbAccessory#UsbAccessory(String, String, String, String, String, + * IUsbSerialReader) instead} */ - public UsbAccessory(String[] strings) { - this(strings[MANUFACTURER_STRING], strings[MODEL_STRING], strings[DESCRIPTION_STRING], - strings[VERSION_STRING], strings[URI_STRING], strings[SERIAL_STRING]); + @Deprecated + public UsbAccessory(@NonNull String manufacturer, @NonNull String model, + @Nullable String description, @Nullable String version, @Nullable String uri, + @Nullable String serialNumber) { + this(manufacturer, model, description, version, uri, new IUsbSerialReader.Stub() { + @Override + public String getSerial(String packageName) { + return serialNumber; + } + }); } /** @@ -146,9 +165,17 @@ public class UsbAccessory implements Parcelable { * between individual accessories of the same model and manufacturer * * @return the unique serial number, or {@code null} if not set + * + * @throws SecurityException if the app targets SDK >= {@value android.os.Build.VERSION_CODES#Q} + * and the app does not have permission to read from the accessory. */ public @Nullable String getSerial() { - return mSerial; + try { + return mSerialNumberReader.getSerial(ActivityThread.currentPackageName()); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return null; + } } private static boolean compare(String s1, String s2) { @@ -165,7 +192,7 @@ public class UsbAccessory implements Parcelable { compare(mDescription, accessory.getDescription()) && compare(mVersion, accessory.getVersion()) && compare(mUri, accessory.getUri()) && - compare(mSerial, accessory.getSerial())); + compare(getSerial(), accessory.getSerial())); } return false; } @@ -175,7 +202,7 @@ public class UsbAccessory implements Parcelable { return mManufacturer.hashCode() ^ mModel.hashCode() ^ (mDescription == null ? 0 : mDescription.hashCode()) ^ (mVersion == null ? 0 : mVersion.hashCode()) ^ - (mUri == null ? 0 : mUri.hashCode()) ^ (mSerial == null ? 0 : mSerial.hashCode()); + (mUri == null ? 0 : mUri.hashCode()); } @Override @@ -185,7 +212,7 @@ public class UsbAccessory implements Parcelable { ", mDescription=" + mDescription + ", mVersion=" + mVersion + ", mUri=" + mUri + - ", mSerial=" + mSerial + "]"; + ", mSerialNumberReader=" + mSerialNumberReader + "]"; } public static final Parcelable.Creator<UsbAccessory> CREATOR = @@ -196,8 +223,11 @@ public class UsbAccessory implements Parcelable { String description = in.readString(); String version = in.readString(); String uri = in.readString(); - String serial = in.readString(); - return new UsbAccessory(manufacturer, model, description, version, uri, serial); + IUsbSerialReader serialNumberReader = IUsbSerialReader.Stub.asInterface( + in.readStrongBinder()); + + return new UsbAccessory(manufacturer, model, description, version, uri, + serialNumberReader); } public UsbAccessory[] newArray(int size) { @@ -215,6 +245,6 @@ public class UsbAccessory implements Parcelable { parcel.writeString(mDescription); parcel.writeString(mVersion); parcel.writeString(mUri); - parcel.writeString(mSerial); + parcel.writeStrongBinder(mSerialNumberReader.asBinder()); } } diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java index 26c5a9597571..b08212c2d37a 100644 --- a/core/java/android/hardware/usb/UsbDevice.java +++ b/core/java/android/hardware/usb/UsbDevice.java @@ -19,8 +19,11 @@ package android.hardware.usb; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; +import android.app.ActivityThread; import android.os.Parcel; import android.os.Parcelable; +import android.os.RemoteException; + import com.android.internal.util.Preconditions; /** @@ -50,27 +53,27 @@ public class UsbDevice implements Parcelable { private final @Nullable String mManufacturerName; private final @Nullable String mProductName; private final @NonNull String mVersion; - private final @Nullable String mSerialNumber; + private final @NonNull UsbConfiguration[] mConfigurations; + private final @NonNull IUsbSerialReader mSerialNumberReader; private final int mVendorId; private final int mProductId; private final int mClass; private final int mSubclass; private final int mProtocol; - /** All configurations for this device, only null during creation */ - private @Nullable Parcelable[] mConfigurations; - /** All interfaces on the device. Initialized on first call to getInterfaceList */ @UnsupportedAppUsage private @Nullable UsbInterface[] mInterfaces; /** - * UsbDevice should only be instantiated by UsbService implementation + * Create a new UsbDevice object. Only called by {@link Builder#build(IUsbSerialReader)} + * * @hide */ - public UsbDevice(@NonNull String name, int vendorId, int productId, int Class, int subClass, + private UsbDevice(@NonNull String name, int vendorId, int productId, int Class, int subClass, int protocol, @Nullable String manufacturerName, @Nullable String productName, - @NonNull String version, @Nullable String serialNumber) { + @NonNull String version, @NonNull UsbConfiguration[] configurations, + @NonNull IUsbSerialReader serialNumberReader) { mName = Preconditions.checkNotNull(name); mVendorId = vendorId; mProductId = productId; @@ -80,7 +83,13 @@ public class UsbDevice implements Parcelable { mManufacturerName = manufacturerName; mProductName = productName; mVersion = Preconditions.checkStringNotEmpty(version); - mSerialNumber = serialNumber; + mConfigurations = Preconditions.checkArrayElementsNotNull(configurations, "configurations"); + mSerialNumberReader = Preconditions.checkNotNull(serialNumberReader); + + // Make sure the binder belongs to the system + if (ActivityThread.isSystem()) { + Preconditions.checkArgument(mSerialNumberReader instanceof IUsbSerialReader.Stub); + } } /** @@ -125,9 +134,17 @@ public class UsbDevice implements Parcelable { * Returns the serial number of the device. * * @return the serial number name, or {@code null} if the property could not be read + * + * @throws SecurityException if the app targets SDK >= {@value android.os.Build.VERSION_CODES#Q} + * and the app does not have permission to read from the device. */ public @Nullable String getSerialNumber() { - return mSerialNumber; + try { + return mSerialNumberReader.getSerial(ActivityThread.currentPackageName()); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return null; + } } /** @@ -203,7 +220,7 @@ public class UsbDevice implements Parcelable { * @return the configuration */ public @NonNull UsbConfiguration getConfiguration(int index) { - return (UsbConfiguration)mConfigurations[index]; + return mConfigurations[index]; } private @Nullable UsbInterface[] getInterfaceList() { @@ -211,14 +228,14 @@ public class UsbDevice implements Parcelable { int configurationCount = mConfigurations.length; int interfaceCount = 0; for (int i = 0; i < configurationCount; i++) { - UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i]; + UsbConfiguration configuration = mConfigurations[i]; interfaceCount += configuration.getInterfaceCount(); } mInterfaces = new UsbInterface[interfaceCount]; int offset = 0; for (int i = 0; i < configurationCount; i++) { - UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i]; + UsbConfiguration configuration = mConfigurations[i]; interfaceCount = configuration.getInterfaceCount(); for (int j = 0; j < interfaceCount; j++) { mInterfaces[offset++] = configuration.getInterface(j); @@ -251,14 +268,6 @@ public class UsbDevice implements Parcelable { return getInterfaceList()[index]; } - /** - * Only used by UsbService implementation - * @hide - */ - public void setConfigurations(@NonNull Parcelable[] configuration) { - mConfigurations = Preconditions.checkArrayElementsNotNull(configuration, "configuration"); - } - @Override public boolean equals(Object o) { if (o instanceof UsbDevice) { @@ -281,7 +290,8 @@ public class UsbDevice implements Parcelable { ",mVendorId=" + mVendorId + ",mProductId=" + mProductId + ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol + ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName + - ",mVersion=" + mVersion + ",mSerialNumber=" + mSerialNumber + ",mConfigurations=["); + ",mVersion=" + mVersion + ",mSerialNumberReader=" + mSerialNumberReader + + ",mConfigurations=["); for (int i = 0; i < mConfigurations.length; i++) { builder.append("\n"); builder.append(mConfigurations[i].toString()); @@ -302,11 +312,13 @@ public class UsbDevice implements Parcelable { String manufacturerName = in.readString(); String productName = in.readString(); String version = in.readString(); - String serialNumber = in.readString(); - Parcelable[] configurations = in.readParcelableArray(UsbInterface.class.getClassLoader()); + IUsbSerialReader serialNumberReader = + IUsbSerialReader.Stub.asInterface(in.readStrongBinder()); + UsbConfiguration[] configurations = in.readParcelableArray( + UsbConfiguration.class.getClassLoader(), UsbConfiguration.class); UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol, - manufacturerName, productName, version, serialNumber); - device.setConfigurations(configurations); + manufacturerName, productName, version, configurations, + serialNumberReader); return device; } @@ -329,7 +341,7 @@ public class UsbDevice implements Parcelable { parcel.writeString(mManufacturerName); parcel.writeString(mProductName); parcel.writeString(mVersion); - parcel.writeString(mSerialNumber); + parcel.writeStrongBinder(mSerialNumberReader.asBinder()); parcel.writeParcelableArray(mConfigurations, 0); } @@ -343,4 +355,53 @@ public class UsbDevice implements Parcelable { private static native int native_get_device_id(String name); private static native String native_get_device_name(int id); + + /** + * @hide + */ + public static class Builder { + private final @NonNull String mName; + private final int mVendorId; + private final int mProductId; + private final int mClass; + private final int mSubclass; + private final int mProtocol; + private final @Nullable String mManufacturerName; + private final @Nullable String mProductName; + private final @NonNull String mVersion; + private final @NonNull UsbConfiguration[] mConfigurations; + + // Temporary storage for serial number. Serial number reader need to be wrapped in a + // IUsbSerialReader as they might be used as PII. + public final @Nullable String serialNumber; + + 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) { + mName = Preconditions.checkNotNull(name); + mVendorId = vendorId; + mProductId = productId; + mClass = Class; + mSubclass = subClass; + mProtocol = protocol; + mManufacturerName = manufacturerName; + mProductName = productName; + mVersion = Preconditions.checkStringNotEmpty(version); + mConfigurations = configurations; + this.serialNumber = serialNumber; + } + + /** + * Create a new {@link UsbDevice} + * + * @param serialReader The method to read the serial number. + * + * @return The usb device + */ + public UsbDevice build(@NonNull IUsbSerialReader serialReader) { + return new UsbDevice(mName, mVendorId, mProductId, mClass, mSubclass, mProtocol, + mManufacturerName, mProductName, mVersion, mConfigurations, serialReader); + } + } } diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 57f166889b85..bd3e74566d1b 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -20,8 +20,6 @@ import static com.android.internal.usb.DumpUtils.writeAccessory; import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; import android.app.ActivityManager; - -import com.android.server.wm.ActivityTaskManagerInternal; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationChannel; @@ -52,6 +50,7 @@ import android.hardware.usb.gadget.V1_0.Status; import android.hidl.manager.V1_0.IServiceManager; import android.hidl.manager.V1_0.IServiceNotification; import android.os.BatteryManager; +import android.os.Binder; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; @@ -82,6 +81,7 @@ import com.android.internal.os.SomeArgs; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; import com.android.server.LocalServices; +import com.android.server.wm.ActivityTaskManagerInternal; import java.io.File; import java.io.FileDescriptor; @@ -658,7 +658,19 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser // successfully entered accessory mode String[] accessoryStrings = mUsbDeviceManager.getAccessoryStrings(); if (accessoryStrings != null) { - mCurrentAccessory = new UsbAccessory(accessoryStrings); + UsbSerialReader serialReader = new UsbSerialReader(mContext, mSettingsManager, + accessoryStrings[UsbAccessory.SERIAL_STRING]); + + mCurrentAccessory = new UsbAccessory( + accessoryStrings[UsbAccessory.MANUFACTURER_STRING], + accessoryStrings[UsbAccessory.MODEL_STRING], + accessoryStrings[UsbAccessory.DESCRIPTION_STRING], + accessoryStrings[UsbAccessory.VERSION_STRING], + accessoryStrings[UsbAccessory.URI_STRING], + serialReader); + + serialReader.setDevice(mCurrentAccessory); + Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory); // defer accessoryAttached if system is not ready if (mBootCompleted) { @@ -1982,7 +1994,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser + currentAccessory; throw new IllegalArgumentException(error); } - settings.checkPermission(accessory); + settings.checkPermission(accessory, Binder.getCallingUid()); return nativeOpenAccessory(); } diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index 589bcdc14871..a4c29a62167b 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -370,13 +370,18 @@ public class UsbHostManager { return false; } - UsbDevice newDevice = parser.toAndroidUsbDevice(); - if (newDevice == null) { + UsbDevice.Builder newDeviceBuilder = parser.toAndroidUsbDevice(); + if (newDeviceBuilder == null) { Slog.e(TAG, "Couldn't create UsbDevice object."); // Tracking addConnectionRecord(deviceAddress, ConnectionRecord.CONNECT_BADDEVICE, parser.getRawDescriptors()); } else { + UsbSerialReader serialNumberReader = new UsbSerialReader(mContext, mSettingsManager, + newDeviceBuilder.serialNumber); + UsbDevice newDevice = newDeviceBuilder.build(serialNumberReader); + serialNumberReader.setDevice(newDevice); + mDevices.put(deviceAddress, newDevice); Slog.d(TAG, "Added device " + newDevice); diff --git a/services/usb/java/com/android/server/usb/UsbPermissionManager.java b/services/usb/java/com/android/server/usb/UsbPermissionManager.java index 2c9ee36107e8..dd2f29ba74ae 100644 --- a/services/usb/java/com/android/server/usb/UsbPermissionManager.java +++ b/services/usb/java/com/android/server/usb/UsbPermissionManager.java @@ -148,11 +148,11 @@ class UsbPermissionManager { * Returns true if caller has permission to access the accessory. * * @param accessory to check permission for + * @param uid to check permission for * @return {@code true} if caller has permssion */ - boolean hasPermission(@NonNull UsbAccessory accessory) { + boolean hasPermission(@NonNull UsbAccessory accessory, int uid) { synchronized (mLock) { - int uid = Binder.getCallingUid(); if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) { return true; } diff --git a/services/usb/java/com/android/server/usb/UsbSerialReader.java b/services/usb/java/com/android/server/usb/UsbSerialReader.java new file mode 100644 index 000000000000..5bf94afd7683 --- /dev/null +++ b/services/usb/java/com/android/server/usb/UsbSerialReader.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2018 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.server.usb; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.hardware.usb.IUsbSerialReader; +import android.hardware.usb.UsbAccessory; +import android.hardware.usb.UsbDevice; +import android.os.Binder; +import android.os.Build; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; + +import com.android.internal.util.ArrayUtils; + +/** + * Allows an app to read the serial number of the {@link UsbDevice}/{@link UsbAccessory} only if + * the app has got the permission to do so. + */ +class UsbSerialReader extends IUsbSerialReader.Stub { + private final @Nullable String mSerialNumber; + private final @NonNull Context mContext; + private final @NonNull UsbSettingsManager mSettingsManager; + + private Object mDevice; + + /** + * Create an new {@link UsbSerialReader}. It is mandatory to call {@link #setDevice(Object)} + * immediately after this. + * + * @param context A context to be used by the reader + * @param settingsManager The USB settings manager + * @param serialNumber The serial number that might be read + */ + UsbSerialReader(@NonNull Context context, @NonNull UsbSettingsManager settingsManager, + @Nullable String serialNumber) { + mContext = context; + mSettingsManager = settingsManager; + mSerialNumber = serialNumber; + } + + /** + * Set the {@link UsbDevice}/{@link UsbAccessory} the serial number belongs to + * + * @param device The device/accessory + */ + public void setDevice(@NonNull Object device) { + mDevice = device; + } + + @Override + public String getSerial(String packageName) throws RemoteException { + int pid = Binder.getCallingPid(); + int uid = Binder.getCallingUid(); + + if (uid != Process.SYSTEM_UID) { + enforcePackageBelongsToUid(uid, packageName); + + PackageInfo pkg; + try { + pkg = mContext.getPackageManager().getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + throw new RemoteException("package " + packageName + " cannot be found"); + } + + if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) { + if (mContext.checkPermission(android.Manifest.permission.MANAGE_USB, pid, uid) + == PackageManager.PERMISSION_DENIED) { + UsbUserSettingsManager settings = mSettingsManager.getSettingsForUser( + UserHandle.getUserId(uid)); + + if (mDevice instanceof UsbDevice) { + settings.checkPermission((UsbDevice) mDevice, packageName, uid); + } else { + settings.checkPermission((UsbAccessory) mDevice, uid); + } + } + } + } + + return mSerialNumber; + } + + private void enforcePackageBelongsToUid(int uid, @NonNull String packageName) { + String[] packages = mContext.getPackageManager().getPackagesForUid(uid); + + if (!ArrayUtils.contains(packages, packageName)) { + throw new IllegalArgumentException(packageName + " does to belong to the " + uid); + } + } +} diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index e92bd74fadf2..4be70af05a3f 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -318,8 +318,13 @@ public class UsbService extends IUsbManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); UserHandle user = UserHandle.of(userId); - mSettingsManager.getSettingsForProfileGroup(user).setDevicePackage(device, packageName, - user); + final long token = Binder.clearCallingIdentity(); + try { + mSettingsManager.getSettingsForProfileGroup(user).setDevicePackage(device, packageName, + user); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override @@ -329,49 +334,93 @@ public class UsbService extends IUsbManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); UserHandle user = UserHandle.of(userId); - mSettingsManager.getSettingsForProfileGroup(user).setAccessoryPackage(accessory, - packageName, user); + + final long token = Binder.clearCallingIdentity(); + try { + mSettingsManager.getSettingsForProfileGroup(user).setAccessoryPackage(accessory, + packageName, user); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override public boolean hasDevicePermission(UsbDevice device, String packageName) { - final int userId = UserHandle.getCallingUserId(); - return getSettingsForUser(userId).hasPermission(device, packageName, - Binder.getCallingUid()); + final int uid = Binder.getCallingUid(); + final int userId = UserHandle.getUserId(uid); + + final long token = Binder.clearCallingIdentity(); + try { + return getSettingsForUser(userId).hasPermission(device, packageName, uid); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override public boolean hasAccessoryPermission(UsbAccessory accessory) { - final int userId = UserHandle.getCallingUserId(); - return getSettingsForUser(userId).hasPermission(accessory); + final int uid = Binder.getCallingUid(); + final int userId = UserHandle.getUserId(uid); + + final long token = Binder.clearCallingIdentity(); + try { + return getSettingsForUser(userId).hasPermission(accessory, uid); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) { - final int userId = UserHandle.getCallingUserId(); - getSettingsForUser(userId).requestPermission(device, packageName, pi, - Binder.getCallingUid()); + final int uid = Binder.getCallingUid(); + final int userId = UserHandle.getUserId(uid); + + final long token = Binder.clearCallingIdentity(); + try { + getSettingsForUser(userId).requestPermission(device, packageName, pi, uid); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override public void requestAccessoryPermission( UsbAccessory accessory, String packageName, PendingIntent pi) { - final int userId = UserHandle.getCallingUserId(); - getSettingsForUser(userId).requestPermission(accessory, packageName, pi); + final int uid = Binder.getCallingUid(); + final int userId = UserHandle.getUserId(uid); + + final long token = Binder.clearCallingIdentity(); + try { + getSettingsForUser(userId).requestPermission(accessory, packageName, pi, uid); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override public void grantDevicePermission(UsbDevice device, int uid) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); final int userId = UserHandle.getUserId(uid); - getSettingsForUser(userId).grantDevicePermission(device, uid); + + final long token = Binder.clearCallingIdentity(); + try { + getSettingsForUser(userId).grantDevicePermission(device, uid); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override public void grantAccessoryPermission(UsbAccessory accessory, int uid) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); final int userId = UserHandle.getUserId(uid); - getSettingsForUser(userId).grantAccessoryPermission(accessory, uid); + + final long token = Binder.clearCallingIdentity(); + try { + getSettingsForUser(userId).grantAccessoryPermission(accessory, uid); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override @@ -381,7 +430,13 @@ public class UsbService extends IUsbManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); UserHandle user = UserHandle.of(userId); - return mSettingsManager.getSettingsForProfileGroup(user).hasDefaults(packageName, user); + + final long token = Binder.clearCallingIdentity(); + try { + return mSettingsManager.getSettingsForProfileGroup(user).hasDefaults(packageName, user); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override @@ -391,7 +446,13 @@ public class UsbService extends IUsbManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); UserHandle user = UserHandle.of(userId); - mSettingsManager.getSettingsForProfileGroup(user).clearDefaults(packageName, user); + + final long token = Binder.clearCallingIdentity(); + try { + mSettingsManager.getSettingsForProfileGroup(user).clearDefaults(packageName, user); + } finally { + Binder.restoreCallingIdentity(token); + } } @Override diff --git a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java index fe93399c2d60..0121d30736c2 100644 --- a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java @@ -168,19 +168,21 @@ class UsbUserSettingsManager { return mUsbPermissionManager.hasPermission(device, uid); } - public boolean hasPermission(UsbAccessory accessory) { - return mUsbPermissionManager.hasPermission(accessory); + public boolean hasPermission(UsbAccessory accessory, int uid) { + return mUsbPermissionManager.hasPermission(accessory, uid); } public void checkPermission(UsbDevice device, String packageName, int uid) { if (!hasPermission(device, packageName, uid)) { - throw new SecurityException("User has not given permission to device " + device); + throw new SecurityException("User has not given " + uid + "/" + packageName + + " permission to access device " + device.getDeviceName()); } } - public void checkPermission(UsbAccessory accessory) { - if (!hasPermission(accessory)) { - throw new SecurityException("User has not given permission to accessory " + accessory); + public void checkPermission(UsbAccessory accessory, int uid) { + if (!hasPermission(accessory, uid)) { + throw new SecurityException("User has not given " + uid + " permission to accessory " + + accessory); } } @@ -236,9 +238,10 @@ class UsbUserSettingsManager { requestPermissionDialog(device, null, canBeDefault(device, packageName), packageName, pi); } - public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi) { + public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi, + int uid) { // respond immediately if permission has already been granted - if (hasPermission(accessory)) { + if (hasPermission(accessory, uid)) { Intent intent = new Intent(); intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory); intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true); 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 e61542824083..c02110186d8d 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java @@ -271,13 +271,13 @@ public final class UsbDescriptorParser { /** * @hide */ - public UsbDevice toAndroidUsbDevice() { + public UsbDevice.Builder toAndroidUsbDevice() { if (mDeviceDescriptor == null) { Log.e(TAG, "toAndroidUsbDevice() ERROR - No Device Descriptor"); return null; } - UsbDevice device = mDeviceDescriptor.toAndroid(this); + UsbDevice.Builder device = mDeviceDescriptor.toAndroid(this); if (device == null) { Log.e(TAG, "toAndroidUsbDevice() ERROR Creating Device"); } 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 fae594ac4986..f50b9cbc5e3d 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java @@ -135,7 +135,7 @@ public final class UsbDeviceDescriptor extends UsbDescriptor { /** * @hide */ - public UsbDevice toAndroid(UsbDescriptorParser parser) { + public UsbDevice.Builder toAndroid(UsbDescriptorParser parser) { if (DEBUG) { Log.d(TAG, "toAndroid()"); } @@ -152,16 +152,14 @@ public final class UsbDeviceDescriptor extends UsbDescriptor { Log.d(TAG, " versionString:" + versionString + " serialStr:" + serialStr); } - UsbDevice device = new UsbDevice(parser.getDeviceAddr(), mVendorID, mProductID, - mDevClass, mDevSubClass, - mProtocol, mfgName, prodName, - versionString, serialStr); UsbConfiguration[] configs = new UsbConfiguration[mConfigDescriptors.size()]; Log.d(TAG, " " + configs.length + " configs"); for (int index = 0; index < mConfigDescriptors.size(); index++) { configs[index] = mConfigDescriptors.get(index).toAndroid(parser); } - device.setConfigurations(configs); + UsbDevice.Builder device = new UsbDevice.Builder(parser.getDeviceAddr(), mVendorID, + mProductID, mDevClass, mDevSubClass, mProtocol, mfgName, prodName, versionString, + configs, serialStr); return device; } |