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
detectAudioHw()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
createAudioHw(bool local,bool playback,TaskCase * testCase)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
~AudioHardware()100 AudioHardware::~AudioHardware()
101 {
102
103 }
104
startPlaybackOrRecordById(const android::String8 & id,TaskCase * testCase)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