OSDN Git Service

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