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