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 */
16464c655871f4c1dd280474723e4b33f55044baa5Mike Lockwoodpackage com.android.internal.alsa;
17c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
18c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport android.util.Slog;
19c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.BufferedReader;
20c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.File;
21c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.FileNotFoundException;
22c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.FileReader;
23c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanimport java.io.IOException;
240a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLeanimport java.util.ArrayList;
25c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
26c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean/**
27c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * @hide
28c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean * Retrieves information from an ALSA "devices" file.
29c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean */
3016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean/*
3116d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * NOTE: This class is currently not being used, but may be needed in the future.
3216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */
33c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLeanpublic class AlsaDevicesParser {
34c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static final String TAG = "AlsaDevicesParser";
350a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    protected static final boolean DEBUG = false;
36c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
37a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood    private static final String kDevicesFilePath = "/proc/asound/devices";
38a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood
39c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static final int kIndex_CardDeviceField = 5;
40c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static final int kStartIndex_CardNum = 6;
41c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static final int kEndIndex_CardNum = 8; // one past
42c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static final int kStartIndex_DeviceNum = 9;
43c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static final int kEndIndex_DeviceNum = 11; // one past
44c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static final int kStartIndex_Type = 14;
45c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
46c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private static LineTokenizer mTokenizer = new LineTokenizer(" :[]-");
47c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
48c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private boolean mHasCaptureDevices = false;
49c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private boolean mHasPlaybackDevices = false;
50c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    private boolean mHasMIDIDevices = false;
51c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
52fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean    public static final int SCANSTATUS_NOTSCANNED = -1;
53fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean    public static final int SCANSTATUS_SUCCESS = 0;
54fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean    public static final int SCANSTATUS_FAIL = 1;
55fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean    public static final int SCANSTATUS_EMPTY = 2;
56fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean    private int mScanStatus = SCANSTATUS_NOTSCANNED;
57fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean
58c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    public class AlsaDeviceRecord {
59c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public static final int kDeviceType_Unknown = -1;
60c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public static final int kDeviceType_Audio = 0;
61c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public static final int kDeviceType_Control = 1;
62c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public static final int kDeviceType_MIDI = 2;
63c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
64c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public static final int kDeviceDir_Unknown = -1;
65c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public static final int kDeviceDir_Capture = 0;
66c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public static final int kDeviceDir_Playback = 1;
67c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
68c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        int mCardNum = -1;
69c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        int mDeviceNum = -1;
70c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        int mDeviceType = kDeviceType_Unknown;
71c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        int mDeviceDir = kDeviceDir_Unknown;
72c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
730a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        public AlsaDeviceRecord() {}
74c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
75c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public boolean parse(String line) {
76c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            // "0123456789012345678901234567890"
77c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            // "  2: [ 0-31]: digital audio playback"
78c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            // "  3: [ 0-30]: digital audio capture"
79c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            // " 35: [ 1]   : control"
80c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            // " 36: [ 2- 0]: raw midi"
81c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
82c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            final int kToken_LineNum = 0;
83c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            final int kToken_CardNum = 1;
84c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            final int kToken_DeviceNum = 2;
85c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            final int kToken_Type0 = 3; // "digital", "control", "raw"
86c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            final int kToken_Type1 = 4; // "audio", "midi"
87c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            final int kToken_Type2 = 5; // "capture", "playback"
88c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
89c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            int tokenOffset = 0;
90c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            int delimOffset = 0;
91c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            int tokenIndex = kToken_LineNum;
92c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            while (true) {
93c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                tokenOffset = mTokenizer.nextToken(line, delimOffset);
94c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                if (tokenOffset == LineTokenizer.kTokenNotFound) {
95c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                    break; // bail
96c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                }
97c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                delimOffset = mTokenizer.nextDelimiter(line, tokenOffset);
98c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                if (delimOffset == LineTokenizer.kTokenNotFound) {
99c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                    delimOffset = line.length();
100c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                }
101c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                String token = line.substring(tokenOffset, delimOffset);
102c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
103a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                try {
104a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    switch (tokenIndex) {
105a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    case kToken_LineNum:
106a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        // ignore
107a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        break;
108a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood
109a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    case kToken_CardNum:
110788854b8c0b43d5b07f77cb65cf8303979cc50ffPaul Mclean                        mCardNum = Integer.parseInt(token);
111788854b8c0b43d5b07f77cb65cf8303979cc50ffPaul Mclean                        if (line.charAt(delimOffset) != '-') {
112788854b8c0b43d5b07f77cb65cf8303979cc50ffPaul Mclean                            tokenIndex++; // no device # in the token stream
113a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        }
114a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        break;
115a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood
116a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    case kToken_DeviceNum:
117788854b8c0b43d5b07f77cb65cf8303979cc50ffPaul Mclean                        mDeviceNum = Integer.parseInt(token);
118a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        break;
119a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood
120a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    case kToken_Type0:
121a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        if (token.equals("digital")) {
122a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            // NOP
123a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        } else if (token.equals("control")) {
124a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            mDeviceType = kDeviceType_Control;
125a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        } else if (token.equals("raw")) {
126a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            // NOP
127a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        }
128a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        break;
129a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood
130a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    case kToken_Type1:
131a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        if (token.equals("audio")) {
132a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            mDeviceType = kDeviceType_Audio;
133a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        } else if (token.equals("midi")) {
134a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            mDeviceType = kDeviceType_MIDI;
135a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            mHasMIDIDevices = true;
136a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        }
137a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        break;
138a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood
139a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    case kToken_Type2:
140a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        if (token.equals("capture")) {
141a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            mDeviceDir = kDeviceDir_Capture;
142a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            mHasCaptureDevices = true;
143a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        } else if (token.equals("playback")) {
144a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            mDeviceDir = kDeviceDir_Playback;
145a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                            mHasPlaybackDevices = true;
146a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        }
147a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        break;
148a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    } // switch (tokenIndex)
149a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                } catch (NumberFormatException e) {
150a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    Slog.e(TAG, "Failed to parse token " + tokenIndex + " of " + kDevicesFilePath
151a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                        + " token: " + token);
152a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                    return false;
153a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood                }
154c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
155c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                tokenIndex++;
156c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            } // while (true)
157c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
158c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            return true;
159c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        } // parse()
160c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
161c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        public String textFormat() {
162c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            StringBuilder sb = new StringBuilder();
163c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            sb.append("[" + mCardNum + ":" + mDeviceNum + "]");
164c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
165c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            switch (mDeviceType) {
166c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            case kDeviceType_Unknown:
167b4b81de5764c36edf67b5e311c7681c0d4fd00bcGlenn Kasten            default:
168c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                sb.append(" N/A");
169c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                break;
170c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            case kDeviceType_Audio:
171c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                sb.append(" Audio");
172c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                break;
173c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            case kDeviceType_Control:
174c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                sb.append(" Control");
175c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                break;
176c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            case kDeviceType_MIDI:
177c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                sb.append(" MIDI");
178c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                break;
179c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            }
180c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
181c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            switch (mDeviceDir) {
182c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            case kDeviceDir_Unknown:
183b4b81de5764c36edf67b5e311c7681c0d4fd00bcGlenn Kasten            default:
184c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                sb.append(" N/A");
185c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                break;
186c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            case kDeviceDir_Capture:
187c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                sb.append(" Capture");
188c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                break;
189c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            case kDeviceDir_Playback:
190c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                sb.append(" Playback");
191c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                break;
192c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            }
193c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
194c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            return sb.toString();
195c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        }
196c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    }
197c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
198ff6615f653dab13c4ac482430af26ac08c2ba891Glenn Kasten    private final ArrayList<AlsaDeviceRecord> mDeviceRecords = new ArrayList<AlsaDeviceRecord>();
199c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
2000a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public AlsaDevicesParser() {}
201c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
2020a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
2030a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    // Access
2040a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
2050a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    public int getDefaultDeviceNum(int card) {
2060a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        // TODO - This (obviously) isn't sufficient. Revisit.
2070a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return 0;
208c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    }
209c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
2100a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
2110a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    // Predicates
2120a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
213df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean    public boolean hasPlaybackDevices(int card) {
2140a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
215df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean            if (deviceRecord.mCardNum == card &&
216df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean                deviceRecord.mDeviceType == AlsaDeviceRecord.kDeviceType_Audio &&
217df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean                deviceRecord.mDeviceDir == AlsaDeviceRecord.kDeviceDir_Playback) {
218df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean                return true;
219df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean            }
220df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean        }
221df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean        return false;
222df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean    }
223df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean
224df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean    public boolean hasCaptureDevices(int card) {
2250a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
226df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean            if (deviceRecord.mCardNum == card &&
227df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean                deviceRecord.mDeviceType == AlsaDeviceRecord.kDeviceType_Audio &&
228df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean                deviceRecord.mDeviceDir == AlsaDeviceRecord.kDeviceDir_Capture) {
229df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean                return true;
230df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean            }
231df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean        }
232df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean        return false;
233df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean    }
234df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean
235df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean    public boolean hasMIDIDevices(int card) {
2360a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
237df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean            if (deviceRecord.mCardNum == card &&
238df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean                deviceRecord.mDeviceType == AlsaDeviceRecord.kDeviceType_MIDI) {
239df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean                return true;
240df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean            }
241df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean        }
242df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean        return false;
243df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean    }
244df3614693dd4fe52a116dcd28bd74eae80818a4fPaul McLean
2450a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
2460a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    // Process
2470a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
2480a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    private boolean isLineDeviceRecord(String line) {
2490a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        return line.charAt(kIndex_CardDeviceField) == '[';
2500a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
2510a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
252fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean    public int scan() {
253fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean        if (DEBUG) {
254fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean            Slog.i(TAG, "AlsaDevicesParser.scan()....");
255fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean        }
256fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean
2570a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        mDeviceRecords.clear();
258c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
259a1329aebe7ef21f18826d495b0df7fdbec1ae096Mike Lockwood        File devicesFile = new File(kDevicesFilePath);
260c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        try {
261c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            FileReader reader = new FileReader(devicesFile);
262c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            BufferedReader bufferedReader = new BufferedReader(reader);
263c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            String line = "";
264c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            while ((line = bufferedReader.readLine()) != null) {
265c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                if (isLineDeviceRecord(line)) {
266c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                    AlsaDeviceRecord deviceRecord = new AlsaDeviceRecord();
267c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                    deviceRecord.parse(line);
26816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean                    Slog.i(TAG, deviceRecord.textFormat());
2690a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                    mDeviceRecords.add(deviceRecord);
270c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean                }
271c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            }
272c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            reader.close();
273fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean            // success if we add at least 1 record
274fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean            if (mDeviceRecords.size() > 0) {
275fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean                mScanStatus = SCANSTATUS_SUCCESS;
276fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean            } else {
277fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean                mScanStatus = SCANSTATUS_EMPTY;
278fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean            }
279c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        } catch (FileNotFoundException e) {
280c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            e.printStackTrace();
281fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean            mScanStatus = SCANSTATUS_FAIL;
282c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        } catch (IOException e) {
283c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean            e.printStackTrace();
284fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean            mScanStatus = SCANSTATUS_FAIL;
285c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean        }
286fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean        if (DEBUG) {
287fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean            Slog.i(TAG, "  status:" + mScanStatus);
288fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean        }
289fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean        return mScanStatus;
290fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean    }
291fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean
292fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean    public int getScanStatus() {
293fd47f4032da128e78d605e10f9e67786b08a14e2Paul McLean        return mScanStatus;
294c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean    }
2950a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean
2960a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
2970a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    // Loging
2980a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    //
29920137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten    private void Log(String heading) {
3000a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        if (DEBUG) {
3010a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            Slog.i(TAG, heading);
3020a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
3030a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean                Slog.i(TAG, deviceRecord.textFormat());
3040a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean            }
3050a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean        }
3060a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean    }
307c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean} // class AlsaDevicesParser
308c837a451946b64d70ed7c642fbde03c182c28b6fPaul McLean
309