• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.alsa;
18 
19 import android.util.Slog;
20 import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.FileNotFoundException;
23 import java.io.FileReader;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 
27 /**
28  * @hide Retrieves information from an ALSA "cards" file.
29  */
30 public class AlsaCardsParser {
31     private static final String TAG = "AlsaCardsParser";
32     protected static final boolean DEBUG = false;
33 
34     private static final String kAlsaFolderPath = "/proc/asound";
35     private static final String kCardsFilePath = kAlsaFolderPath + "/cards";
36     private static final String kDeviceAddressPrefix = "/dev/bus/usb/";
37 
38     private static LineTokenizer mTokenizer = new LineTokenizer(" :[]");
39 
40     private ArrayList<AlsaCardRecord> mCardRecords = new ArrayList<AlsaCardRecord>();
41 
42     public static final int SCANSTATUS_NOTSCANNED = -1;
43     public static final int SCANSTATUS_SUCCESS = 0;
44     public static final int SCANSTATUS_FAIL = 1;
45     public static final int SCANSTATUS_EMPTY = 2;
46     private int mScanStatus = SCANSTATUS_NOTSCANNED;
47 
48     public class AlsaCardRecord {
49         private static final String TAG = "AlsaCardRecord";
50         private static final String kUsbCardKeyStr = "at usb-";
51 
52         int mCardNum = -1;
53         String mField1 = "";
54         String mCardName = "";
55         String mCardDescription = "";
56 
57         private String mUsbDeviceAddress = null;
58 
AlsaCardRecord()59         public AlsaCardRecord() {}
60 
getCardNum()61         public int getCardNum() {
62             return mCardNum;
63         }
64 
getCardName()65         public String getCardName() {
66             return mCardName;
67         }
68 
getCardDescription()69         public String getCardDescription() {
70             return mCardDescription;
71         }
72 
setDeviceAddress(String usbDeviceAddress)73         public void setDeviceAddress(String usbDeviceAddress) {
74             mUsbDeviceAddress = usbDeviceAddress;
75         }
76 
parse(String line, int lineIndex)77         private boolean parse(String line, int lineIndex) {
78             int tokenIndex = 0;
79             int delimIndex = 0;
80 
81             if (lineIndex == 0) {
82                 // line # (skip)
83                 tokenIndex = mTokenizer.nextToken(line, tokenIndex);
84                 delimIndex = mTokenizer.nextDelimiter(line, tokenIndex);
85 
86                 try {
87                     // mCardNum
88                     mCardNum = Integer.parseInt(line.substring(tokenIndex, delimIndex));
89                 } catch (NumberFormatException e) {
90                     Slog.e(TAG, "Failed to parse line " + lineIndex + " of " + kCardsFilePath
91                         + ": " + line.substring(tokenIndex, delimIndex));
92                     return false;
93                 }
94 
95                 // mField1
96                 tokenIndex = mTokenizer.nextToken(line, delimIndex);
97                 delimIndex = mTokenizer.nextDelimiter(line, tokenIndex);
98                 mField1 = line.substring(tokenIndex, delimIndex);
99 
100                 // mCardName
101                 tokenIndex = mTokenizer.nextToken(line, delimIndex);
102                 mCardName = line.substring(tokenIndex);
103 
104                 // done
105               } else if (lineIndex == 1) {
106                   tokenIndex = mTokenizer.nextToken(line, 0);
107                   if (tokenIndex != -1) {
108                       int keyIndex = line.indexOf(kUsbCardKeyStr);
109                       boolean isUsb = keyIndex != -1;
110                       if (isUsb) {
111                           mCardDescription = line.substring(tokenIndex, keyIndex - 1);
112                       }
113                   }
114             }
115 
116             return true;
117         }
118 
isUsb()119         boolean isUsb() {
120             return mUsbDeviceAddress != null;
121         }
122 
textFormat()123         public String textFormat() {
124           return mCardName + " : " + mCardDescription + " [addr:" + mUsbDeviceAddress + "]";
125         }
126 
log(int listIndex)127         public void log(int listIndex) {
128             Slog.d(TAG, "" + listIndex +
129                 " [" + mCardNum + " " + mCardName + " : " + mCardDescription +
130                 " usb:" + isUsb());
131         }
132     }
133 
AlsaCardsParser()134     public AlsaCardsParser() {}
135 
scan()136     public int scan() {
137         if (DEBUG) {
138             Slog.d(TAG, "AlsaCardsParser.scan()....");
139         }
140 
141         mCardRecords = new ArrayList<AlsaCardRecord>();
142 
143         File cardsFile = new File(kCardsFilePath);
144         try {
145             FileReader reader = new FileReader(cardsFile);
146             BufferedReader bufferedReader = new BufferedReader(reader);
147             String line = "";
148             while ((line = bufferedReader.readLine()) != null) {
149                 AlsaCardRecord cardRecord = new AlsaCardRecord();
150                 if (DEBUG) {
151                     Slog.d(TAG, "  " + line);
152                 }
153                 cardRecord.parse(line, 0);
154 
155                 line = bufferedReader.readLine();
156                 if (line == null) {
157                     break;
158                 }
159                 if (DEBUG) {
160                     Slog.d(TAG, "  " + line);
161                 }
162                 cardRecord.parse(line, 1);
163 
164                 // scan "usbbus" file
165                 int cardNum = cardRecord.mCardNum;
166                 String cardFolderPath = kAlsaFolderPath + "/card" + cardNum;
167                 File usbbusFile = new File(cardFolderPath + "/usbbus");
168                 if (usbbusFile.exists()) {
169                     // read it in
170                     FileReader usbbusReader = new FileReader(usbbusFile);
171                     String deviceAddress = (new BufferedReader(usbbusReader)).readLine();
172                     if (deviceAddress != null) {
173                         cardRecord.setDeviceAddress(kDeviceAddressPrefix + deviceAddress);
174                     }
175                     usbbusReader.close();
176                 }
177                 mCardRecords.add(cardRecord);
178             }
179             reader.close();
180             if (mCardRecords.size() > 0) {
181                 mScanStatus = SCANSTATUS_SUCCESS;
182             } else {
183                 mScanStatus = SCANSTATUS_EMPTY;
184             }
185         } catch (FileNotFoundException e) {
186             mScanStatus = SCANSTATUS_FAIL;
187         } catch (IOException e) {
188             mScanStatus = SCANSTATUS_FAIL;
189         }
190         if (DEBUG) {
191             Slog.d(TAG, "  status:" + mScanStatus);
192         }
193         return mScanStatus;
194     }
195 
getScanStatus()196     public int getScanStatus() {
197         return mScanStatus;
198     }
199 
findCardNumFor(String deviceAddress)200     public AlsaCardRecord findCardNumFor(String deviceAddress) {
201         for(AlsaCardRecord cardRec : mCardRecords) {
202             if (cardRec.isUsb() && cardRec.mUsbDeviceAddress.equals(deviceAddress)) {
203                 return cardRec;
204             }
205         }
206         return null;
207     }
208 
209     //
210     // Logging
211     //
Log(String heading)212     private void Log(String heading) {
213         if (DEBUG) {
214             Slog.d(TAG, heading);
215             for (AlsaCardRecord cardRec : mCardRecords) {
216                 Slog.d(TAG, cardRec.textFormat());
217             }
218         }
219     }
220 
221 //    static private void LogDevices(String caption, ArrayList<AlsaCardRecord> deviceList) {
222 //        Slog.d(TAG, caption + " ----------------");
223 //        int listIndex = 0;
224 //        for (AlsaCardRecord device : deviceList) {
225 //            device.log(listIndex++);
226 //        }
227 //        Slog.d(TAG, caption + "----------------");
228 //    }
229 }
230