1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 #include <sys/types.h> 17 #include <regex.h> 18 #include <stdlib.h> 19 20 #include <tinyalsa/asoundlib.h> 21 22 #include "Log.h" 23 #include "StringUtil.h" 24 #include "SimpleScriptExec.h" 25 #include "audio/AudioHardware.h" 26 #include "audio/Buffer.h" 27 #include "audio/AudioPlaybackLocal.h" 28 #include "audio/AudioRecordingLocal.h" 29 #include "audio/AudioRemote.h" 30 #include "task/TaskCase.h" 31 32 int AudioHardware::mHwId = -1; 33 34 int AudioHardware::detectAudioHw() 35 { 36 android::String8 script("test_description/conf/detect_usb_audio.py"); 37 android::String8 param("MobilePre"); 38 android::String8 resultStr; 39 if (!SimpleScriptExec::runScript(script, param, resultStr)) { 40 LOGE("cannot run script"); 41 return -1; 42 } 43 44 android::String8 match("[ \t]+([A-Za-z0-9_]+)[ \t]+([0-9]+)"); 45 const int nmatch = 3; 46 regmatch_t pmatch[nmatch]; 47 if (!SimpleScriptExec::checkIfPassed(resultStr, match, nmatch, pmatch)) { 48 LOGE("result not correct %s", resultStr.string()); 49 return -1; 50 } 51 LOGV("pmatch 0: %d, %d 1:%d, %d 2:%d, %d", 52 pmatch[0].rm_so, pmatch[0].rm_eo, 53 pmatch[1].rm_so, pmatch[1].rm_eo, 54 pmatch[2].rm_so, pmatch[2].rm_eo); 55 56 if (pmatch[1].rm_so == -1) { 57 return -1; 58 } 59 if (pmatch[2].rm_so == -1) { 60 return -1; 61 } 62 android::String8 product = StringUtil::substr(resultStr, pmatch[1].rm_so, 63 pmatch[1].rm_eo - pmatch[1].rm_so); 64 LOGI("Audio device %s found", product.string()); 65 android::String8 cardNumber = StringUtil::substr(resultStr, pmatch[2].rm_so, 66 pmatch[2].rm_eo - pmatch[2].rm_so); 67 int cardN = atoi(cardNumber.string()); 68 LOGI("Card number : %d", cardN); 69 return cardN; 70 } 71 72 android::sp<AudioHardware> AudioHardware::createAudioHw(bool local, bool playback, 73 TaskCase* testCase) 74 { 75 android::sp<AudioHardware> hw; 76 if (local) { 77 if (mHwId < 0) { 78 mHwId = detectAudioHw(); 79 } 80 if (mHwId < 0) { 81 return NULL; 82 } 83 if (playback) { 84 hw = new AudioPlaybackLocal(mHwId); 85 } else { 86 hw = new AudioRecordingLocal(mHwId); 87 } 88 } else { 89 if (testCase != NULL) { 90 if (playback) { 91 hw = new AudioRemotePlayback(testCase->getRemoteAudio()); 92 } else { 93 hw = new AudioRemoteRecording(testCase->getRemoteAudio()); 94 } 95 } 96 } 97 return hw; 98 } 99 100 AudioHardware::~AudioHardware() 101 { 102 103 } 104 105 bool AudioHardware::startPlaybackOrRecordById(const android::String8& id, TaskCase* testCase) 106 { 107 if (testCase == NULL) { // default implementation only handles local buffer. 108 return false; 109 } 110 android::sp<Buffer> buffer = testCase->findBuffer(id); 111 if (buffer.get() == NULL) { 112 return false; 113 } 114 return startPlaybackOrRecord(buffer); 115 } 116