1 /*
2  * Copyright (C) 2014 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 "AudioHAL:audio_hal_thunks"
18 #include <utils/Log.h>
19 
20 #include <errno.h>
21 #include <stdlib.h>
22 
23 #include <hardware/hardware.h>
24 #include <hardware/audio.h>
25 
26 #include "AudioHardwareInput.h"
27 #include "AudioHardwareOutput.h"
28 #include "AudioStreamIn.h"
29 #include "AudioStreamOut.h"
30 
31 namespace android {
32 
33 extern AudioHardwareInput gAudioHardwareInput;
34 extern AudioHardwareOutput gAudioHardwareOutput;
35 
36 struct atv_audio_device {
37     struct audio_hw_device device;
38     AudioHardwareOutput* output;
39     AudioHardwareInput* input;
40 };
41 
42 struct atv_stream_out {
43     struct audio_stream_out stream;
44     AudioHardwareOutput* hw;
45     AudioStreamOut* impl;
46 };
47 
48 struct atv_stream_in {
49     struct audio_stream_in stream;
50     AudioStreamIn* impl;
51 };
52 
53 /*******************************************************************************
54  *
55  * Audio output stream stubs.
56  *
57  ******************************************************************************/
58 
out_set_volume(struct audio_stream_out * stream,float left,float right)59 static int out_set_volume(struct audio_stream_out *stream,
60                           float left,
61                           float right)
62 {
63     (void) stream;
64     (void) left;
65     (void) right;
66     return 0;
67 }
68 
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)69 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
70 {
71     (void) stream;
72     (void) effect;
73     return 0;
74 }
75 
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)76 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
77 {
78     (void) stream;
79     (void) effect;
80     return 0;
81 }
82 
83 /*******************************************************************************
84  *
85  * Audio output stream implementation
86  *
87  ******************************************************************************/
88 
out_get_sample_rate(const struct audio_stream * stream)89 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
90 {
91     const struct atv_stream_out* tstream =
92         reinterpret_cast<const struct atv_stream_out*>(stream);
93 
94     return tstream->impl->sampleRate();
95 }
96 
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)97 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
98 {
99     const struct atv_stream_out* tstream =
100         reinterpret_cast<const struct atv_stream_out*>(stream);
101 
102     if (rate != tstream->impl->sampleRate())
103         return -EINVAL;
104 
105     return 0;
106 }
107 
out_get_buffer_size(const struct audio_stream * stream)108 static size_t out_get_buffer_size(const struct audio_stream *stream)
109 {
110     const struct atv_stream_out* tstream =
111         reinterpret_cast<const struct atv_stream_out*>(stream);
112 
113     return tstream->impl->bufferSize();
114 }
115 
out_get_channels(const struct audio_stream * stream)116 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
117 {
118     const struct atv_stream_out* tstream =
119         reinterpret_cast<const struct atv_stream_out*>(stream);
120 
121     return tstream->impl->chanMask();
122 }
123 
out_get_format(const struct audio_stream * stream)124 static audio_format_t out_get_format(const struct audio_stream *stream)
125 {
126     const struct atv_stream_out* tstream =
127         reinterpret_cast<const struct atv_stream_out*>(stream);
128 
129     return tstream->impl->format();
130 }
131 
out_set_format(struct audio_stream * stream,audio_format_t format)132 static int out_set_format(struct audio_stream *stream, audio_format_t format)
133 {
134     const struct atv_stream_out* tstream =
135         reinterpret_cast<const struct atv_stream_out*>(stream);
136 
137     if (format != tstream->impl->format())
138         return -EINVAL;
139 
140     return 0;
141 }
142 
out_get_latency(const struct audio_stream_out * stream)143 static uint32_t out_get_latency(const struct audio_stream_out *stream)
144 {
145     const struct atv_stream_out* tstream =
146         reinterpret_cast<const struct atv_stream_out*>(stream);
147 
148     return tstream->impl->latency();
149 }
150 
out_standby(struct audio_stream * stream)151 static int out_standby(struct audio_stream *stream)
152 {
153     struct atv_stream_out* tstream =
154         reinterpret_cast<struct atv_stream_out*>(stream);
155 
156     return tstream->impl->standby();
157 }
158 
out_dump(const struct audio_stream * stream,int fd)159 static int out_dump(const struct audio_stream *stream, int fd)
160 {
161     const struct atv_stream_out* tstream =
162         reinterpret_cast<const struct atv_stream_out*>(stream);
163 
164     return tstream->impl->dump(fd);
165 }
166 
out_set_parameters(struct audio_stream * stream,const char * kvpairs)167 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
168 {
169     struct atv_stream_out* tstream =
170         reinterpret_cast<struct atv_stream_out*>(stream);
171 
172     return tstream->impl->setParameters(stream, kvpairs);
173 }
174 
out_get_parameters(const struct audio_stream * stream,const char * keys)175 static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
176 {
177     const struct atv_stream_out* tstream =
178         reinterpret_cast<const struct atv_stream_out*>(stream);
179 
180     return tstream->impl->getParameters(keys);
181 }
182 
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)183 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
184                          size_t bytes)
185 {
186     struct atv_stream_out* tstream =
187         reinterpret_cast<struct atv_stream_out*>(stream);
188 
189     return tstream->impl->write(buffer, bytes);
190 }
191 
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)192 static int out_get_render_position(const struct audio_stream_out *stream,
193                                    uint32_t *dsp_frames)
194 {
195     const struct atv_stream_out* tstream =
196         reinterpret_cast<const struct atv_stream_out*>(stream);
197 
198     return tstream->impl->getRenderPosition(dsp_frames);
199 }
200 
out_get_presentation_position(const struct audio_stream_out * stream,uint64_t * frames,struct timespec * timestamp)201 static int out_get_presentation_position(const struct audio_stream_out *stream,
202                                uint64_t *frames, struct timespec *timestamp)
203 {
204     const struct atv_stream_out* tstream =
205         reinterpret_cast<const struct atv_stream_out*>(stream);
206 
207     return tstream->impl->getPresentationPosition(frames, timestamp);
208 }
209 
out_get_next_write_timestamp(const struct audio_stream_out * stream __unused,int64_t * timestamp __unused)210 static int out_get_next_write_timestamp(const struct audio_stream_out *stream __unused,
211                                         int64_t *timestamp __unused)
212 {
213     return -ENOSYS;
214 }
215 
out_pause(struct audio_stream_out * stream)216 static int out_pause(struct audio_stream_out* stream)
217 {
218     const struct atv_stream_out* tstream =
219         reinterpret_cast<const struct atv_stream_out*>(stream);
220 
221     return tstream->impl->pause();
222 }
223 
out_resume(struct audio_stream_out * stream)224 static int out_resume(struct audio_stream_out* stream)
225 {
226     const struct atv_stream_out* tstream =
227         reinterpret_cast<const struct atv_stream_out*>(stream);
228 
229     return tstream->impl->resume();
230 }
231 
out_flush(struct audio_stream_out * stream)232 static int out_flush(struct audio_stream_out* stream)
233 {
234     const struct atv_stream_out* tstream =
235         reinterpret_cast<const struct atv_stream_out*>(stream);
236 
237     return tstream->impl->flush();
238 }
239 
240 /*******************************************************************************
241  *
242  * Audio input stream implementation
243  *
244  ******************************************************************************/
245 
in_get_sample_rate(const struct audio_stream * stream)246 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
247 {
248     const struct atv_stream_in* tstream =
249         reinterpret_cast<const struct atv_stream_in*>(stream);
250 
251     return tstream->impl->getSampleRate();
252 }
253 
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)254 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
255 {
256     const struct atv_stream_in* tstream =
257         reinterpret_cast<const struct atv_stream_in*>(stream);
258 
259     return tstream->impl->setSampleRate(rate);
260 }
261 
in_get_buffer_size(const struct audio_stream * stream)262 static size_t in_get_buffer_size(const struct audio_stream *stream)
263 {
264     const struct atv_stream_in* tstream =
265         reinterpret_cast<const struct atv_stream_in*>(stream);
266 
267     return tstream->impl->getBufferSize();
268 }
269 
in_get_channels(const struct audio_stream * stream)270 static uint32_t in_get_channels(const struct audio_stream *stream)
271 {
272     const struct atv_stream_in* tstream =
273         reinterpret_cast<const struct atv_stream_in*>(stream);
274 
275     return tstream->impl->getChannelMask();
276 }
277 
in_get_format(const struct audio_stream * stream)278 static audio_format_t in_get_format(const struct audio_stream *stream)
279 {
280     const struct atv_stream_in* tstream =
281         reinterpret_cast<const struct atv_stream_in*>(stream);
282 
283     return tstream->impl->getFormat();
284 }
285 
in_set_format(struct audio_stream * stream,audio_format_t format)286 static int in_set_format(struct audio_stream *stream, audio_format_t format)
287 {
288     const struct atv_stream_in* tstream =
289         reinterpret_cast<const struct atv_stream_in*>(stream);
290 
291     return tstream->impl->setFormat(format);
292 }
293 
in_standby(struct audio_stream * stream)294 static int in_standby(struct audio_stream *stream)
295 {
296     const struct atv_stream_in* tstream =
297         reinterpret_cast<const struct atv_stream_in*>(stream);
298 
299     return tstream->impl->standby();
300 }
301 
in_dump(const struct audio_stream * stream,int fd)302 static int in_dump(const struct audio_stream *stream, int fd)
303 {
304     const struct atv_stream_in* tstream =
305         reinterpret_cast<const struct atv_stream_in*>(stream);
306 
307     return tstream->impl->dump(fd);
308 }
309 
in_set_parameters(struct audio_stream * stream,const char * kvpairs)310 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
311 {
312     const struct atv_stream_in* tstream =
313         reinterpret_cast<const struct atv_stream_in*>(stream);
314 
315     return tstream->impl->setParameters(stream, kvpairs);
316 }
317 
in_get_parameters(const struct audio_stream * stream,const char * keys)318 static char* in_get_parameters(const struct audio_stream *stream,
319                                const char *keys)
320 {
321     const struct atv_stream_in* tstream =
322         reinterpret_cast<const struct atv_stream_in*>(stream);
323 
324     return tstream->impl->getParameters(keys);
325 }
326 
in_set_gain(struct audio_stream_in * stream,float gain)327 static int in_set_gain(struct audio_stream_in *stream, float gain)
328 {
329     const struct atv_stream_in* tstream =
330         reinterpret_cast<const struct atv_stream_in*>(stream);
331 
332     return tstream->impl->setGain(gain);
333 }
334 
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)335 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
336                        size_t bytes)
337 {
338     const struct atv_stream_in* tstream =
339         reinterpret_cast<const struct atv_stream_in*>(stream);
340 
341     return tstream->impl->read(buffer, bytes);
342 }
343 
in_get_input_frames_lost(struct audio_stream_in * stream)344 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
345 {
346     const struct atv_stream_in* tstream =
347         reinterpret_cast<const struct atv_stream_in*>(stream);
348 
349     return tstream->impl->getInputFramesLost();
350 }
351 
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)352 static int in_add_audio_effect(const struct audio_stream *stream,
353                                effect_handle_t effect)
354 {
355     const struct atv_stream_in* tstream =
356         reinterpret_cast<const struct atv_stream_in*>(stream);
357 
358     return tstream->impl->addAudioEffect(effect);
359 }
360 
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)361 static int in_remove_audio_effect(const struct audio_stream *stream,
362                                   effect_handle_t effect)
363 {
364     const struct atv_stream_in* tstream =
365         reinterpret_cast<const struct atv_stream_in*>(stream);
366 
367     return tstream->impl->removeAudioEffect(effect);
368 }
369 
370 /*******************************************************************************
371  *
372  * Audio device stubs
373  *
374  ******************************************************************************/
375 
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)376 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
377 {
378     const struct atv_audio_device* adev =
379         reinterpret_cast<const struct atv_audio_device*>(dev);
380 
381     return adev->output->setParameters(kvpairs);
382 
383 }
384 
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)385 static char * adev_get_parameters(const struct audio_hw_device *dev,
386                                   const char *keys)
387 {
388     const struct atv_audio_device* adev =
389         reinterpret_cast<const struct atv_audio_device*>(dev);
390 
391     return adev->output->getParameters(keys);
392 }
393 
adev_set_voice_volume(struct audio_hw_device * dev,float volume)394 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
395 {
396     (void) dev;
397     (void) volume;
398     return 0;
399 }
400 
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)401 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
402 {
403     (void) dev;
404     (void) mode;
405     return 0;
406 }
407 
adev_set_mic_mute(struct audio_hw_device * dev,bool state)408 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
409 {
410     const struct atv_audio_device* adev =
411         reinterpret_cast<struct atv_audio_device*>(dev);
412 
413     return adev->input->setMicMute(state);
414 }
415 
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)416 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
417 {
418     const struct atv_audio_device* adev =
419         reinterpret_cast<const struct atv_audio_device*>(dev);
420 
421     return adev->input->getMicMute(state);
422 }
423 
adev_get_input_buffer_size(const struct audio_hw_device * dev,const audio_config * config)424 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
425                                          const audio_config *config)
426 {
427     const struct atv_audio_device* adev =
428         reinterpret_cast<const struct atv_audio_device*>(dev);
429 
430     return adev->input->getInputBufferSize(config);
431 }
432 
adev_open_input_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,struct audio_stream_in ** stream_in,audio_input_flags_t flags,const char * address __unused,audio_source_t source __unused)433 static int adev_open_input_stream(struct audio_hw_device *dev,
434                                   audio_io_handle_t handle,
435                                   audio_devices_t devices,
436                                   struct audio_config *config,
437                                   struct audio_stream_in **stream_in,
438                                   audio_input_flags_t flags,
439                                   const char *address __unused,
440                                   audio_source_t source __unused)
441 {
442     (void) handle;
443     (void) flags;
444     int ret = 0;
445     struct atv_audio_device* adev =
446         reinterpret_cast<struct atv_audio_device*>(dev);
447     struct atv_stream_in *in = NULL;
448 
449     *stream_in = NULL;
450 
451     in = reinterpret_cast<struct atv_stream_in*>(
452             calloc(1, sizeof(struct atv_stream_in)));
453     if (!in)  {
454         ret = -ENOMEM;
455         goto bailout;
456     }
457 
458     in->stream.common.get_sample_rate = in_get_sample_rate;
459     in->stream.common.set_sample_rate = in_set_sample_rate;
460     in->stream.common.get_buffer_size = in_get_buffer_size;
461     in->stream.common.get_channels = in_get_channels;
462     in->stream.common.get_format = in_get_format;
463     in->stream.common.set_format = in_set_format;
464     in->stream.common.standby = in_standby;
465     in->stream.common.dump = in_dump;
466     in->stream.common.set_parameters = in_set_parameters;
467     in->stream.common.get_parameters = in_get_parameters;
468     in->stream.common.add_audio_effect = in_add_audio_effect;
469     in->stream.common.remove_audio_effect = in_remove_audio_effect;
470     in->stream.set_gain = in_set_gain;
471     in->stream.read = in_read;
472     in->stream.get_input_frames_lost = in_get_input_frames_lost;
473 
474     in->impl = adev->input->openInputStream(devices,
475                                             &config->format,
476                                             &config->channel_mask,
477                                             &config->sample_rate,
478                                             reinterpret_cast<status_t*>(&ret));
479     if (NULL == in->impl) {
480         ret = -ENOMEM;
481         goto bailout;
482     }
483 
484     if (0 == ret)
485         *stream_in = &in->stream;
486 
487 bailout:
488     if ((0 != ret) && (NULL != in)) {
489         delete in->impl;
490         free(in);
491     }
492 
493     return ret;
494 }
495 
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * stream)496 static void adev_close_input_stream(struct audio_hw_device *dev,
497                                     struct audio_stream_in *stream)
498 {
499     struct atv_audio_device* adev =
500         reinterpret_cast<struct atv_audio_device*>(dev);
501     struct atv_stream_in* tstream =
502         reinterpret_cast<struct atv_stream_in*>(stream);
503 
504     adev->input->closeInputStream(tstream->impl);
505     free(stream);
506 }
507 
adev_open_output_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,struct audio_stream_out ** stream_out,const char * address __unused)508 static int adev_open_output_stream(struct audio_hw_device *dev,
509                                    audio_io_handle_t handle,
510                                    audio_devices_t devices,
511                                    audio_output_flags_t flags,
512                                    struct audio_config *config,
513                                    struct audio_stream_out **stream_out,
514                                    const char *address __unused)
515 {
516     (void) handle;
517     int ret = 0;
518     struct atv_audio_device* adev =
519         reinterpret_cast<struct atv_audio_device*>(dev);
520     struct atv_stream_out *out = NULL;
521 
522     *stream_out = NULL;
523 
524     out = reinterpret_cast<struct atv_stream_out*>(
525             calloc(1, sizeof(struct atv_stream_out)));
526     if (!out)  {
527         ret = -ENOMEM;
528         goto bailout;
529     }
530 
531     out->stream.common.get_sample_rate = out_get_sample_rate;
532     out->stream.common.set_sample_rate = out_set_sample_rate;
533     out->stream.common.get_buffer_size = out_get_buffer_size;
534     out->stream.common.get_channels = out_get_channels;
535     out->stream.common.get_format = out_get_format;
536     out->stream.common.set_format = out_set_format;
537     out->stream.common.standby = out_standby;
538     out->stream.common.dump = out_dump;
539     out->stream.common.set_parameters = out_set_parameters;
540     out->stream.common.get_parameters = out_get_parameters;
541     out->stream.common.add_audio_effect = out_add_audio_effect;
542     out->stream.common.remove_audio_effect = out_remove_audio_effect;
543     out->stream.get_latency = out_get_latency;
544     out->stream.set_volume = out_set_volume;
545     out->stream.write = out_write;
546     out->stream.get_render_position = out_get_render_position;
547     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
548     out->stream.get_presentation_position = out_get_presentation_position;
549     out->stream.pause = out_pause;
550     out->stream.resume = out_resume;
551     out->stream.flush = out_flush;
552 
553     out->impl = adev->output->openOutputStream(
554             devices,
555             &config->format,
556             &config->channel_mask,
557             &config->sample_rate,
558             flags,
559             reinterpret_cast<status_t*>(&ret));
560 
561     if (NULL == out->impl) {
562         ret = -ENOMEM;
563         goto bailout;
564     }
565 
566     if (0 == ret) {
567         out->hw = adev->output;
568         *stream_out = &out->stream;
569     }
570 
571 bailout:
572     if ((0 != ret) && (NULL != out)) {
573         delete out->impl;
574         free(out);
575     }
576 
577     return ret;
578 }
579 
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)580 static void adev_close_output_stream(struct audio_hw_device *dev,
581                                      struct audio_stream_out *stream)
582 {
583     struct atv_audio_device* adev =
584         reinterpret_cast<struct atv_audio_device*>(dev);
585     struct atv_stream_out* tstream =
586         reinterpret_cast<struct atv_stream_out*>(stream);
587 
588     adev->output->closeOutputStream(tstream->impl);
589     free(stream);
590 }
591 
adev_init_check(const struct audio_hw_device * dev)592 static int adev_init_check(const struct audio_hw_device *dev)
593 {
594     const struct atv_audio_device* adev =
595         reinterpret_cast<const struct atv_audio_device*>(dev);
596 
597     return adev->output->initCheck();
598 }
599 
adev_set_master_volume(struct audio_hw_device * dev,float volume)600 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
601 {
602     struct atv_audio_device* adev =
603         reinterpret_cast<struct atv_audio_device*>(dev);
604 
605     return adev->output->setMasterVolume(volume);
606 }
607 
adev_get_master_volume(struct audio_hw_device * dev,float * volume)608 static int adev_get_master_volume(struct audio_hw_device *dev,
609                                   float *volume)
610 {
611     struct atv_audio_device* adev =
612         reinterpret_cast<struct atv_audio_device*>(dev);
613 
614     return adev->output->getMasterVolume(volume);
615 }
616 
adev_set_master_mute(struct audio_hw_device * dev,bool muted)617 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
618 {
619     struct atv_audio_device* adev =
620         reinterpret_cast<struct atv_audio_device*>(dev);
621 
622     return adev->output->setMasterMute(muted);
623 }
624 
adev_get_master_mute(struct audio_hw_device * dev,bool * muted)625 static int adev_get_master_mute(struct audio_hw_device *dev,
626                                 bool *muted)
627 {
628     struct atv_audio_device* adev =
629         reinterpret_cast<struct atv_audio_device*>(dev);
630 
631     return adev->output->getMasterMute(muted);
632 }
633 
adev_dump(const audio_hw_device * dev,int fd)634 static int adev_dump(const audio_hw_device* dev, int fd)
635 {
636     const struct atv_audio_device* adev =
637         reinterpret_cast<const struct atv_audio_device*>(dev);
638 
639     int ret = adev->output->dump(fd);
640     if (ret == 0) {
641         ret = adev->input->dump(fd);
642     }
643     return ret;
644 }
645 
adev_close(hw_device_t * device)646 static int adev_close(hw_device_t *device)
647 {
648     struct atv_audio_device* adev =
649         reinterpret_cast<struct atv_audio_device*>(device);
650 
651     free(device);
652 
653     return 0;
654 }
655 
atv_audiodev_open_cpp(const hw_module_t * module,const char * name,hw_device_t ** device)656 static int atv_audiodev_open_cpp(
657         const hw_module_t* module,
658         const char* name,
659         hw_device_t** device)
660 {
661     struct atv_audio_device* adev = NULL;
662     int ret = 0;
663 
664     if (NULL == device) {
665         ret = -EINVAL;
666         goto bailout;
667     }
668 
669     *device = NULL;
670 
671     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
672         ret = -EINVAL;
673         goto bailout;
674     }
675 
676     adev = (struct atv_audio_device*)calloc(1,
677             sizeof(struct atv_audio_device));
678     if (NULL == adev) {
679         ret = -ENOMEM;
680         goto bailout;
681     }
682 
683     adev->device.common.tag = HARDWARE_DEVICE_TAG;
684     adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
685     adev->device.common.module = (struct hw_module_t *) module;
686     adev->device.common.close = adev_close;
687 
688     adev->device.init_check = adev_init_check;
689     adev->device.set_voice_volume = adev_set_voice_volume;
690     adev->device.set_master_volume = adev_set_master_volume;
691     adev->device.get_master_volume = adev_get_master_volume;
692     adev->device.set_master_mute = adev_set_master_mute;
693     adev->device.get_master_mute = adev_get_master_mute;
694     adev->device.set_mode = adev_set_mode;
695     adev->device.set_mic_mute = adev_set_mic_mute;
696     adev->device.get_mic_mute = adev_get_mic_mute;
697     adev->device.set_parameters = adev_set_parameters;
698     adev->device.get_parameters = adev_get_parameters;
699     adev->device.get_input_buffer_size = adev_get_input_buffer_size;
700     adev->device.open_output_stream = adev_open_output_stream;
701     adev->device.close_output_stream = adev_close_output_stream;
702     adev->device.open_input_stream = adev_open_input_stream;
703     adev->device.close_input_stream = adev_close_input_stream;
704     adev->device.dump = adev_dump;
705 
706     adev->output = &gAudioHardwareOutput;
707     adev->input = &gAudioHardwareInput;
708     *device = &adev->device.common;
709 
710 bailout:
711     if ((0 != ret) && (NULL != adev)) {
712         free(adev);
713     }
714 
715     return 0;
716 }
717 
718 }  // namespace android
719 
atv_audiodev_open(const hw_module_t * module,const char * name,hw_device_t ** device)720 extern "C" int atv_audiodev_open(const hw_module_t* module,
721                              const char* name,
722                              hw_device_t** device) {
723     return android::atv_audiodev_open_cpp(module, name, device);
724 }
725