1*79330504STreehugger Robot /*
2*79330504STreehugger Robot **
3*79330504STreehugger Robot ** Copyright 2007, The Android Open Source Project
4*79330504STreehugger Robot **
5*79330504STreehugger Robot ** Licensed under the Apache License, Version 2.0 (the "License");
6*79330504STreehugger Robot ** you may not use this file except in compliance with the License.
7*79330504STreehugger Robot ** You may obtain a copy of the License at
8*79330504STreehugger Robot **
9*79330504STreehugger Robot ** http://www.apache.org/licenses/LICENSE-2.0
10*79330504STreehugger Robot **
11*79330504STreehugger Robot ** Unless required by applicable law or agreed to in writing, software
12*79330504STreehugger Robot ** distributed under the License is distributed on an "AS IS" BASIS,
13*79330504STreehugger Robot ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*79330504STreehugger Robot ** See the License for the specific language governing permissions and
15*79330504STreehugger Robot ** limitations under the License.
16*79330504STreehugger Robot */
17*79330504STreehugger Robot
18*79330504STreehugger Robot #include <stdint.h>
19*79330504STreehugger Robot #include <sys/types.h>
20*79330504STreehugger Robot
21*79330504STreehugger Robot #include <stdlib.h>
22*79330504STreehugger Robot #include <stdio.h>
23*79330504STreehugger Robot #include <unistd.h>
24*79330504STreehugger Robot #include <sched.h>
25*79330504STreehugger Robot #include <fcntl.h>
26*79330504STreehugger Robot #include <sys/ioctl.h>
27*79330504STreehugger Robot
28*79330504STreehugger Robot #define LOG_TAG "AudioHardware"
29*79330504STreehugger Robot #include <utils/Log.h>
30*79330504STreehugger Robot #include <utils/String8.h>
31*79330504STreehugger Robot
32*79330504STreehugger Robot #include "AudioHardwareGeneric.h"
33*79330504STreehugger Robot #include <media/AudioRecord.h>
34*79330504STreehugger Robot
35*79330504STreehugger Robot #include <hardware_legacy/AudioSystemLegacy.h>
36*79330504STreehugger Robot
37*79330504STreehugger Robot namespace android_audio_legacy {
38*79330504STreehugger Robot
39*79330504STreehugger Robot // ----------------------------------------------------------------------------
40*79330504STreehugger Robot
41*79330504STreehugger Robot static char const * const kAudioDeviceName = "/dev/eac";
42*79330504STreehugger Robot
43*79330504STreehugger Robot // ----------------------------------------------------------------------------
44*79330504STreehugger Robot
AudioHardwareGeneric()45*79330504STreehugger Robot AudioHardwareGeneric::AudioHardwareGeneric()
46*79330504STreehugger Robot : mOutput(0), mInput(0), mFd(-1), mMicMute(false)
47*79330504STreehugger Robot {
48*79330504STreehugger Robot mFd = ::open(kAudioDeviceName, O_RDWR);
49*79330504STreehugger Robot }
50*79330504STreehugger Robot
~AudioHardwareGeneric()51*79330504STreehugger Robot AudioHardwareGeneric::~AudioHardwareGeneric()
52*79330504STreehugger Robot {
53*79330504STreehugger Robot if (mFd >= 0) ::close(mFd);
54*79330504STreehugger Robot closeOutputStream((AudioStreamOut *)mOutput);
55*79330504STreehugger Robot closeInputStream((AudioStreamIn *)mInput);
56*79330504STreehugger Robot }
57*79330504STreehugger Robot
initCheck()58*79330504STreehugger Robot status_t AudioHardwareGeneric::initCheck()
59*79330504STreehugger Robot {
60*79330504STreehugger Robot if (mFd >= 0) {
61*79330504STreehugger Robot if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
62*79330504STreehugger Robot return NO_ERROR;
63*79330504STreehugger Robot }
64*79330504STreehugger Robot return NO_INIT;
65*79330504STreehugger Robot }
66*79330504STreehugger Robot
openOutputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status)67*79330504STreehugger Robot AudioStreamOut* AudioHardwareGeneric::openOutputStream(
68*79330504STreehugger Robot uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
69*79330504STreehugger Robot {
70*79330504STreehugger Robot AutoMutex lock(mLock);
71*79330504STreehugger Robot
72*79330504STreehugger Robot // only one output stream allowed
73*79330504STreehugger Robot if (mOutput) {
74*79330504STreehugger Robot if (status) {
75*79330504STreehugger Robot *status = INVALID_OPERATION;
76*79330504STreehugger Robot }
77*79330504STreehugger Robot return 0;
78*79330504STreehugger Robot }
79*79330504STreehugger Robot
80*79330504STreehugger Robot // create new output stream
81*79330504STreehugger Robot AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
82*79330504STreehugger Robot status_t lStatus = out->set(this, mFd, devices, format, channels, sampleRate);
83*79330504STreehugger Robot if (status) {
84*79330504STreehugger Robot *status = lStatus;
85*79330504STreehugger Robot }
86*79330504STreehugger Robot if (lStatus == NO_ERROR) {
87*79330504STreehugger Robot mOutput = out;
88*79330504STreehugger Robot } else {
89*79330504STreehugger Robot delete out;
90*79330504STreehugger Robot }
91*79330504STreehugger Robot return mOutput;
92*79330504STreehugger Robot }
93*79330504STreehugger Robot
closeOutputStream(AudioStreamOut * out)94*79330504STreehugger Robot void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) {
95*79330504STreehugger Robot if (mOutput && out == mOutput) {
96*79330504STreehugger Robot delete mOutput;
97*79330504STreehugger Robot mOutput = 0;
98*79330504STreehugger Robot }
99*79330504STreehugger Robot }
100*79330504STreehugger Robot
openInputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status,AudioSystem::audio_in_acoustics acoustics)101*79330504STreehugger Robot AudioStreamIn* AudioHardwareGeneric::openInputStream(
102*79330504STreehugger Robot uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
103*79330504STreehugger Robot status_t *status, AudioSystem::audio_in_acoustics acoustics)
104*79330504STreehugger Robot {
105*79330504STreehugger Robot // check for valid input source
106*79330504STreehugger Robot if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
107*79330504STreehugger Robot return 0;
108*79330504STreehugger Robot }
109*79330504STreehugger Robot
110*79330504STreehugger Robot AutoMutex lock(mLock);
111*79330504STreehugger Robot
112*79330504STreehugger Robot // only one input stream allowed
113*79330504STreehugger Robot if (mInput) {
114*79330504STreehugger Robot if (status) {
115*79330504STreehugger Robot *status = INVALID_OPERATION;
116*79330504STreehugger Robot }
117*79330504STreehugger Robot return 0;
118*79330504STreehugger Robot }
119*79330504STreehugger Robot
120*79330504STreehugger Robot // create new output stream
121*79330504STreehugger Robot AudioStreamInGeneric* in = new AudioStreamInGeneric();
122*79330504STreehugger Robot status_t lStatus = in->set(this, mFd, devices, format, channels, sampleRate, acoustics);
123*79330504STreehugger Robot if (status) {
124*79330504STreehugger Robot *status = lStatus;
125*79330504STreehugger Robot }
126*79330504STreehugger Robot if (lStatus == NO_ERROR) {
127*79330504STreehugger Robot mInput = in;
128*79330504STreehugger Robot } else {
129*79330504STreehugger Robot delete in;
130*79330504STreehugger Robot }
131*79330504STreehugger Robot return mInput;
132*79330504STreehugger Robot }
133*79330504STreehugger Robot
closeInputStream(AudioStreamIn * in)134*79330504STreehugger Robot void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) {
135*79330504STreehugger Robot if (mInput && in == mInput) {
136*79330504STreehugger Robot delete mInput;
137*79330504STreehugger Robot mInput = 0;
138*79330504STreehugger Robot }
139*79330504STreehugger Robot }
140*79330504STreehugger Robot
setVoiceVolume(float v)141*79330504STreehugger Robot status_t AudioHardwareGeneric::setVoiceVolume(float v)
142*79330504STreehugger Robot {
143*79330504STreehugger Robot // Implement: set voice volume
144*79330504STreehugger Robot return NO_ERROR;
145*79330504STreehugger Robot }
146*79330504STreehugger Robot
setMasterVolume(float v)147*79330504STreehugger Robot status_t AudioHardwareGeneric::setMasterVolume(float v)
148*79330504STreehugger Robot {
149*79330504STreehugger Robot // Implement: set master volume
150*79330504STreehugger Robot // return error - software mixer will handle it
151*79330504STreehugger Robot return INVALID_OPERATION;
152*79330504STreehugger Robot }
153*79330504STreehugger Robot
setMicMute(bool state)154*79330504STreehugger Robot status_t AudioHardwareGeneric::setMicMute(bool state)
155*79330504STreehugger Robot {
156*79330504STreehugger Robot mMicMute = state;
157*79330504STreehugger Robot return NO_ERROR;
158*79330504STreehugger Robot }
159*79330504STreehugger Robot
getMicMute(bool * state)160*79330504STreehugger Robot status_t AudioHardwareGeneric::getMicMute(bool* state)
161*79330504STreehugger Robot {
162*79330504STreehugger Robot *state = mMicMute;
163*79330504STreehugger Robot return NO_ERROR;
164*79330504STreehugger Robot }
165*79330504STreehugger Robot
dumpInternals(int fd,const Vector<String16> & args)166*79330504STreehugger Robot status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
167*79330504STreehugger Robot {
168*79330504STreehugger Robot const size_t SIZE = 256;
169*79330504STreehugger Robot char buffer[SIZE];
170*79330504STreehugger Robot String8 result;
171*79330504STreehugger Robot result.append("AudioHardwareGeneric::dumpInternals\n");
172*79330504STreehugger Robot snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n", mFd, mMicMute? "true": "false");
173*79330504STreehugger Robot result.append(buffer);
174*79330504STreehugger Robot ::write(fd, result.string(), result.size());
175*79330504STreehugger Robot return NO_ERROR;
176*79330504STreehugger Robot }
177*79330504STreehugger Robot
dump(int fd,const Vector<String16> & args)178*79330504STreehugger Robot status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
179*79330504STreehugger Robot {
180*79330504STreehugger Robot dumpInternals(fd, args);
181*79330504STreehugger Robot if (mInput) {
182*79330504STreehugger Robot mInput->dump(fd, args);
183*79330504STreehugger Robot }
184*79330504STreehugger Robot if (mOutput) {
185*79330504STreehugger Robot mOutput->dump(fd, args);
186*79330504STreehugger Robot }
187*79330504STreehugger Robot return NO_ERROR;
188*79330504STreehugger Robot }
189*79330504STreehugger Robot
190*79330504STreehugger Robot // ----------------------------------------------------------------------------
191*79330504STreehugger Robot
set(AudioHardwareGeneric * hw,int fd,uint32_t devices,int * pFormat,uint32_t * pChannels,uint32_t * pRate)192*79330504STreehugger Robot status_t AudioStreamOutGeneric::set(
193*79330504STreehugger Robot AudioHardwareGeneric *hw,
194*79330504STreehugger Robot int fd,
195*79330504STreehugger Robot uint32_t devices,
196*79330504STreehugger Robot int *pFormat,
197*79330504STreehugger Robot uint32_t *pChannels,
198*79330504STreehugger Robot uint32_t *pRate)
199*79330504STreehugger Robot {
200*79330504STreehugger Robot int lFormat = pFormat ? *pFormat : 0;
201*79330504STreehugger Robot uint32_t lChannels = pChannels ? *pChannels : 0;
202*79330504STreehugger Robot uint32_t lRate = pRate ? *pRate : 0;
203*79330504STreehugger Robot
204*79330504STreehugger Robot // fix up defaults
205*79330504STreehugger Robot if (lFormat == 0) lFormat = format();
206*79330504STreehugger Robot if (lChannels == 0) lChannels = channels();
207*79330504STreehugger Robot if (lRate == 0) lRate = sampleRate();
208*79330504STreehugger Robot
209*79330504STreehugger Robot // check values
210*79330504STreehugger Robot if ((lFormat != format()) ||
211*79330504STreehugger Robot (lChannels != channels()) ||
212*79330504STreehugger Robot (lRate != sampleRate())) {
213*79330504STreehugger Robot if (pFormat) *pFormat = format();
214*79330504STreehugger Robot if (pChannels) *pChannels = channels();
215*79330504STreehugger Robot if (pRate) *pRate = sampleRate();
216*79330504STreehugger Robot return BAD_VALUE;
217*79330504STreehugger Robot }
218*79330504STreehugger Robot
219*79330504STreehugger Robot if (pFormat) *pFormat = lFormat;
220*79330504STreehugger Robot if (pChannels) *pChannels = lChannels;
221*79330504STreehugger Robot if (pRate) *pRate = lRate;
222*79330504STreehugger Robot
223*79330504STreehugger Robot mAudioHardware = hw;
224*79330504STreehugger Robot mFd = fd;
225*79330504STreehugger Robot mDevice = devices;
226*79330504STreehugger Robot return NO_ERROR;
227*79330504STreehugger Robot }
228*79330504STreehugger Robot
~AudioStreamOutGeneric()229*79330504STreehugger Robot AudioStreamOutGeneric::~AudioStreamOutGeneric()
230*79330504STreehugger Robot {
231*79330504STreehugger Robot }
232*79330504STreehugger Robot
write(const void * buffer,size_t bytes)233*79330504STreehugger Robot ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
234*79330504STreehugger Robot {
235*79330504STreehugger Robot Mutex::Autolock _l(mLock);
236*79330504STreehugger Robot return ssize_t(::write(mFd, buffer, bytes));
237*79330504STreehugger Robot }
238*79330504STreehugger Robot
standby()239*79330504STreehugger Robot status_t AudioStreamOutGeneric::standby()
240*79330504STreehugger Robot {
241*79330504STreehugger Robot // Implement: audio hardware to standby mode
242*79330504STreehugger Robot return NO_ERROR;
243*79330504STreehugger Robot }
244*79330504STreehugger Robot
dump(int fd,const Vector<String16> & args)245*79330504STreehugger Robot status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
246*79330504STreehugger Robot {
247*79330504STreehugger Robot const size_t SIZE = 256;
248*79330504STreehugger Robot char buffer[SIZE];
249*79330504STreehugger Robot String8 result;
250*79330504STreehugger Robot snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
251*79330504STreehugger Robot result.append(buffer);
252*79330504STreehugger Robot snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
253*79330504STreehugger Robot result.append(buffer);
254*79330504STreehugger Robot snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
255*79330504STreehugger Robot result.append(buffer);
256*79330504STreehugger Robot snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
257*79330504STreehugger Robot result.append(buffer);
258*79330504STreehugger Robot snprintf(buffer, SIZE, "\tformat: %d\n", format());
259*79330504STreehugger Robot result.append(buffer);
260*79330504STreehugger Robot snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
261*79330504STreehugger Robot result.append(buffer);
262*79330504STreehugger Robot snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
263*79330504STreehugger Robot result.append(buffer);
264*79330504STreehugger Robot snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
265*79330504STreehugger Robot result.append(buffer);
266*79330504STreehugger Robot ::write(fd, result.string(), result.size());
267*79330504STreehugger Robot return NO_ERROR;
268*79330504STreehugger Robot }
269*79330504STreehugger Robot
setParameters(const String8 & keyValuePairs)270*79330504STreehugger Robot status_t AudioStreamOutGeneric::setParameters(const String8& keyValuePairs)
271*79330504STreehugger Robot {
272*79330504STreehugger Robot AudioParameter param = AudioParameter(keyValuePairs);
273*79330504STreehugger Robot String8 key = String8(AudioParameter::keyRouting);
274*79330504STreehugger Robot status_t status = NO_ERROR;
275*79330504STreehugger Robot int device;
276*79330504STreehugger Robot ALOGV("setParameters() %s", keyValuePairs.string());
277*79330504STreehugger Robot
278*79330504STreehugger Robot if (param.getInt(key, device) == NO_ERROR) {
279*79330504STreehugger Robot mDevice = device;
280*79330504STreehugger Robot param.remove(key);
281*79330504STreehugger Robot }
282*79330504STreehugger Robot
283*79330504STreehugger Robot if (param.size()) {
284*79330504STreehugger Robot status = BAD_VALUE;
285*79330504STreehugger Robot }
286*79330504STreehugger Robot return status;
287*79330504STreehugger Robot }
288*79330504STreehugger Robot
getParameters(const String8 & keys)289*79330504STreehugger Robot String8 AudioStreamOutGeneric::getParameters(const String8& keys)
290*79330504STreehugger Robot {
291*79330504STreehugger Robot AudioParameter param = AudioParameter(keys);
292*79330504STreehugger Robot String8 value;
293*79330504STreehugger Robot String8 key = String8(AudioParameter::keyRouting);
294*79330504STreehugger Robot
295*79330504STreehugger Robot if (param.get(key, value) == NO_ERROR) {
296*79330504STreehugger Robot param.addInt(key, (int)mDevice);
297*79330504STreehugger Robot }
298*79330504STreehugger Robot
299*79330504STreehugger Robot ALOGV("getParameters() %s", param.toString().string());
300*79330504STreehugger Robot return param.toString();
301*79330504STreehugger Robot }
302*79330504STreehugger Robot
getRenderPosition(uint32_t * dspFrames)303*79330504STreehugger Robot status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
304*79330504STreehugger Robot {
305*79330504STreehugger Robot return INVALID_OPERATION;
306*79330504STreehugger Robot }
307*79330504STreehugger Robot
308*79330504STreehugger Robot // ----------------------------------------------------------------------------
309*79330504STreehugger Robot
310*79330504STreehugger Robot // record functions
set(AudioHardwareGeneric * hw,int fd,uint32_t devices,int * pFormat,uint32_t * pChannels,uint32_t * pRate,AudioSystem::audio_in_acoustics acoustics)311*79330504STreehugger Robot status_t AudioStreamInGeneric::set(
312*79330504STreehugger Robot AudioHardwareGeneric *hw,
313*79330504STreehugger Robot int fd,
314*79330504STreehugger Robot uint32_t devices,
315*79330504STreehugger Robot int *pFormat,
316*79330504STreehugger Robot uint32_t *pChannels,
317*79330504STreehugger Robot uint32_t *pRate,
318*79330504STreehugger Robot AudioSystem::audio_in_acoustics acoustics)
319*79330504STreehugger Robot {
320*79330504STreehugger Robot if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE;
321*79330504STreehugger Robot ALOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
322*79330504STreehugger Robot // check values
323*79330504STreehugger Robot if ((*pFormat != format()) ||
324*79330504STreehugger Robot (*pChannels != channels()) ||
325*79330504STreehugger Robot (*pRate != sampleRate())) {
326*79330504STreehugger Robot ALOGE("Error opening input channel");
327*79330504STreehugger Robot *pFormat = format();
328*79330504STreehugger Robot *pChannels = channels();
329*79330504STreehugger Robot *pRate = sampleRate();
330*79330504STreehugger Robot return BAD_VALUE;
331*79330504STreehugger Robot }
332*79330504STreehugger Robot
333*79330504STreehugger Robot mAudioHardware = hw;
334*79330504STreehugger Robot mFd = fd;
335*79330504STreehugger Robot mDevice = devices;
336*79330504STreehugger Robot return NO_ERROR;
337*79330504STreehugger Robot }
338*79330504STreehugger Robot
~AudioStreamInGeneric()339*79330504STreehugger Robot AudioStreamInGeneric::~AudioStreamInGeneric()
340*79330504STreehugger Robot {
341*79330504STreehugger Robot }
342*79330504STreehugger Robot
read(void * buffer,ssize_t bytes)343*79330504STreehugger Robot ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
344*79330504STreehugger Robot {
345*79330504STreehugger Robot AutoMutex lock(mLock);
346*79330504STreehugger Robot if (mFd < 0) {
347*79330504STreehugger Robot ALOGE("Attempt to read from unopened device");
348*79330504STreehugger Robot return NO_INIT;
349*79330504STreehugger Robot }
350*79330504STreehugger Robot return ::read(mFd, buffer, bytes);
351*79330504STreehugger Robot }
352*79330504STreehugger Robot
dump(int fd,const Vector<String16> & args)353*79330504STreehugger Robot status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
354*79330504STreehugger Robot {
355*79330504STreehugger Robot const size_t SIZE = 256;
356*79330504STreehugger Robot char buffer[SIZE];
357*79330504STreehugger Robot String8 result;
358*79330504STreehugger Robot snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
359*79330504STreehugger Robot result.append(buffer);
360*79330504STreehugger Robot snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
361*79330504STreehugger Robot result.append(buffer);
362*79330504STreehugger Robot snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
363*79330504STreehugger Robot result.append(buffer);
364*79330504STreehugger Robot snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
365*79330504STreehugger Robot result.append(buffer);
366*79330504STreehugger Robot snprintf(buffer, SIZE, "\tformat: %d\n", format());
367*79330504STreehugger Robot result.append(buffer);
368*79330504STreehugger Robot snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
369*79330504STreehugger Robot result.append(buffer);
370*79330504STreehugger Robot snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
371*79330504STreehugger Robot result.append(buffer);
372*79330504STreehugger Robot snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
373*79330504STreehugger Robot result.append(buffer);
374*79330504STreehugger Robot ::write(fd, result.string(), result.size());
375*79330504STreehugger Robot return NO_ERROR;
376*79330504STreehugger Robot }
377*79330504STreehugger Robot
setParameters(const String8 & keyValuePairs)378*79330504STreehugger Robot status_t AudioStreamInGeneric::setParameters(const String8& keyValuePairs)
379*79330504STreehugger Robot {
380*79330504STreehugger Robot AudioParameter param = AudioParameter(keyValuePairs);
381*79330504STreehugger Robot String8 key = String8(AudioParameter::keyRouting);
382*79330504STreehugger Robot status_t status = NO_ERROR;
383*79330504STreehugger Robot int device;
384*79330504STreehugger Robot ALOGV("setParameters() %s", keyValuePairs.string());
385*79330504STreehugger Robot
386*79330504STreehugger Robot if (param.getInt(key, device) == NO_ERROR) {
387*79330504STreehugger Robot mDevice = device;
388*79330504STreehugger Robot param.remove(key);
389*79330504STreehugger Robot }
390*79330504STreehugger Robot
391*79330504STreehugger Robot if (param.size()) {
392*79330504STreehugger Robot status = BAD_VALUE;
393*79330504STreehugger Robot }
394*79330504STreehugger Robot return status;
395*79330504STreehugger Robot }
396*79330504STreehugger Robot
getParameters(const String8 & keys)397*79330504STreehugger Robot String8 AudioStreamInGeneric::getParameters(const String8& keys)
398*79330504STreehugger Robot {
399*79330504STreehugger Robot AudioParameter param = AudioParameter(keys);
400*79330504STreehugger Robot String8 value;
401*79330504STreehugger Robot String8 key = String8(AudioParameter::keyRouting);
402*79330504STreehugger Robot
403*79330504STreehugger Robot if (param.get(key, value) == NO_ERROR) {
404*79330504STreehugger Robot param.addInt(key, (int)mDevice);
405*79330504STreehugger Robot }
406*79330504STreehugger Robot
407*79330504STreehugger Robot ALOGV("getParameters() %s", param.toString().string());
408*79330504STreehugger Robot return param.toString();
409*79330504STreehugger Robot }
410*79330504STreehugger Robot
411*79330504STreehugger Robot // ----------------------------------------------------------------------------
412*79330504STreehugger Robot
413*79330504STreehugger Robot }; // namespace android
414