1c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean/*
2c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * Copyright (C) 2014 The Android Open Source Project
3c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean *
4c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * Licensed under the Apache License, Version 2.0 (the "License");
5c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * you may not use this file except in compliance with the License.
6c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * You may obtain a copy of the License at
7c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean *
8c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean *      http://www.apache.org/licenses/LICENSE-2.0
9c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean *
10c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * Unless required by applicable law or agreed to in writing, software
11c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * distributed under the License is distributed on an "AS IS" BASIS,
12c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * See the License for the specific language governing permissions and
14c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * limitations under the License.
15c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean */
16c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
17464c655871f4c1dd280474723e4b33f55044baa5Mike Lockwoodpackage com.android.internal.alsa;
18c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
19c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport android.util.Slog;
20c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.BufferedReader;
21c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.File;
22c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.FileNotFoundException;
23c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.FileReader;
24c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.IOException;
250a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLeanimport java.util.ArrayList;
26c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
27c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean/**
28c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * @hide Retrieves information from an ALSA "cards" file.
29c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean */
30c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanpublic class AlsaCardsParser {
31c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static final String TAG = "AlsaCardsParser";
32afe55a5ce96d7fe5e9e37dcd499336423bf87a06Paul McLean    protected static final boolean DEBUG = false;
33c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
34a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood    private static final String kCardsFilePath = "/proc/asound/cards";
35a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood
360a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    private static LineTokenizer mTokenizer = new LineTokenizer(" :[]");
370a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
380a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    private ArrayList<AlsaCardRecord> mCardRecords = new ArrayList<AlsaCardRecord>();
39c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
40c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    public class AlsaCardRecord {
410a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        private static final String TAG = "AlsaCardRecord";
420a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        private static final String kUsbCardKeyStr = "at usb-";
430a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
44c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public int mCardNum = -1;
45c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public String mField1 = "";
46c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public String mCardName = "";
47c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public String mCardDescription = "";
480a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        public boolean mIsUsb = false;
49c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
50c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public AlsaCardRecord() {}
51c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
52c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public boolean parse(String line, int lineIndex) {
53c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            int tokenIndex = 0;
54c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            int delimIndex = 0;
550a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
56c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            if (lineIndex == 0) {
57c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                // line # (skip)
580a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                tokenIndex = mTokenizer.nextToken(line, tokenIndex);
590a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                delimIndex = mTokenizer.nextDelimiter(line, tokenIndex);
600a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
61a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                try {
62a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    // mCardNum
63a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    mCardNum = Integer.parseInt(line.substring(tokenIndex, delimIndex));
64a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                } catch (NumberFormatException e) {
65a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    Slog.e(TAG, "Failed to parse line " + lineIndex + " of " + kCardsFilePath
66a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        + ": " + line.substring(tokenIndex, delimIndex));
67a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    return false;
68a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                }
69c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
70c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                // mField1
710a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                tokenIndex = mTokenizer.nextToken(line, delimIndex);
720a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                delimIndex = mTokenizer.nextDelimiter(line, tokenIndex);
73c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                mField1 = line.substring(tokenIndex, delimIndex);
74c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
75c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                // mCardName
760a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                tokenIndex = mTokenizer.nextToken(line, delimIndex);
77c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                mCardName = line.substring(tokenIndex);
780a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
79c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                // done
80c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean              } else if (lineIndex == 1) {
810a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                  tokenIndex = mTokenizer.nextToken(line, 0);
82c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                  if (tokenIndex != -1) {
8310804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean                      int keyIndex = line.indexOf(kUsbCardKeyStr);
8410804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean                      mIsUsb = keyIndex != -1;
8510804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean                      if (mIsUsb) {
8610804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean                          mCardDescription = line.substring(tokenIndex, keyIndex - 1);
8710804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean                      }
88c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                  }
89c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            }
90c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
91c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            return true;
92c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        }
93c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
94c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public String textFormat() {
95c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean          return mCardName + " : " + mCardDescription;
96c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        }
97c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean
98c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        public void log(int listIndex) {
99c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            Slog.d(TAG, "" + listIndex +
100c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean                " [" + mCardNum + " " + mCardName + " : " + mCardDescription +
101c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean                " usb:" + mIsUsb);
102c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        }
103c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    }
104c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
1050a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public AlsaCardsParser() {}
106c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
107c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    public void scan() {
1080a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        if (DEBUG) {
1090a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            Slog.i(TAG, "AlsaCardsParser.scan()");
1100a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
1110a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        mCardRecords = new ArrayList<AlsaCardRecord>();
1120a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
113a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood        File cardsFile = new File(kCardsFilePath);
1140a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        try {
1150a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            FileReader reader = new FileReader(cardsFile);
1160a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            BufferedReader bufferedReader = new BufferedReader(reader);
1170a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            String line = "";
1180a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            while ((line = bufferedReader.readLine()) != null) {
1190a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                AlsaCardRecord cardRecord = new AlsaCardRecord();
1200a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                if (DEBUG) {
1210a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                    Slog.i(TAG, "  " + line);
1220a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                }
1230a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                cardRecord.parse(line, 0);
1240a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1250a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                line = bufferedReader.readLine();
126f98e1c72fc77bd1708c5b1869b64510ae0179f85Mohamad Ayyash                if (line == null) {
127f98e1c72fc77bd1708c5b1869b64510ae0179f85Mohamad Ayyash                    break;
128f98e1c72fc77bd1708c5b1869b64510ae0179f85Mohamad Ayyash                }
1290a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                if (DEBUG) {
1300a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                    Slog.i(TAG, "  " + line);
1310a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                }
1320a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                cardRecord.parse(line, 1);
1330a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1340a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                mCardRecords.add(cardRecord);
1350a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            }
1360a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            reader.close();
1370a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        } catch (FileNotFoundException e) {
1380a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            e.printStackTrace();
1390a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        } catch (IOException e) {
1400a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            e.printStackTrace();
1410a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
142c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    }
143c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
1440a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public ArrayList<AlsaCardRecord> getScanRecords() {
1450a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return mCardRecords;
1460a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
1470a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1480a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public AlsaCardRecord getCardRecordAt(int index) {
1490a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return mCardRecords.get(index);
1500a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
1510a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1520a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public AlsaCardRecord getCardRecordFor(int cardNum) {
1530a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        for (AlsaCardRecord rec : mCardRecords) {
1540a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            if (rec.mCardNum == cardNum) {
1550a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                return rec;
1560a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            }
1570a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
1580a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1590a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return null;
1600a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
1610a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1620a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public int getNumCardRecords() {
1630a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return mCardRecords.size();
1640a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
1650a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1660a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public boolean isCardUsb(int cardNum) {
1670a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        for (AlsaCardRecord rec : mCardRecords) {
1680a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            if (rec.mCardNum == cardNum) {
1690a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                return rec.mIsUsb;
1700a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            }
1710a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
1720a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1730a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return false;
1740a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
1750a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
1760a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    // return -1 if none found
1770a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public int getDefaultUsbCard() {
178c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        // save the current list of devices
179c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        ArrayList<AlsaCardsParser.AlsaCardRecord> prevRecs = mCardRecords;
180c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        if (DEBUG) {
181c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            LogDevices("Previous Devices:", prevRecs);
182c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        }
183c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean
184c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        // get the new list of devices
185c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        scan();
186c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        if (DEBUG) {
187c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            LogDevices("Current Devices:", mCardRecords);
188c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        }
189c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean
190c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        // Calculate the difference between the old and new device list
191c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        ArrayList<AlsaCardRecord> newRecs = getNewCardRecords(prevRecs);
192c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        if (DEBUG) {
193c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            LogDevices("New Devices:", newRecs);
194c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        }
195c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean
1960a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        // Choose the most-recently added EXTERNAL card
197c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        // Check recently added devices
198c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        for (AlsaCardRecord rec : newRecs) {
199c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            if (DEBUG) {
200c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean                Slog.d(TAG, rec.mCardName + " card:" + rec.mCardNum + " usb:" + rec.mIsUsb);
201c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            }
202c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            if (rec.mIsUsb) {
203c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean                // Found it
204c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean                return rec.mCardNum;
205c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            }
206c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        }
207c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean
2080a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        // or return the first added EXTERNAL card?
209c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        for (AlsaCardRecord rec : prevRecs) {
210c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            if (DEBUG) {
211c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean                Slog.d(TAG, rec.mCardName + " card:" + rec.mCardNum + " usb:" + rec.mIsUsb);
212c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            }
2130a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            if (rec.mIsUsb) {
2140a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                return rec.mCardNum;
2150a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            }
2160a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
2170a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
2180a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return -1;
2190a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
2200a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
2210a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public int getDefaultCard() {
2220a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        // return an external card if possible
2230a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        int card = getDefaultUsbCard();
224c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        if (DEBUG) {
225c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            Slog.d(TAG, "getDefaultCard() default usb card:" + card);
226c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        }
2270a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
2280a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        if (card < 0 && getNumCardRecords() > 0) {
2290a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            // otherwise return the (internal) card with the highest number
2300a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            card = getCardRecordAt(getNumCardRecords() - 1).mCardNum;
2310a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
232c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        if (DEBUG) {
233c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            Slog.d(TAG, "  returns card:" + card);
234c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        }
2350a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return card;
2360a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
2370a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
2380a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    static public boolean hasCardNumber(ArrayList<AlsaCardRecord> recs, int cardNum) {
2390a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        for (AlsaCardRecord cardRec : recs) {
2400a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            if (cardRec.mCardNum == cardNum) {
2410a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                return true;
2420a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            }
2430a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
2440a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return false;
2450a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
2460a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
2470a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public ArrayList<AlsaCardRecord> getNewCardRecords(ArrayList<AlsaCardRecord> prevScanRecs) {
2480a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        ArrayList<AlsaCardRecord> newRecs = new ArrayList<AlsaCardRecord>();
2490a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        for (AlsaCardRecord rec : mCardRecords) {
2500a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            // now scan to see if this card number is in the previous scan list
2510a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            if (!hasCardNumber(prevScanRecs, rec.mCardNum)) {
2520a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                newRecs.add(rec);
2530a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            }
2540a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
2550a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return newRecs;
2560a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
2570a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
2580a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
2590a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    // Logging
2600a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
2610a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public void Log(String heading) {
2620a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        if (DEBUG) {
2630a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            Slog.i(TAG, heading);
2640a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            for (AlsaCardRecord cardRec : mCardRecords) {
2650a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                Slog.i(TAG, cardRec.textFormat());
2660a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            }
2670a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
2680a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
269c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean
270c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean    static public void LogDevices(String caption, ArrayList<AlsaCardRecord> deviceList) {
271c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        Slog.d(TAG, caption + " ----------------");
272c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        int listIndex = 0;
273c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        for (AlsaCardRecord device : deviceList) {
274c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean            device.log(listIndex++);
275c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        }
276c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean        Slog.d(TAG, "----------------");
277c15f75644385df59663cf2e9e6c6bf27fe228924Paul McLean    }
278c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean}
279