OSDN Git Service

Merge "[AWARE]: Fix Nan capabilities mismatch" am: 980baf1bd7 am: 41fc794eff
[android-x86/hardware-libhardware_legacy.git] / audio / audio_hw_hal.cpp
1 /*
2  * Copyright (C) 2011 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 #define LOG_TAG "legacy_audio_hw_hal"
18 //#define LOG_NDEBUG 0
19
20 #include <stdint.h>
21
22 #include <hardware/hardware.h>
23 #include <system/audio.h>
24 #include <hardware/audio.h>
25
26 #include <hardware_legacy/AudioHardwareInterface.h>
27 #include <hardware_legacy/AudioSystemLegacy.h>
28
29 namespace android_audio_legacy {
30
31 class AudioHardwareInterface;
32
33 extern "C" {
34
35 struct legacy_audio_module {
36     struct audio_module module;
37 };
38
39 struct legacy_audio_device {
40     struct audio_hw_device device;
41
42     AudioHardwareInterface *hwif;
43 };
44
45 struct legacy_stream_out {
46     struct audio_stream_out stream;
47
48     AudioStreamOut *legacy_out;
49 };
50
51 struct legacy_stream_in {
52     struct audio_stream_in stream;
53
54     AudioStreamIn *legacy_in;
55 };
56
57
58 enum {
59     HAL_API_REV_1_0,
60     HAL_API_REV_2_0,
61     HAL_API_REV_NUM
62 } hal_api_rev;
63
64 static uint32_t audio_device_conv_table[][HAL_API_REV_NUM] =
65 {
66     /* output devices */
67     { AudioSystem::DEVICE_OUT_EARPIECE, AUDIO_DEVICE_OUT_EARPIECE },
68     { AudioSystem::DEVICE_OUT_SPEAKER, AUDIO_DEVICE_OUT_SPEAKER },
69     { AudioSystem::DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET },
70     { AudioSystem::DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADPHONE },
71     { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, AUDIO_DEVICE_OUT_BLUETOOTH_SCO },
72     { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET },
73     { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT },
74     { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP },
75     { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES },
76     { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER },
77     { AudioSystem::DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_AUX_DIGITAL },
78     { AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET },
79     { AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET },
80     { AudioSystem::DEVICE_OUT_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT },
81     /* input devices */
82     { AudioSystem::DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_IN_COMMUNICATION },
83     { AudioSystem::DEVICE_IN_AMBIENT, AUDIO_DEVICE_IN_AMBIENT },
84     { AudioSystem::DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC },
85     { AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET },
86     { AudioSystem::DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET },
87     { AudioSystem::DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_AUX_DIGITAL },
88     { AudioSystem::DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_VOICE_CALL },
89     { AudioSystem::DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BACK_MIC },
90     { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT },
91 };
92
93 static uint32_t convert_audio_device(uint32_t from_device, int from_rev, int to_rev)
94 {
95     const uint32_t k_num_devices = sizeof(audio_device_conv_table)/sizeof(uint32_t)/HAL_API_REV_NUM;
96     uint32_t to_device = AUDIO_DEVICE_NONE;
97     uint32_t in_bit = 0;
98
99     if (from_rev != HAL_API_REV_1_0) {
100         in_bit = from_device & AUDIO_DEVICE_BIT_IN;
101         from_device &= ~AUDIO_DEVICE_BIT_IN;
102     }
103
104     while (from_device) {
105         uint32_t i = 31 - __builtin_clz(from_device);
106         uint32_t cur_device = (1 << i) | in_bit;
107
108         for (i = 0; i < k_num_devices; i++) {
109             if (audio_device_conv_table[i][from_rev] == cur_device) {
110                 to_device |= audio_device_conv_table[i][to_rev];
111                 break;
112             }
113         }
114         from_device &= ~cur_device;
115     }
116     return to_device;
117 }
118
119
120 /** audio_stream_out implementation **/
121 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
122 {
123     const struct legacy_stream_out *out =
124         reinterpret_cast<const struct legacy_stream_out *>(stream);
125     return out->legacy_out->sampleRate();
126 }
127
128 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
129 {
130     struct legacy_stream_out *out =
131         reinterpret_cast<struct legacy_stream_out *>(stream);
132
133     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
134     /* TODO: implement this */
135     return 0;
136 }
137
138 static size_t out_get_buffer_size(const struct audio_stream *stream)
139 {
140     const struct legacy_stream_out *out =
141         reinterpret_cast<const struct legacy_stream_out *>(stream);
142     return out->legacy_out->bufferSize();
143 }
144
145 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
146 {
147     const struct legacy_stream_out *out =
148         reinterpret_cast<const struct legacy_stream_out *>(stream);
149     return (audio_channel_mask_t) out->legacy_out->channels();
150 }
151
152 static audio_format_t out_get_format(const struct audio_stream *stream)
153 {
154     const struct legacy_stream_out *out =
155         reinterpret_cast<const struct legacy_stream_out *>(stream);
156     // legacy API, don't change return type
157     return (audio_format_t) out->legacy_out->format();
158 }
159
160 static int out_set_format(struct audio_stream *stream, audio_format_t format)
161 {
162     struct legacy_stream_out *out =
163         reinterpret_cast<struct legacy_stream_out *>(stream);
164     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
165     /* TODO: implement me */
166     return 0;
167 }
168
169 static int out_standby(struct audio_stream *stream)
170 {
171     struct legacy_stream_out *out =
172         reinterpret_cast<struct legacy_stream_out *>(stream);
173     return out->legacy_out->standby();
174 }
175
176 static int out_dump(const struct audio_stream *stream, int fd)
177 {
178     const struct legacy_stream_out *out =
179         reinterpret_cast<const struct legacy_stream_out *>(stream);
180     Vector<String16> args;
181     return out->legacy_out->dump(fd, args);
182 }
183
184 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
185 {
186     struct legacy_stream_out *out =
187         reinterpret_cast<struct legacy_stream_out *>(stream);
188     int val;
189     String8 s8 = String8(kvpairs);
190     AudioParameter parms = AudioParameter(String8(kvpairs));
191
192     if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
193         val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0);
194         parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
195         parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
196         s8 = parms.toString();
197     }
198
199     return out->legacy_out->setParameters(s8);
200 }
201
202 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
203 {
204     const struct legacy_stream_out *out =
205         reinterpret_cast<const struct legacy_stream_out *>(stream);
206     String8 s8;
207     int val;
208
209     s8 = out->legacy_out->getParameters(String8(keys));
210
211     AudioParameter parms = AudioParameter(s8);
212     if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
213         val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0);
214         parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
215         parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
216         s8 = parms.toString();
217     }
218
219     return strdup(s8.string());
220 }
221
222 static uint32_t out_get_latency(const struct audio_stream_out *stream)
223 {
224     const struct legacy_stream_out *out =
225         reinterpret_cast<const struct legacy_stream_out *>(stream);
226     return out->legacy_out->latency();
227 }
228
229 static int out_set_volume(struct audio_stream_out *stream, float left,
230                           float right)
231 {
232     struct legacy_stream_out *out =
233         reinterpret_cast<struct legacy_stream_out *>(stream);
234     return out->legacy_out->setVolume(left, right);
235 }
236
237 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
238                          size_t bytes)
239 {
240     struct legacy_stream_out *out =
241         reinterpret_cast<struct legacy_stream_out *>(stream);
242     return out->legacy_out->write(buffer, bytes);
243 }
244
245 static int out_get_render_position(const struct audio_stream_out *stream,
246                                    uint32_t *dsp_frames)
247 {
248     const struct legacy_stream_out *out =
249         reinterpret_cast<const struct legacy_stream_out *>(stream);
250     return out->legacy_out->getRenderPosition(dsp_frames);
251 }
252
253 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
254                                         int64_t *timestamp)
255 {
256     const struct legacy_stream_out *out =
257         reinterpret_cast<const struct legacy_stream_out *>(stream);
258     return out->legacy_out->getNextWriteTimestamp(timestamp);
259 }
260
261 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
262 {
263     return 0;
264 }
265
266 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
267 {
268     return 0;
269 }
270
271 /** audio_stream_in implementation **/
272 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
273 {
274     const struct legacy_stream_in *in =
275         reinterpret_cast<const struct legacy_stream_in *>(stream);
276     return in->legacy_in->sampleRate();
277 }
278
279 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
280 {
281     struct legacy_stream_in *in =
282         reinterpret_cast<struct legacy_stream_in *>(stream);
283
284     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
285     /* TODO: implement this */
286     return 0;
287 }
288
289 static size_t in_get_buffer_size(const struct audio_stream *stream)
290 {
291     const struct legacy_stream_in *in =
292         reinterpret_cast<const struct legacy_stream_in *>(stream);
293     return in->legacy_in->bufferSize();
294 }
295
296 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
297 {
298     const struct legacy_stream_in *in =
299         reinterpret_cast<const struct legacy_stream_in *>(stream);
300     return (audio_channel_mask_t) in->legacy_in->channels();
301 }
302
303 static audio_format_t in_get_format(const struct audio_stream *stream)
304 {
305     const struct legacy_stream_in *in =
306         reinterpret_cast<const struct legacy_stream_in *>(stream);
307     // legacy API, don't change return type
308     return (audio_format_t) in->legacy_in->format();
309 }
310
311 static int in_set_format(struct audio_stream *stream, audio_format_t format)
312 {
313     struct legacy_stream_in *in =
314         reinterpret_cast<struct legacy_stream_in *>(stream);
315     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
316     /* TODO: implement me */
317     return 0;
318 }
319
320 static int in_standby(struct audio_stream *stream)
321 {
322     struct legacy_stream_in *in = reinterpret_cast<struct legacy_stream_in *>(stream);
323     return in->legacy_in->standby();
324 }
325
326 static int in_dump(const struct audio_stream *stream, int fd)
327 {
328     const struct legacy_stream_in *in =
329         reinterpret_cast<const struct legacy_stream_in *>(stream);
330     Vector<String16> args;
331     return in->legacy_in->dump(fd, args);
332 }
333
334 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
335 {
336     struct legacy_stream_in *in =
337         reinterpret_cast<struct legacy_stream_in *>(stream);
338     int val;
339     AudioParameter parms = AudioParameter(String8(kvpairs));
340     String8 s8 = String8(kvpairs);
341
342     if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
343         val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0);
344         parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
345         parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
346         s8 = parms.toString();
347     }
348
349     return in->legacy_in->setParameters(s8);
350 }
351
352 static char * in_get_parameters(const struct audio_stream *stream,
353                                 const char *keys)
354 {
355     const struct legacy_stream_in *in =
356         reinterpret_cast<const struct legacy_stream_in *>(stream);
357     String8 s8;
358     int val;
359
360     s8 = in->legacy_in->getParameters(String8(keys));
361
362     AudioParameter parms = AudioParameter(s8);
363     if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
364         val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0);
365         parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
366         parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
367         s8 = parms.toString();
368     }
369
370     return strdup(s8.string());
371 }
372
373 static int in_set_gain(struct audio_stream_in *stream, float gain)
374 {
375     struct legacy_stream_in *in =
376         reinterpret_cast<struct legacy_stream_in *>(stream);
377     return in->legacy_in->setGain(gain);
378 }
379
380 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
381                        size_t bytes)
382 {
383     struct legacy_stream_in *in =
384         reinterpret_cast<struct legacy_stream_in *>(stream);
385     return in->legacy_in->read(buffer, bytes);
386 }
387
388 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
389 {
390     struct legacy_stream_in *in =
391         reinterpret_cast<struct legacy_stream_in *>(stream);
392     return in->legacy_in->getInputFramesLost();
393 }
394
395 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
396 {
397     const struct legacy_stream_in *in =
398         reinterpret_cast<const struct legacy_stream_in *>(stream);
399     return in->legacy_in->addAudioEffect(effect);
400 }
401
402 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
403 {
404     const struct legacy_stream_in *in =
405         reinterpret_cast<const struct legacy_stream_in *>(stream);
406     return in->legacy_in->removeAudioEffect(effect);
407 }
408
409 /** audio_hw_device implementation **/
410 static inline struct legacy_audio_device * to_ladev(struct audio_hw_device *dev)
411 {
412     return reinterpret_cast<struct legacy_audio_device *>(dev);
413 }
414
415 static inline const struct legacy_audio_device * to_cladev(const struct audio_hw_device *dev)
416 {
417     return reinterpret_cast<const struct legacy_audio_device *>(dev);
418 }
419
420 static int adev_init_check(const struct audio_hw_device *dev)
421 {
422     const struct legacy_audio_device *ladev = to_cladev(dev);
423
424     return ladev->hwif->initCheck();
425 }
426
427 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
428 {
429     struct legacy_audio_device *ladev = to_ladev(dev);
430     return ladev->hwif->setVoiceVolume(volume);
431 }
432
433 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
434 {
435     struct legacy_audio_device *ladev = to_ladev(dev);
436     return ladev->hwif->setMasterVolume(volume);
437 }
438
439 static int adev_get_master_volume(struct audio_hw_device *dev, float* volume)
440 {
441     struct legacy_audio_device *ladev = to_ladev(dev);
442     return ladev->hwif->getMasterVolume(volume);
443 }
444
445 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
446 {
447     struct legacy_audio_device *ladev = to_ladev(dev);
448     // as this is the legacy API, don't change it to use audio_mode_t instead of int
449     return ladev->hwif->setMode((int) mode);
450 }
451
452 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
453 {
454     struct legacy_audio_device *ladev = to_ladev(dev);
455     return ladev->hwif->setMicMute(state);
456 }
457
458 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
459 {
460     const struct legacy_audio_device *ladev = to_cladev(dev);
461     return ladev->hwif->getMicMute(state);
462 }
463
464 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
465 {
466     struct legacy_audio_device *ladev = to_ladev(dev);
467     return ladev->hwif->setParameters(String8(kvpairs));
468 }
469
470 static char * adev_get_parameters(const struct audio_hw_device *dev,
471                                   const char *keys)
472 {
473     const struct legacy_audio_device *ladev = to_cladev(dev);
474     String8 s8;
475
476     s8 = ladev->hwif->getParameters(String8(keys));
477     return strdup(s8.string());
478 }
479
480 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
481                                          const struct audio_config *config)
482 {
483     const struct legacy_audio_device *ladev = to_cladev(dev);
484     return ladev->hwif->getInputBufferSize(config->sample_rate, (int) config->format,
485                                            audio_channel_count_from_in_mask(config->channel_mask));
486 }
487
488 static int adev_open_output_stream(struct audio_hw_device *dev,
489                                    audio_io_handle_t handle,
490                                    audio_devices_t devices,
491                                    audio_output_flags_t flags,
492                                    struct audio_config *config,
493                                    struct audio_stream_out **stream_out,
494                                    const char *address __unused)
495 {
496     struct legacy_audio_device *ladev = to_ladev(dev);
497     status_t status;
498     struct legacy_stream_out *out;
499     int ret;
500
501     out = (struct legacy_stream_out *)calloc(1, sizeof(*out));
502     if (!out)
503         return -ENOMEM;
504
505     devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
506
507     out->legacy_out = ladev->hwif->openOutputStreamWithFlags(devices, flags,
508                                                     (int *) &config->format,
509                                                     &config->channel_mask,
510                                                     &config->sample_rate, &status);
511     if (!out->legacy_out) {
512         ret = status;
513         goto err_open;
514     }
515
516     out->stream.common.get_sample_rate = out_get_sample_rate;
517     out->stream.common.set_sample_rate = out_set_sample_rate;
518     out->stream.common.get_buffer_size = out_get_buffer_size;
519     out->stream.common.get_channels = out_get_channels;
520     out->stream.common.get_format = out_get_format;
521     out->stream.common.set_format = out_set_format;
522     out->stream.common.standby = out_standby;
523     out->stream.common.dump = out_dump;
524     out->stream.common.set_parameters = out_set_parameters;
525     out->stream.common.get_parameters = out_get_parameters;
526     out->stream.common.add_audio_effect = out_add_audio_effect;
527     out->stream.common.remove_audio_effect = out_remove_audio_effect;
528     out->stream.get_latency = out_get_latency;
529     out->stream.set_volume = out_set_volume;
530     out->stream.write = out_write;
531     out->stream.get_render_position = out_get_render_position;
532     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
533
534     *stream_out = &out->stream;
535     return 0;
536
537 err_open:
538     free(out);
539     *stream_out = NULL;
540     return ret;
541 }
542
543 static void adev_close_output_stream(struct audio_hw_device *dev,
544                                      struct audio_stream_out* stream)
545 {
546     struct legacy_audio_device *ladev = to_ladev(dev);
547     struct legacy_stream_out *out = reinterpret_cast<struct legacy_stream_out *>(stream);
548
549     ladev->hwif->closeOutputStream(out->legacy_out);
550     free(out);
551 }
552
553 /** This method creates and opens the audio hardware input stream */
554 static int adev_open_input_stream(struct audio_hw_device *dev,
555                                   audio_io_handle_t handle,
556                                   audio_devices_t devices,
557                                   struct audio_config *config,
558                                   struct audio_stream_in **stream_in,
559                                   audio_input_flags_t flags __unused,
560                                   const char *address __unused,
561                                   audio_source_t source __unused)
562 {
563     struct legacy_audio_device *ladev = to_ladev(dev);
564     status_t status;
565     struct legacy_stream_in *in;
566     int ret;
567
568     in = (struct legacy_stream_in *)calloc(1, sizeof(*in));
569     if (!in)
570         return -ENOMEM;
571
572     devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
573
574     in->legacy_in = ladev->hwif->openInputStream(devices, (int *) &config->format,
575                                                  &config->channel_mask, &config->sample_rate,
576                                                  &status, (AudioSystem::audio_in_acoustics)0);
577     if (!in->legacy_in) {
578         ret = status;
579         goto err_open;
580     }
581
582     in->stream.common.get_sample_rate = in_get_sample_rate;
583     in->stream.common.set_sample_rate = in_set_sample_rate;
584     in->stream.common.get_buffer_size = in_get_buffer_size;
585     in->stream.common.get_channels = in_get_channels;
586     in->stream.common.get_format = in_get_format;
587     in->stream.common.set_format = in_set_format;
588     in->stream.common.standby = in_standby;
589     in->stream.common.dump = in_dump;
590     in->stream.common.set_parameters = in_set_parameters;
591     in->stream.common.get_parameters = in_get_parameters;
592     in->stream.common.add_audio_effect = in_add_audio_effect;
593     in->stream.common.remove_audio_effect = in_remove_audio_effect;
594     in->stream.set_gain = in_set_gain;
595     in->stream.read = in_read;
596     in->stream.get_input_frames_lost = in_get_input_frames_lost;
597
598     *stream_in = &in->stream;
599     return 0;
600
601 err_open:
602     free(in);
603     *stream_in = NULL;
604     return ret;
605 }
606
607 static void adev_close_input_stream(struct audio_hw_device *dev,
608                                struct audio_stream_in *stream)
609 {
610     struct legacy_audio_device *ladev = to_ladev(dev);
611     struct legacy_stream_in *in =
612         reinterpret_cast<struct legacy_stream_in *>(stream);
613
614     ladev->hwif->closeInputStream(in->legacy_in);
615     free(in);
616 }
617
618 static int adev_dump(const struct audio_hw_device *dev, int fd)
619 {
620     const struct legacy_audio_device *ladev = to_cladev(dev);
621     Vector<String16> args;
622
623     return ladev->hwif->dumpState(fd, args);
624 }
625
626 static int legacy_adev_close(hw_device_t* device)
627 {
628     struct audio_hw_device *hwdev =
629                         reinterpret_cast<struct audio_hw_device *>(device);
630     struct legacy_audio_device *ladev = to_ladev(hwdev);
631
632     if (!ladev)
633         return 0;
634
635     if (ladev->hwif)
636         delete ladev->hwif;
637
638     free(ladev);
639     return 0;
640 }
641
642 static int legacy_adev_open(const hw_module_t* module, const char* name,
643                             hw_device_t** device)
644 {
645     struct legacy_audio_device *ladev;
646     int ret;
647
648     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
649         return -EINVAL;
650
651     ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev));
652     if (!ladev)
653         return -ENOMEM;
654
655     ladev->device.common.tag = HARDWARE_DEVICE_TAG;
656     ladev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
657     ladev->device.common.module = const_cast<hw_module_t*>(module);
658     ladev->device.common.close = legacy_adev_close;
659
660     ladev->device.init_check = adev_init_check;
661     ladev->device.set_voice_volume = adev_set_voice_volume;
662     ladev->device.set_master_volume = adev_set_master_volume;
663     ladev->device.get_master_volume = adev_get_master_volume;
664     ladev->device.set_mode = adev_set_mode;
665     ladev->device.set_mic_mute = adev_set_mic_mute;
666     ladev->device.get_mic_mute = adev_get_mic_mute;
667     ladev->device.set_parameters = adev_set_parameters;
668     ladev->device.get_parameters = adev_get_parameters;
669     ladev->device.get_input_buffer_size = adev_get_input_buffer_size;
670     ladev->device.open_output_stream = adev_open_output_stream;
671     ladev->device.close_output_stream = adev_close_output_stream;
672     ladev->device.open_input_stream = adev_open_input_stream;
673     ladev->device.close_input_stream = adev_close_input_stream;
674     ladev->device.dump = adev_dump;
675
676     ladev->hwif = createAudioHardware();
677     if (!ladev->hwif) {
678         ret = -EIO;
679         goto err_create_audio_hw;
680     }
681
682     *device = &ladev->device.common;
683
684     return 0;
685
686 err_create_audio_hw:
687     free(ladev);
688     return ret;
689 }
690
691 static struct hw_module_methods_t legacy_audio_module_methods = {
692         open: legacy_adev_open
693 };
694
695 struct legacy_audio_module HAL_MODULE_INFO_SYM = {
696     module: {
697         common: {
698             tag: HARDWARE_MODULE_TAG,
699             module_api_version: AUDIO_MODULE_API_VERSION_0_1,
700             hal_api_version: HARDWARE_HAL_API_VERSION,
701             id: AUDIO_HARDWARE_MODULE_ID,
702             name: "LEGACY Audio HW HAL",
703             author: "The Android Open Source Project",
704             methods: &legacy_audio_module_methods,
705             dso : NULL,
706             reserved : {0},
707         },
708     },
709 };
710
711 }; // extern "C"
712
713 }; // namespace android_audio_legacy