Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2c6eea9 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Require permission to read USB device's serial number.

Fixes: 110953952
Test: CtsVerifier USB Device test
Change-Id: I99b52bac6c800d869198e282e364f3a530336803
parent f0c67fb4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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",
+24 −0
Original line number Diff line number Diff line
/*
 * 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);
}
+44 −14
Original line number Diff line number Diff line
@@ -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());
   }
}
+87 −26
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+16 −4
Original line number Diff line number Diff line
@@ -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();
    }

Loading