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

Commit 846944e9 authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "Add support for USB audio docks."

parents ae36c6a8 9b2b85c2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1360,6 +1360,9 @@ public class AudioDeviceInventory {
            case AudioSystem.DEVICE_OUT_USB_HEADSET:
                connType = AudioRoutesInfo.MAIN_USB;
                break;
            case AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET:
                connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
                break;
        }

        synchronized (mCurAudioRoutes) {
+30 −18
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ public final class UsbAlsaDevice {

    private final boolean mIsInputHeadset;
    private final boolean mIsOutputHeadset;
    private final boolean mIsDock;

    private boolean mSelected = false;
    private int mOutputState;
@@ -53,7 +54,7 @@ public final class UsbAlsaDevice {

    public UsbAlsaDevice(IAudioService audioService, int card, int device, String deviceAddress,
            boolean hasOutput, boolean hasInput,
            boolean isInputHeadset, boolean isOutputHeadset) {
            boolean isInputHeadset, boolean isOutputHeadset, boolean isDock) {
        mAudioService = audioService;
        mCardNum = card;
        mDeviceNum = device;
@@ -62,31 +63,32 @@ public final class UsbAlsaDevice {
        mHasInput = hasInput;
        mIsInputHeadset = isInputHeadset;
        mIsOutputHeadset = isOutputHeadset;
        mIsDock = isDock;
    }

    /**
     * @returns the ALSA card number associated with this peripheral.
     * @return the ALSA card number associated with this peripheral.
     */
    public int getCardNum() {
        return mCardNum;
    }

    /**
     * @returns the ALSA device number associated with this peripheral.
     * @return the ALSA device number associated with this peripheral.
     */
    public int getDeviceNum() {
        return mDeviceNum;
    }

    /**
     * @returns the USB device device address associated with this peripheral.
     * @return the USB device device address associated with this peripheral.
     */
    public String getDeviceAddress() {
        return mDeviceAddress;
    }

    /**
     * @returns the ALSA card/device address string.
     * @return the ALSA card/device address string.
     */
    public String getAlsaCardDeviceString() {
        if (mCardNum < 0 || mDeviceNum < 0) {
@@ -98,35 +100,42 @@ public final class UsbAlsaDevice {
    }

    /**
     * @returns true if the device supports output.
     * @return true if the device supports output.
     */
    public boolean hasOutput() {
        return mHasOutput;
    }

    /**
     * @returns true if the device supports input (recording).
     * @return true if the device supports input (recording).
     */
    public boolean hasInput() {
        return mHasInput;
    }

    /**
     * @returns true if the device is a headset for purposes of input.
     * @return true if the device is a headset for purposes of input.
     */
    public boolean isInputHeadset() {
        return mIsInputHeadset;
    }

    /**
     * @returns true if the device is a headset for purposes of output.
     * @return true if the device is a headset for purposes of output.
     */
    public boolean isOutputHeadset() {
        return mIsOutputHeadset;
    }

    /**
     * @returns true if input jack is detected or jack detection is not supported.
     * @return true if the device is a USB dock.
     */
    public boolean isDock() {
        return mIsDock;
    }

    /**
     * @return true if input jack is detected or jack detection is not supported.
     */
    private synchronized boolean isInputJackConnected() {
        if (mJackDetector == null) {
@@ -136,7 +145,7 @@ public final class UsbAlsaDevice {
    }

    /**
     * @returns true if input jack is detected or jack detection is not supported.
     * @return true if input jack is detected or jack detection is not supported.
     */
    private synchronized boolean isOutputJackConnected() {
        if (mJackDetector == null) {
@@ -190,9 +199,10 @@ public final class UsbAlsaDevice {
        try {
            // Output Device
            if (mHasOutput) {
                int device = mIsOutputHeadset
                int device = mIsDock ? AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET
                        : (mIsOutputHeadset
                            ? AudioSystem.DEVICE_OUT_USB_HEADSET
                        : AudioSystem.DEVICE_OUT_USB_DEVICE;
                            : AudioSystem.DEVICE_OUT_USB_DEVICE);
                if (DEBUG) {
                    Slog.d(TAG, "pre-call device:0x" + Integer.toHexString(device)
                            + " addr:" + alsaCardDeviceString
@@ -231,7 +241,7 @@ public final class UsbAlsaDevice {

    /**
     * @Override
     * @returns a string representation of the object.
     * @return a string representation of the object.
     */
    public synchronized String toString() {
        return "UsbAlsaDevice: [card: " + mCardNum
@@ -273,7 +283,7 @@ public final class UsbAlsaDevice {

    /**
     * @Override
     * @returns true if the objects are equivalent.
     * @return true if the objects are equivalent.
     */
    public boolean equals(Object obj) {
        if (!(obj instanceof UsbAlsaDevice)) {
@@ -285,12 +295,13 @@ public final class UsbAlsaDevice {
                && mHasOutput == other.mHasOutput
                && mHasInput == other.mHasInput
                && mIsInputHeadset == other.mIsInputHeadset
                && mIsOutputHeadset == other.mIsOutputHeadset);
                && mIsOutputHeadset == other.mIsOutputHeadset
                && mIsDock == other.mIsDock);
    }

    /**
     * @Override
     * @returns a hash code generated from the object contents.
     * @return a hash code generated from the object contents.
     */
    public int hashCode() {
        final int prime = 31;
@@ -301,6 +312,7 @@ public final class UsbAlsaDevice {
        result = prime * result + (mHasInput ? 0 : 1);
        result = prime * result + (mIsInputHeadset ? 0 : 1);
        result = prime * result + (mIsOutputHeadset ? 0 : 1);
        result = prime * result + (mIsDock ? 0 : 1);

        return result;
    }
+2 −1
Original line number Diff line number Diff line
@@ -237,6 +237,7 @@ public final class UsbAlsaManager {
        if (hasInput || hasOutput) {
            boolean isInputHeadset = parser.isInputHeadset();
            boolean isOutputHeadset = parser.isOutputHeadset();
            boolean isDock = parser.isDock();

            if (mAudioService == null) {
                Slog.e(TAG, "no AudioService");
@@ -246,7 +247,7 @@ public final class UsbAlsaManager {
            UsbAlsaDevice alsaDevice =
                    new UsbAlsaDevice(mAudioService, cardRec.getCardNum(), 0 /*device*/,
                                      deviceAddress, hasOutput, hasInput,
                                      isInputHeadset, isOutputHeadset);
                                      isInputHeadset, isOutputHeadset, isDock);
            if (alsaDevice != null) {
                alsaDevice.setDeviceNameAndDescription(
                          cardRec.getCardName(), cardRec.getCardDescription());
+3 −5
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ public class UsbHostManager {
                pw.println("manfacturer:0x" + Integer.toHexString(deviceDescriptor.getVendorID())
                        + " product:" + Integer.toHexString(deviceDescriptor.getProductID()));
                pw.println("isHeadset[in: " + parser.isInputHeadset()
                        + " , out: " + parser.isOutputHeadset() + "]");
                        + " , out: " + parser.isOutputHeadset() + "], isDock: " + parser.isDock());
            } else {
                pw.println(formatTime() + " Disconnect " + mDeviceAddress);
            }
@@ -179,9 +179,8 @@ public class UsbHostManager {
                UsbDescriptorsTree descriptorTree = new UsbDescriptorsTree();
                descriptorTree.parse(parser);
                descriptorTree.report(new TextReportCanvas(parser, stringBuilder));

                stringBuilder.append("isHeadset[in: " + parser.isInputHeadset()
                        + " , out: " + parser.isOutputHeadset() + "]");
                        + " , out: " + parser.isOutputHeadset() + "], isDock: " + parser.isDock());
                pw.println(stringBuilder.toString());
            } else {
                pw.println(formatTime() + " Disconnect " + mDeviceAddress);
@@ -198,9 +197,8 @@ public class UsbHostManager {
                    descriptor.report(canvas);
                }
                pw.println(stringBuilder.toString());

                pw.println("isHeadset[in: " + parser.isInputHeadset()
                        + " , out: " + parser.isOutputHeadset() + "]");
                        + " , out: " + parser.isOutputHeadset() + "], isDock: " + parser.isDock());
            } else {
                pw.println(formatTime() + " Disconnect " + mDeviceAddress);
            }
+31 −0
Original line number Diff line number Diff line
@@ -870,4 +870,35 @@ public final class UsbDescriptorParser {
        return getOutputHeadsetProbability() >= OUT_HEADSET_TRIGGER;
    }

    /**
     * isDock() indicates if the connected USB output peripheral is a docking station with
     * audio output.
     * A valid audio dock must declare only one audio output control terminal of type
     * TERMINAL_EXTERN_DIGITAL.
     */
    public boolean isDock() {
        if (hasMIDIInterface() || hasHIDInterface()) {
            return false;
        }

        ArrayList<UsbDescriptor> acDescriptors =
                getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL,
                        UsbACInterface.AUDIO_AUDIOCONTROL);

        if (acDescriptors.size() != 1) {
            return false;
        }

        if (acDescriptors.get(0) instanceof UsbACTerminal) {
            UsbACTerminal outDescr = (UsbACTerminal) acDescriptors.get(0);
            if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_EXTERN_DIGITAL) {
                return true;
            }
        } else {
            Log.w(TAG, "Undefined Audio Output terminal l: " + acDescriptors.get(0).getLength()
                    + " t:0x" + Integer.toHexString(acDescriptors.get(0).getType()));
        }
        return false;
    }

}