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

Commit b151f194 authored by Paul Mclean's avatar Paul Mclean Committed by Android (Google) Code Review
Browse files

Merge "Add video class-specific descriptors to UsbDescriptorParser framework."

parents 08fddb89 a7e7f94f
Loading
Loading
Loading
Loading
+32 −5
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ public class UsbDevice implements Parcelable {
    private final boolean mHasAudioPlayback;
    private final boolean mHasAudioCapture;
    private final boolean mHasMidi;
    private final boolean mHasVideoPlayback;
    private final boolean mHasVideoCapture;

    /** All interfaces on the device. Initialized on first call to getInterfaceList */
    @UnsupportedAppUsage
@@ -77,7 +79,8 @@ public class UsbDevice implements Parcelable {
            int protocol, @Nullable String manufacturerName, @Nullable String productName,
            @NonNull String version, @NonNull UsbConfiguration[] configurations,
            @NonNull IUsbSerialReader serialNumberReader,
            boolean hasAudioPlayback, boolean hasAudioCapture, boolean hasMidi) {
            boolean hasAudioPlayback, boolean hasAudioCapture, boolean hasMidi,
            boolean hasVideoPlayback, boolean hasVideoCapture) {
        mName = Preconditions.checkNotNull(name);
        mVendorId = vendorId;
        mProductId = productId;
@@ -92,6 +95,8 @@ public class UsbDevice implements Parcelable {
        mHasAudioPlayback = hasAudioPlayback;
        mHasAudioCapture = hasAudioCapture;
        mHasMidi = hasMidi;
        mHasVideoPlayback = hasVideoPlayback;
        mHasVideoCapture = hasVideoCapture;

        // Make sure the binder belongs to the system
        if (ActivityThread.isSystem()) {
@@ -236,6 +241,16 @@ public class UsbDevice implements Parcelable {
        return mHasMidi;
    }

    /** @hide */
    public boolean getHasVideoPlayback() {
        return mHasVideoPlayback;
    }

    /** @hide */
    public boolean getHasVideoCapture() {
        return mHasVideoCapture;
    }

    /**
     * Returns the {@link UsbConfiguration} at the given index.
     *
@@ -316,6 +331,8 @@ public class UsbDevice implements Parcelable {
                + ", mHasAudioPlayback=" + mHasAudioPlayback
                + ", mHasAudioCapture=" + mHasAudioCapture
                + ", mHasMidi=" + mHasMidi
                + ", mHasVideoCapture=" + mHasVideoCapture
                + ", mHasVideoPlayback=" + mHasVideoPlayback
                + ", mConfigurations=[");
        for (int i = 0; i < mConfigurations.length; i++) {
            builder.append("\n");
@@ -345,10 +362,12 @@ public class UsbDevice implements Parcelable {
            boolean hasAudioPlayback = in.readInt() == 1;
            boolean hasAudioCapture = in.readInt() == 1;
            boolean hasMidi = in.readInt() == 1;

            boolean hasVideoPlayback = in.readInt() == 1;
            boolean hasVideoCapture = in.readInt() == 1;
            UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
                    manufacturerName, productName, version, configurations, serialNumberReader,
                    hasAudioPlayback, hasAudioCapture, hasMidi);
                    hasAudioPlayback, hasAudioCapture, hasMidi,
                    hasVideoPlayback, hasVideoCapture);

            return device;
        }
@@ -377,6 +396,8 @@ public class UsbDevice implements Parcelable {
        parcel.writeInt(mHasAudioPlayback ? 1 : 0);
        parcel.writeInt(mHasAudioCapture ? 1 : 0);
        parcel.writeInt(mHasMidi ? 1 : 0);
        parcel.writeInt(mHasVideoPlayback ? 1 : 0);
        parcel.writeInt(mHasVideoCapture ? 1 : 0);
    }

    public static int getDeviceId(String name) {
@@ -407,6 +428,8 @@ public class UsbDevice implements Parcelable {
        private final boolean mHasAudioPlayback;
        private final boolean mHasAudioCapture;
        private final boolean mHasMidi;
        private final boolean mHasVideoPlayback;
        private final boolean mHasVideoCapture;

        // Temporary storage for serial number. Serial number reader need to be wrapped in a
        // IUsbSerialReader as they might be used as PII.
@@ -416,7 +439,8 @@ public class UsbDevice implements Parcelable {
                int protocol, @Nullable String manufacturerName, @Nullable String productName,
                @NonNull String version, @NonNull UsbConfiguration[] configurations,
                @Nullable String serialNumber,
                boolean hasAudioPlayback, boolean hasAudioCapture, boolean hasMidi) {
                boolean hasAudioPlayback, boolean hasAudioCapture, boolean hasMidi,
                boolean hasVideoPlayback, boolean hasVideoCapture) {
            mName = Preconditions.checkNotNull(name);
            mVendorId = vendorId;
            mProductId = productId;
@@ -431,6 +455,8 @@ public class UsbDevice implements Parcelable {
            mHasAudioPlayback = hasAudioPlayback;
            mHasAudioCapture = hasAudioCapture;
            mHasMidi = hasMidi;
            mHasVideoPlayback = hasVideoPlayback;
            mHasVideoCapture = hasVideoCapture;
        }

        /**
@@ -443,7 +469,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,
                    mHasAudioPlayback, mHasAudioCapture, mHasMidi);
                    mHasAudioPlayback, mHasAudioCapture, mHasMidi,
                    mHasVideoPlayback, mHasVideoCapture);
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ abstract class UsbACEndpoint extends UsbDescriptor {
                                                int length, byte type) {
        UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
        int subClass = interfaceDesc.getUsbSubclass();
        // TODO shouldn't this switch on subtype?
        switch (subClass) {
            case AUDIO_AUDIOCONTROL:
                if (UsbDescriptorParser.DEBUG) {
+63 −16
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import java.util.ArrayList;
 */
public final class UsbDescriptorParser {
    private static final String TAG = "UsbDescriptorParser";
    public static final boolean DEBUG = true;
    public static final boolean DEBUG = false;

    private final String mDeviceAddr;

@@ -43,6 +43,11 @@ public final class UsbDescriptorParser {
    // Obtained from the first AudioClass Header descriptor.
    private int mACInterfacesSpec = UsbDeviceDescriptor.USBSPEC_1_0;

    // The VideoClass spec implemented by the VideoClass Interfaces
    // This may well be different than the overall USB Spec.
    // Obtained from the first VidieoClass Header descriptor.
    private int mVCInterfacesSpec = UsbDeviceDescriptor.USBSPEC_1_0;

    /**
     * Connect this parser to an existing set of already parsed descriptors.
     * This is useful for reporting.
@@ -90,6 +95,14 @@ public final class UsbDescriptorParser {
        return mACInterfacesSpec;
    }

    public void setVCInterfaceSpec(int spec) {
        mVCInterfacesSpec = spec;
    }

    public int getVCInterfaceSpec() {
        return mVCInterfacesSpec;
    }

    private class UsbDescriptorsStreamFormatException extends Exception {
        String mMessage;
        UsbDescriptorsStreamFormatException(String message) {
@@ -186,19 +199,20 @@ public final class UsbDescriptorParser {
                            break;

                        case UsbDescriptor.CLASSID_VIDEO:
                            Log.d(TAG, "  UsbDescriptor.CLASSID_VIDEO subType:0x"
                                    + Integer.toHexString(stream.getByte()));
                            if (DEBUG) {
                                Log.d(TAG, "  UsbDescriptor.CLASSID_VIDEO");
                            }
                            descriptor = UsbVCInterface.allocDescriptor(this, stream, length, type);
                            break;

                        case UsbDescriptor.CLASSID_AUDIOVIDEO:
                            Log.d(TAG, "  UsbDescriptor.CLASSID_AUDIOVIDEO subType:0x"
                                    + Integer.toHexString(stream.getByte()));
                            if (DEBUG) {
                                Log.d(TAG, "  UsbDescriptor.CLASSID_AUDIOVIDEO");
                            }
                            break;

                        default:
                            Log.d(TAG, "  Unparsed Class-specific Interface:0x"
                                    + Integer.toHexString(mCurInterfaceDescriptor.getUsbClass()));
                            Log.w(TAG, "  Unparsed Class-specific");
                            break;
                    }
                }
@@ -206,23 +220,32 @@ public final class UsbDescriptorParser {

            case UsbDescriptor.DESCRIPTORTYPE_CLASSSPECIFIC_ENDPOINT:
                if (mCurInterfaceDescriptor != null) {
                    switch (mCurInterfaceDescriptor.getUsbClass()) {
                    int subClass = mCurInterfaceDescriptor.getUsbClass();
                    switch (subClass) {
                        case UsbDescriptor.CLASSID_AUDIO:
                            descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
                            break;
                        case UsbDescriptor.CLASSID_VIDEO:
                            Log.d(TAG, "UsbDescriptor.CLASSID_VIDEO subType:0x"
                                    + Integer.toHexString(stream.getByte()));
                            descriptor = UsbVCEndpoint.allocDescriptor(this, length, type);

                        case UsbDescriptor.CLASSID_VIDEO: {
                            Byte subtype = stream.getByte();
                            if (DEBUG) {
                                Log.d(TAG, "UsbDescriptor.CLASSID_VIDEO type:0x"
                                        + Integer.toHexString(type));
                            }
                            descriptor = UsbVCEndpoint.allocDescriptor(this, length, type, subtype);
                        }
                            break;

                        case UsbDescriptor.CLASSID_AUDIOVIDEO:
                            Log.d(TAG, "UsbDescriptor.CLASSID_AUDIOVIDEO subType:0x"
                                    + Integer.toHexString(stream.getByte()));
                            if (DEBUG) {
                                Log.d(TAG, "UsbDescriptor.CLASSID_AUDIOVIDEO type:0x"
                                        + Integer.toHexString(type));
                            }
                            break;

                        default:
                            Log.d(TAG, "  Unparsed Class-specific Endpoint:0x"
                                    + Integer.toHexString(mCurInterfaceDescriptor.getUsbClass()));
                            Log.w(TAG, "  Unparsed Class-specific Endpoint:0x"
                                    + Integer.toHexString(subClass));
                            break;
                    }
                }
@@ -552,6 +575,30 @@ public final class UsbDescriptorParser {
        return hasAudioTerminal(UsbACInterface.ACI_INPUT_TERMINAL);
    }

    /**
     * @hide
     */
    public boolean hasVideoCapture() {
        for (UsbDescriptor descriptor : mDescriptors) {
            if (descriptor instanceof UsbVCInputTerminal) {
                return true;
            }
        }
        return false;
    }

    /**
     * @hide
     */
    public boolean hasVideoPlayback() {
        for (UsbDescriptor descriptor : mDescriptors) {
            if (descriptor instanceof UsbVCOutputTerminal) {
                return true;
            }
        }
        return false;
    }

    /**
     * @hide
     */
+2 −1
Original line number Diff line number Diff line
@@ -160,7 +160,8 @@ public final class UsbDeviceDescriptor extends UsbDescriptor {
        return new UsbDevice.Builder(parser.getDeviceAddr(), mVendorID,
                mProductID, mDevClass, mDevSubClass, mProtocol, mfgName, prodName, versionString,
                configs, serialStr, parser.hasAudioPlayback(), parser.hasAudioCapture(),
                parser.hasMIDIInterface());
                parser.hasMIDIInterface(),
                parser.hasVideoPlayback(), parser.hasVideoCapture());
    }

    @Override
+37 −24
Original line number Diff line number Diff line
@@ -20,41 +20,54 @@ import android.util.Log;
/**
 * @hide
 * A video class-specific Endpoint
 * see
 * see USB_Video_Class_1.1.pdf - 3.10 VideoStreaming Endpoint Descriptors
 */
abstract class UsbVCEndpoint extends UsbDescriptor {
    private static final String TAG = "UsbVCEndpoint";

    UsbVCEndpoint(int length, byte type, int subclass) {

    public static final byte VCEP_UNDEFINED = 0x00;
    public static final byte VCEP_GENERAL   = 0x01;
    public static final byte VCEP_ENDPOINT  = 0x02;
    public static final byte VCEP_INTERRUPT = 0x03;

    UsbVCEndpoint(int length, byte type) {
        super(length, type);
        // mSubclass = subclass;
    }

    public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser,
                                                int length, byte type) {
                                                int length, byte type, byte subtype) {
        UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
        int subClass = interfaceDesc.getUsbSubclass();
        switch (subClass) {
//            case AUDIO_AUDIOCONTROL:
//                if (UsbDescriptorParser.DEBUG) {
//                    Log.i(TAG, "---> AUDIO_AUDIOCONTROL");
//                }
//                return new UsbACAudioControlEndpoint(length, type, subClass);
//
//            case AUDIO_AUDIOSTREAMING:
//                if (UsbDescriptorParser.DEBUG) {
//                    Log.i(TAG, "---> AUDIO_AUDIOSTREAMING");
//                }
//                return new UsbACAudioStreamEndpoint(length, type, subClass);
//
//            case AUDIO_MIDISTREAMING:
//                if (UsbDescriptorParser.DEBUG) {
//                    Log.i(TAG, "---> AUDIO_MIDISTREAMING");
//                }
//                return new UsbACMidiEndpoint(length, type, subClass);

        // TODO - create classes for each specific subtype
        //  (don't need it to answer if this device supports video
        switch (subtype) {
            case VCEP_UNDEFINED:
                if (UsbDescriptorParser.DEBUG) {
                    Log.d(TAG, "---> VCEP_UNDEFINED");
                }
                return null;

            case VCEP_GENERAL:
                if (UsbDescriptorParser.DEBUG) {
                    Log.d(TAG, "---> VCEP_GENERAL");
                }
                return null;

            case VCEP_ENDPOINT:
                if (UsbDescriptorParser.DEBUG) {
                    Log.d(TAG, "---> VCEP_ENDPOINT");
                }
                return null;

            case VCEP_INTERRUPT:
                if (UsbDescriptorParser.DEBUG) {
                    Log.d(TAG, "---> VCEP_INTERRUPT");
                }
                return null;

            default:
                Log.w(TAG, "Unknown Video Class Endpoint id:0x" + Integer.toHexString(subClass));
                Log.w(TAG, "Unknown Video Class Endpoint id:0x" + Integer.toHexString(subtype));
                return null;
        }
    }
Loading