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

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

Merge changes from topic "usb_connect_protocol"

* changes:
  Optimize/streamline USB audio (dis)connect
  renamed UsbAudioDevice.java to UsbAlsaDevice.java
parents 146ea7f7 16d7913d
Loading
Loading
Loading
Loading
+64 −139
Original line number Diff line number Diff line
@@ -31,7 +31,9 @@ public class AlsaCardsParser {
    private static final String TAG = "AlsaCardsParser";
    protected static final boolean DEBUG = false;

    private static final String kCardsFilePath = "/proc/asound/cards";
    private static final String kAlsaFolderPath = "/proc/asound";
    private static final String kCardsFilePath = kAlsaFolderPath + "/cards";
    private static final String kDeviceAddressPrefix = "/dev/bus/usb/";

    private static LineTokenizer mTokenizer = new LineTokenizer(" :[]");

@@ -47,14 +49,31 @@ public class AlsaCardsParser {
        private static final String TAG = "AlsaCardRecord";
        private static final String kUsbCardKeyStr = "at usb-";

        public int mCardNum = -1;
        public String mField1 = "";
        public String mCardName = "";
        public String mCardDescription = "";
        public boolean mIsUsb = false;
        int mCardNum = -1;
        String mField1 = "";
        String mCardName = "";
        String mCardDescription = "";

        private String mUsbDeviceAddress = null;

        public AlsaCardRecord() {}

        public int getCardNum() {
            return mCardNum;
        }

        public String getCardName() {
            return mCardName;
        }

        public String getCardDescription() {
            return mCardDescription;
        }

        public void setDeviceAddress(String usbDeviceAddress) {
            mUsbDeviceAddress = usbDeviceAddress;
        }

        private boolean parse(String line, int lineIndex) {
            int tokenIndex = 0;
            int delimIndex = 0;
@@ -87,8 +106,8 @@ public class AlsaCardsParser {
                  tokenIndex = mTokenizer.nextToken(line, 0);
                  if (tokenIndex != -1) {
                      int keyIndex = line.indexOf(kUsbCardKeyStr);
                      mIsUsb = keyIndex != -1;
                      if (mIsUsb) {
                      boolean isUsb = keyIndex != -1;
                      if (isUsb) {
                          mCardDescription = line.substring(tokenIndex, keyIndex - 1);
                      }
                  }
@@ -97,14 +116,18 @@ public class AlsaCardsParser {
            return true;
        }

        boolean isUsb() {
            return mUsbDeviceAddress != null;
        }

        public String textFormat() {
          return mCardName + " : " + mCardDescription;
          return mCardName + " : " + mCardDescription + " [addr:" + mUsbDeviceAddress + "]";
        }

        public void log(int listIndex) {
            Slog.d(TAG, "" + listIndex +
                " [" + mCardNum + " " + mCardName + " : " + mCardDescription +
                " usb:" + mIsUsb);
                " usb:" + isUsb());
        }
    }

@@ -112,7 +135,7 @@ public class AlsaCardsParser {

    public int scan() {
        if (DEBUG) {
            Slog.i(TAG, "AlsaCardsParser.scan()....");
            Slog.d(TAG, "AlsaCardsParser.scan()....");
        }

        mCardRecords = new ArrayList<AlsaCardRecord>();
@@ -125,7 +148,7 @@ public class AlsaCardsParser {
            while ((line = bufferedReader.readLine()) != null) {
                AlsaCardRecord cardRecord = new AlsaCardRecord();
                if (DEBUG) {
                    Slog.i(TAG, "  " + line);
                    Slog.d(TAG, "  " + line);
                }
                cardRecord.parse(line, 0);

@@ -134,10 +157,23 @@ public class AlsaCardsParser {
                    break;
                }
                if (DEBUG) {
                    Slog.i(TAG, "  " + line);
                    Slog.d(TAG, "  " + line);
                }
                cardRecord.parse(line, 1);

                // scan "usbbus" file
                int cardNum = cardRecord.mCardNum;
                String cardFolderPath = kAlsaFolderPath + "/card" + cardNum;
                File usbbusFile = new File(cardFolderPath + "/usbbus");
                if (usbbusFile.exists()) {
                    // read it in
                    FileReader usbbusReader = new FileReader(usbbusFile);
                    String deviceAddress = (new BufferedReader(usbbusReader)).readLine();
                    if (deviceAddress != null) {
                        cardRecord.setDeviceAddress(kDeviceAddressPrefix + deviceAddress);
                    }
                    usbbusReader.close();
                }
                mCardRecords.add(cardRecord);
            }
            reader.close();
@@ -147,14 +183,12 @@ public class AlsaCardsParser {
                mScanStatus = SCANSTATUS_EMPTY;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            mScanStatus = SCANSTATUS_FAIL;
        } catch (IOException e) {
            e.printStackTrace();
            mScanStatus = SCANSTATUS_FAIL;
        }
        if (DEBUG) {
            Slog.i(TAG, "  status:" + mScanStatus);
            Slog.d(TAG, "  status:" + mScanStatus);
        }
        return mScanStatus;
    }
@@ -163,142 +197,33 @@ public class AlsaCardsParser {
        return mScanStatus;
    }

    public ArrayList<AlsaCardRecord> getScanRecords() {
        return mCardRecords;
    }

    public AlsaCardRecord getCardRecordAt(int index) {
        return mCardRecords.get(index);
    }

    public AlsaCardRecord getCardRecordFor(int cardNum) {
        for (AlsaCardRecord rec : mCardRecords) {
            if (rec.mCardNum == cardNum) {
                return rec;
    public AlsaCardRecord findCardNumFor(String deviceAddress) {
        for(AlsaCardRecord cardRec : mCardRecords) {
            if (cardRec.isUsb() && cardRec.mUsbDeviceAddress.equals(deviceAddress)) {
                return cardRec;
            }
        }

        return null;
    }

    public int getNumCardRecords() {
        return mCardRecords.size();
    }

    public boolean isCardUsb(int cardNum) {
        for (AlsaCardRecord rec : mCardRecords) {
            if (rec.mCardNum == cardNum) {
                return rec.mIsUsb;
            }
        }

        return false;
    }

    // return -1 if none found
    public int getDefaultUsbCard() {
        // save the current list of devices
        ArrayList<AlsaCardsParser.AlsaCardRecord> prevRecs = mCardRecords;
        if (DEBUG) {
            LogDevices("Previous Devices:", prevRecs);
        }

        // get the new list of devices
        if (scan() != SCANSTATUS_SUCCESS) {
            Slog.e(TAG, "Error scanning Alsa cards file.");
            return -1;
        }

        if (DEBUG) {
            LogDevices("Current Devices:", mCardRecords);
        }

        // Calculate the difference between the old and new device list
        ArrayList<AlsaCardRecord> newRecs = getNewCardRecords(prevRecs);
        if (DEBUG) {
            LogDevices("New Devices:", newRecs);
        }

        // Choose the most-recently added EXTERNAL card
        // Check recently added devices
        for (AlsaCardRecord rec : newRecs) {
            if (DEBUG) {
                Slog.d(TAG, rec.mCardName + " card:" + rec.mCardNum + " usb:" + rec.mIsUsb);
            }
            if (rec.mIsUsb) {
                // Found it
                return rec.mCardNum;
            }
        }

        // or return the first added EXTERNAL card?
        for (AlsaCardRecord rec : prevRecs) {
            if (DEBUG) {
                Slog.d(TAG, rec.mCardName + " card:" + rec.mCardNum + " usb:" + rec.mIsUsb);
            }
            if (rec.mIsUsb) {
                return rec.mCardNum;
            }
        }

        return -1;
    }

    public int getDefaultCard() {
        // return an external card if possible
        int card = getDefaultUsbCard();
        if (DEBUG) {
            Slog.d(TAG, "getDefaultCard() default usb card:" + card);
        }

        if (card < 0 && getNumCardRecords() > 0) {
            // otherwise return the (internal) card with the highest number
            card = getCardRecordAt(getNumCardRecords() - 1).mCardNum;
        }
        if (DEBUG) {
            Slog.d(TAG, "  returns card:" + card);
        }
        return card;
    }

    static public boolean hasCardNumber(ArrayList<AlsaCardRecord> recs, int cardNum) {
        for (AlsaCardRecord cardRec : recs) {
            if (cardRec.mCardNum == cardNum) {
                return true;
            }
        }
        return false;
    }

    public ArrayList<AlsaCardRecord> getNewCardRecords(ArrayList<AlsaCardRecord> prevScanRecs) {
        ArrayList<AlsaCardRecord> newRecs = new ArrayList<AlsaCardRecord>();
        for (AlsaCardRecord rec : mCardRecords) {
            // now scan to see if this card number is in the previous scan list
            if (!hasCardNumber(prevScanRecs, rec.mCardNum)) {
                newRecs.add(rec);
            }
        }
        return newRecs;
    }

    //
    // Logging
    //
    private void Log(String heading) {
        if (DEBUG) {
            Slog.i(TAG, heading);
            Slog.d(TAG, heading);
            for (AlsaCardRecord cardRec : mCardRecords) {
                Slog.i(TAG, cardRec.textFormat());
                Slog.d(TAG, cardRec.textFormat());
            }
        }
    }

    static private void LogDevices(String caption, ArrayList<AlsaCardRecord> deviceList) {
        Slog.d(TAG, caption + " ----------------");
        int listIndex = 0;
        for (AlsaCardRecord device : deviceList) {
            device.log(listIndex++);
        }
        Slog.d(TAG, "----------------");
    }
//    static private void LogDevices(String caption, ArrayList<AlsaCardRecord> deviceList) {
//        Slog.d(TAG, caption + " ----------------");
//        int listIndex = 0;
//        for (AlsaCardRecord device : deviceList) {
//            device.log(listIndex++);
//        }
//        Slog.d(TAG, caption + "----------------");
//    }
}
+4 −18
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ import java.util.ArrayList;
 * @hide
 * Retrieves information from an ALSA "devices" file.
 */
/*
 * NOTE: This class is currently not being used, but may be needed in the future.
 */
public class AlsaDevicesParser {
    private static final String TAG = "AlsaDevicesParser";
    protected static final boolean DEBUG = false;
@@ -207,12 +210,6 @@ public class AlsaDevicesParser {
    //
    // Predicates
    //
/*
   public boolean hasPlaybackDevices() {
        return mHasPlaybackDevices;
    }
*/

    public boolean hasPlaybackDevices(int card) {
        for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
            if (deviceRecord.mCardNum == card &&
@@ -224,12 +221,6 @@ public class AlsaDevicesParser {
        return false;
    }

/*
    public boolean hasCaptureDevices() {
        return mHasCaptureDevices;
    }
*/

    public boolean hasCaptureDevices(int card) {
        for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
            if (deviceRecord.mCardNum == card &&
@@ -241,12 +232,6 @@ public class AlsaDevicesParser {
        return false;
    }

/*
    public boolean hasMIDIDevices() {
        return mHasMIDIDevices;
    }
*/

    public boolean hasMIDIDevices(int card) {
        for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
            if (deviceRecord.mCardNum == card &&
@@ -280,6 +265,7 @@ public class AlsaDevicesParser {
                if (isLineDeviceRecord(line)) {
                    AlsaDeviceRecord deviceRecord = new AlsaDeviceRecord();
                    deviceRecord.parse(line);
                    Slog.i(TAG, deviceRecord.textFormat());
                    mDeviceRecords.add(deviceRecord);
                }
            }
+160 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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;

/**
 * Represents the ALSA specification, and attributes of an ALSA device.
 */
public final class UsbAlsaDevice {
    private static final String TAG = "UsbAlsaDevice";
    protected static final boolean DEBUG = false;

    private final int mCardNum;
    private final int mDeviceNum;
    private final boolean mHasPlayback;
    private final boolean mHasCapture;

    private final boolean mIsInputHeadset;
    private final boolean mIsOutputHeadset;

    private final String mDeviceAddress;

    private String mDeviceName = "";
    private String mDeviceDescription = "";

    public UsbAlsaDevice(int card, int device, String deviceAddress,
            boolean hasPlayback, boolean hasCapture,
            boolean isInputHeadset, boolean isOutputHeadset) {
        mCardNum = card;
        mDeviceNum = device;
        mDeviceAddress = deviceAddress;
        mHasPlayback = hasPlayback;
        mHasCapture = hasCapture;
        mIsInputHeadset = isInputHeadset;
        mIsOutputHeadset = isOutputHeadset;
    }

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

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

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

    /**
     * @returns true if the device supports playback.
     */
    public boolean hasPlayback() {
        return mHasPlayback;
    }

    /**
     * @returns true if the device supports capture (recording).
     */
    public boolean hasCapture() {
        return mHasCapture;
    }

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

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

    /**
     * @Override
     * @returns a string representation of the object.
     */
    public String toString() {
        return "UsbAlsaDevice: [card: " + mCardNum
            + ", device: " + mDeviceNum
            + ", name: " + mDeviceName
            + ", hasPlayback: " + mHasPlayback
            + ", hasCapture: " + mHasCapture + "]";
    }

    // called by logDevices
    String toShortString() {
        return "[card:" + mCardNum + " device:" + mDeviceNum + " " + mDeviceName + "]";
    }

    String getDeviceName() {
        return mDeviceName;
    }

    void setDeviceNameAndDescription(String deviceName, String deviceDescription) {
        mDeviceName = deviceName;
        mDeviceDescription = deviceDescription;
    }

    /**
     * @Override
     * @returns true if the objects are equivalent.
     */
    public boolean equals(Object obj) {
        if (!(obj instanceof UsbAlsaDevice)) {
            return false;
        }
        UsbAlsaDevice other = (UsbAlsaDevice) obj;
        return (mCardNum == other.mCardNum
                && mDeviceNum == other.mDeviceNum
                && mHasPlayback == other.mHasPlayback
                && mHasCapture == other.mHasCapture
                && mIsInputHeadset == other.mIsInputHeadset
                && mIsOutputHeadset == other.mIsOutputHeadset);
    }

    /**
     * @Override
     * @returns a hash code generated from the object contents.
     */
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + mCardNum;
        result = prime * result + mDeviceNum;
        result = prime * result + (mHasPlayback ? 0 : 1);
        result = prime * result + (mHasCapture ? 0 : 1);
        result = prime * result + (mIsInputHeadset ? 0 : 1);
        result = prime * result + (mIsOutputHeadset ? 0 : 1);

        return result;
    }
}
+131 −355

File changed.

Preview size limit exceeded, changes collapsed.

+0 −77
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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 an
 * limitations under the License.
 */

package com.android.server.usb;

public final class UsbAudioDevice {
    private static final String TAG = "UsbAudioDevice";
    protected static final boolean DEBUG = false;

    public final int mCard;
    public final int mDevice;
    public final boolean mHasPlayback;
    public final boolean mHasCapture;

    // Device "class" flags
    public static final int kAudioDeviceClassMask = 0x00FFFFFF;
    public static final int kAudioDeviceClass_Undefined = 0x00000000;
    public static final int kAudioDeviceClass_Internal = 0x00000001;
    public static final int kAudioDeviceClass_External = 0x00000002;
    // Device meta-data flags
    public static final int kAudioDeviceMetaMask = 0xFF000000;
    public static final int kAudioDeviceMeta_Alsa = 0x80000000;
    // This member is a combination of the above bit-flags
    public final int mDeviceClass;

    private String mDeviceName = "";
    private String mDeviceDescription = "";

    public UsbAudioDevice(int card, int device,
            boolean hasPlayback, boolean hasCapture, int deviceClass) {
        mCard = card;
        mDevice = device;
        mHasPlayback = hasPlayback;
        mHasCapture = hasCapture;
        mDeviceClass = deviceClass;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("UsbAudioDevice: [card: " + mCard);
        sb.append(", device: " + mDevice);
        sb.append(", name: " + mDeviceName);
        sb.append(", hasPlayback: " + mHasPlayback);
        sb.append(", hasCapture: " + mHasCapture);
        sb.append(", class: 0x" + Integer.toHexString(mDeviceClass) + "]");
        return sb.toString();
    }

    // called by logDevices
    String toShortString() {
        return "[card:" + mCard + " device:" + mDevice + " " + mDeviceName + "]";
    }

    String getDeviceName() {
        return mDeviceName;
    }

    void setDeviceNameAndDescription(String deviceName, String deviceDescription) {
        mDeviceName = deviceName;
        mDeviceDescription = deviceDescription;
    }

}
Loading