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

Commit ea09d764 authored by Paul Mclean's avatar Paul Mclean Committed by android-build-merger
Browse files

Merge "Adding USB audio-class 2.0 spec descriptors." into oc-mr1-dev

am: 87cb6d80

Change-Id: I0a673c8b72d80813f9542d3c122debdc1c1cbef7
parents aa8ed4fe 87cb6d80
Loading
Loading
Loading
Loading
+43 −9
Original line number Original line Diff line number Diff line
@@ -15,7 +15,11 @@
 */
 */
package com.android.server.usb.descriptors;
package com.android.server.usb.descriptors;


// Framework builds and Android Studio builds use different imports for NonNull.
// This one for Framework builds
import android.annotation.NonNull;
import android.annotation.NonNull;
// this one in the AndroidStudio project
// import android.support.annotation.NonNull;


/**
/**
 * @hide
 * @hide
@@ -23,7 +27,7 @@ import android.annotation.NonNull;
 * but with the capability to "back up" in situations where the parser discovers that a
 * but with the capability to "back up" in situations where the parser discovers that a
 * UsbDescriptor has overrun its length.
 * UsbDescriptor has overrun its length.
 */
 */
public class ByteStream {
public final class ByteStream {
    private static final String TAG = "ByteStream";
    private static final String TAG = "ByteStream";


    /** The byte array being wrapped */
    /** The byte array being wrapped */
@@ -103,6 +107,20 @@ public class ByteStream {
        }
        }
    }
    }


    /**
     * @return the next byte from the stream and advances the stream and the read count. Note
     * that this is an unsigned byte encoded in a Java int.
     * @throws IndexOutOfBoundsException
     */
    public int getUnsignedByte() {
        if (available() > 0) {
            mReadCount++;
            return mBytes[mIndex++] & 0x000000FF;
        } else {
            throw new IndexOutOfBoundsException();
        }
    }

    /**
    /**
     * Reads 2 bytes in *little endian format* from the stream and composes a 16-bit integer.
     * Reads 2 bytes in *little endian format* from the stream and composes a 16-bit integer.
     * As we are storing the 2-byte value in a 4-byte integer, the upper 2 bytes are always
     * As we are storing the 2-byte value in a 4-byte integer, the upper 2 bytes are always
@@ -111,11 +129,11 @@ public class ByteStream {
     * next 2 bytes in the stream.
     * next 2 bytes in the stream.
     * @throws IndexOutOfBoundsException
     * @throws IndexOutOfBoundsException
     */
     */
    public int unpackUsbWord() {
    public int unpackUsbShort() {
        if (available() >= 2) {
        if (available() >= 2) {
            int b0 = getByte();
            int b0 = getUnsignedByte();
            int b1 = getByte();
            int b1 = getUnsignedByte();
            return ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF);
            return (b1 << 8) | b0;
        } else {
        } else {
            throw new IndexOutOfBoundsException();
            throw new IndexOutOfBoundsException();
        }
        }
@@ -131,15 +149,31 @@ public class ByteStream {
     */
     */
    public int unpackUsbTriple() {
    public int unpackUsbTriple() {
        if (available() >= 3) {
        if (available() >= 3) {
            int b0 = getByte();
            int b0 = getUnsignedByte();
            int b1 = getByte();
            int b1 = getUnsignedByte();
            int b2 = getByte();
            int b2 = getUnsignedByte();
            return ((b2 << 16) & 0x00FF0000) | ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF);
            return (b2 << 16) | (b1 << 8) | b0;
        } else {
        } else {
            throw new IndexOutOfBoundsException();
            throw new IndexOutOfBoundsException();
        }
        }
    }
    }


    /**
     * Reads 4 bytes in *little endian format* from the stream and composes a 32-bit integer.
     * @return The 32-bit integer encoded by the next 4 bytes in the stream.
     * @throws IndexOutOfBoundsException
     */
    public int unpackUsbInt() {
        if (available() >= 4) {
            int b0 = getUnsignedByte();
            int b1 = getUnsignedByte();
            int b2 = getUnsignedByte();
            int b3 = getUnsignedByte();
            return (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
        } else {
            throw new IndexOutOfBoundsException();
        }
    }
    /**
    /**
     * Advances the logical position in the stream. Affects the running count also.
     * Advances the logical position in the stream. Affects the running count also.
     * @param numBytes The number of bytes to advance.
     * @param numBytes The number of bytes to advance.
+33 −18
Original line number Original line Diff line number Diff line
@@ -15,18 +15,16 @@
 */
 */
package com.android.server.usb.descriptors;
package com.android.server.usb.descriptors;


import com.android.server.usb.descriptors.report.ReportCanvas;

/**
/**
 * @hide
 * @hide
 * An audio class-specific Interface Header.
 * An audio class-specific Interface Header.
 * see audio10.pdf section 4.3.2
 * see audio10.pdf section 4.3.2
 */
 */
public class UsbACHeader extends UsbACInterface {
public final class Usb10ACHeader extends UsbACHeaderInterface {
    private static final String TAG = "ACHeader";
    private static final String TAG = "Usb10ACHeader";


    private int mADCRelease;    // 3:2 Audio Device Class Specification Release (BCD).
    private int mTotalLength;   // 5:2 Total number of bytes returned for the class-specific
                                // AudioControl interface descriptor. Includes the combined length
                                // of this descriptor header and all Unit and Terminal descriptors.
    private byte mNumInterfaces = 0; // 7:1 The number of AudioStreaming and MIDIStreaming
    private byte mNumInterfaces = 0; // 7:1 The number of AudioStreaming and MIDIStreaming
                                     // interfaces in the Audio Interface Collection to which this
                                     // interfaces in the Audio Interface Collection to which this
                                     // AudioControl interface belongs: n
                                     // AudioControl interface belongs: n
@@ -34,16 +32,8 @@ public class UsbACHeader extends UsbACInterface {
                                            // numbers associate with this endpoint
                                            // numbers associate with this endpoint
    private byte mControls;                 // Vers 2.0 thing
    private byte mControls;                 // Vers 2.0 thing


    public UsbACHeader(int length, byte type, byte subtype, byte subclass) {
    public Usb10ACHeader(int length, byte type, byte subtype, byte subclass, int spec) {
        super(length, type, subtype, subclass);
        super(length, type, subtype, subclass, spec);
    }

    public int getADCRelease() {
        return mADCRelease;
    }

    public int getTotalLength() {
        return mTotalLength;
    }
    }


    public byte getNumInterfaces() {
    public byte getNumInterfaces() {
@@ -60,9 +50,8 @@ public class UsbACHeader extends UsbACInterface {


    @Override
    @Override
    public int parseRawDescriptors(ByteStream stream) {
    public int parseRawDescriptors(ByteStream stream) {
        mADCRelease = stream.unpackUsbWord();


        mTotalLength = stream.unpackUsbWord();
        mTotalLength = stream.unpackUsbShort();
        if (mADCRelease >= 0x200) {
        if (mADCRelease >= 0x200) {
            mControls = stream.getByte();
            mControls = stream.getByte();
        } else {
        } else {
@@ -75,4 +64,30 @@ public class UsbACHeader extends UsbACInterface {


        return mLength;
        return mLength;
    }
    }

    @Override
    public void report(ReportCanvas canvas) {
        super.report(canvas);

        canvas.openList();
        int numInterfaces = getNumInterfaces();
        StringBuilder sb = new StringBuilder();
        sb.append("" + numInterfaces + " Interfaces");
        if (numInterfaces > 0) {
            sb.append(" [");
            byte[] interfaceNums = getInterfaceNums();
            if (interfaceNums != null) {
                for (int index = 0; index < numInterfaces; index++) {
                    sb.append("" + interfaceNums[index]);
                    if (index < numInterfaces - 1) {
                        sb.append(" ");
                    }
                }
            }
            sb.append("]");
        }
        canvas.writeListItem(sb.toString());
        canvas.writeListItem("Controls: " + ReportCanvas.getHexString(getControls()));
        canvas.closeList();
    }
}
}
+18 −4
Original line number Original line Diff line number Diff line
@@ -15,13 +15,15 @@
 */
 */
package com.android.server.usb.descriptors;
package com.android.server.usb.descriptors;


import com.android.server.usb.descriptors.report.ReportCanvas;

/**
/**
 * @hide
 * @hide
 * An audio class-specific Input Terminal interface.
 * An audio class-specific Input Terminal interface.
 * see audio10.pdf section 4.3.2.1
 * see audio10.pdf section 4.3.2.1
 */
 */
public class UsbACInputTerminal extends UsbACTerminal {
public final class Usb10ACInputTerminal extends UsbACTerminal {
    private static final String TAG = "ACInputTerminal";
    private static final String TAG = "Usb10ACInputTerminal";


    private byte mNrChannels;       // 7:1 1 Channel (0x01)
    private byte mNrChannels;       // 7:1 1 Channel (0x01)
                                    // Number of logical output channels in the
                                    // Number of logical output channels in the
@@ -30,7 +32,7 @@ public class UsbACInputTerminal extends UsbACTerminal {
    private byte mChannelNames;     // 10:1 Unused (0x00)
    private byte mChannelNames;     // 10:1 Unused (0x00)
    private byte mTerminal;         // 11:1 Unused (0x00)
    private byte mTerminal;         // 11:1 Unused (0x00)


    public UsbACInputTerminal(int length, byte type, byte subtype, byte subclass) {
    public Usb10ACInputTerminal(int length, byte type, byte subtype, byte subclass) {
        super(length, type, subtype, subclass);
        super(length, type, subtype, subclass);
    }
    }


@@ -55,10 +57,22 @@ public class UsbACInputTerminal extends UsbACTerminal {
        super.parseRawDescriptors(stream);
        super.parseRawDescriptors(stream);


        mNrChannels = stream.getByte();
        mNrChannels = stream.getByte();
        mChannelConfig = stream.unpackUsbWord();
        mChannelConfig = stream.unpackUsbShort();
        mChannelNames = stream.getByte();
        mChannelNames = stream.getByte();
        mTerminal = stream.getByte();
        mTerminal = stream.getByte();


        return mLength;
        return mLength;
    }
    }

    @Override
    public void report(ReportCanvas canvas) {
        super.report(canvas);

        canvas.openList();
        canvas.writeListItem("Associated Terminal: "
                + ReportCanvas.getHexString(getAssocTerminal()));
        canvas.writeListItem("" + getNrChannels() + " Chans. Config: "
                + ReportCanvas.getHexString(getChannelConfig()));
        canvas.closeList();
    }
}
}
+108 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2017 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.descriptors;

import com.android.server.usb.descriptors.report.ReportCanvas;

/**
 * @hide
 * An audio class-specific Mixer Interface.
 * see audio10.pdf section 4.3.2.3
 */
public final class Usb10ACMixerUnit extends UsbACMixerUnit {
    private static final String TAG = "Usb10ACMixerUnit";

    private int mChannelConfig; // Spatial location of output channels
    private byte mChanNameID;   // First channel name string descriptor ID
    private byte[] mControls;   // bitmasks of which controls are present for each channel
    private byte mNameID;       // string descriptor ID of mixer name

    public Usb10ACMixerUnit(int length, byte type, byte subtype, byte subClass) {
        super(length, type, subtype, subClass);
    }

    public int getChannelConfig() {
        return mChannelConfig;
    }

    public byte getChanNameID() {
        return mChanNameID;
    }

    public byte[] getControls() {
        return mControls;
    }

    public byte getNameID() {
        return mNameID;
    }

    @Override
    public int parseRawDescriptors(ByteStream stream) {
        super.parseRawDescriptors(stream);

        mChannelConfig = stream.unpackUsbShort();
        mChanNameID = stream.getByte();

        int controlArraySize = calcControlArraySize(mNumInputs, mNumOutputs);
        mControls = new byte[controlArraySize];
        for (int index = 0; index < controlArraySize; index++) {
            mControls[index] = stream.getByte();
        }

        mNameID = stream.getByte();

        return mLength;
    }

    @Override
    public void report(ReportCanvas canvas) {
        super.report(canvas);

        canvas.writeParagraph("Mixer Unit", false);
        canvas.openList();

        canvas.writeListItem("Unit ID: " + ReportCanvas.getHexString(getUnitID()));
        byte numInputs = getNumInputs();
        byte[] inputIDs = getInputIDs();
        canvas.openListItem();
        canvas.write("Num Inputs: " + numInputs + " [");
        for (int input = 0; input < numInputs; input++) {
            canvas.write("" + ReportCanvas.getHexString(inputIDs[input]));
            if (input < numInputs - 1) {
                canvas.write(" ");
            }
        }
        canvas.write("]");
        canvas.closeListItem();

        canvas.writeListItem("Num Outputs: " + getNumOutputs());
        canvas.writeListItem("Channel Config: " + ReportCanvas.getHexString(getChannelConfig()));

        byte[] controls = getControls();
        canvas.openListItem();
        canvas.write("Controls: " + controls.length + " [");
        for (int ctrl = 0; ctrl < controls.length; ctrl++) {
            canvas.write("" + controls[ctrl]);
            if (ctrl < controls.length - 1) {
                canvas.write(" ");
            }
        }
        canvas.write("]");
        canvas.closeListItem();
        canvas.closeList();
    }
}
+14 −3
Original line number Original line Diff line number Diff line
@@ -15,18 +15,20 @@
 */
 */
package com.android.server.usb.descriptors;
package com.android.server.usb.descriptors;


import com.android.server.usb.descriptors.report.ReportCanvas;

/**
/**
 * @hide
 * @hide
 * An audio class-specific Output Terminal Interface.
 * An audio class-specific Output Terminal Interface.
 * see audio10.pdf section 4.3.2.2
 * see audio10.pdf section 4.3.2.2
 */
 */
public class UsbACOutputTerminal extends UsbACTerminal {
public final class Usb10ACOutputTerminal extends UsbACTerminal {
    private static final String TAG = "ACOutputTerminal";
    private static final String TAG = "Usb10ACOutputTerminal";


    private byte mSourceID;         // 7:1 From Input Terminal. (0x01)
    private byte mSourceID;         // 7:1 From Input Terminal. (0x01)
    private byte mTerminal;         // 8:1 Unused.
    private byte mTerminal;         // 8:1 Unused.


    public UsbACOutputTerminal(int length, byte type, byte subtype, byte subClass) {
    public Usb10ACOutputTerminal(int length, byte type, byte subtype, byte subClass) {
        super(length, type, subtype, subClass);
        super(length, type, subtype, subClass);
    }
    }


@@ -46,4 +48,13 @@ public class UsbACOutputTerminal extends UsbACTerminal {
        mTerminal = stream.getByte();
        mTerminal = stream.getByte();
        return mLength;
        return mLength;
    }
    }

    @Override
    public void report(ReportCanvas canvas) {
        super.report(canvas);

        canvas.openList();
        canvas.writeListItem("Source ID: " + ReportCanvas.getHexString(getSourceID()));
        canvas.closeList();
    }
}
}
Loading