xref: /aosp_15_r20/hardware/libhardware_legacy/audio/AudioHardwareGeneric.cpp (revision 79330504eb3d14022296e3b041867f86289dd52c)
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