1 /*
2 * Copyright (C) 2008-2011 The Android Open Source Project
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 */
19
20 #define LOG_TAG "a2dp_audio_hw"
21 //#define LOG_NDEBUG 0
22
23 #include <errno.h>
24 #include <pthread.h>
25 #include <stdint.h>
26 #include <sys/time.h>
27
28 #include <cutils/log.h>
29 #include <cutils/str_parms.h>
30
31 #include <hardware/hardware.h>
32 #include <system/audio.h>
33 #include <hardware/audio.h>
34
35 #include <hardware_legacy/power.h>
36
37 #include "liba2dp.h"
38
39 #define A2DP_WAKE_LOCK_NAME "A2dpOutputStream"
40 #define MAX_WRITE_RETRIES 5
41
42 #define A2DP_SUSPENDED_PARM "A2dpSuspended"
43 #define BLUETOOOTH_ENABLED_PARM "bluetooth_enabled"
44
45 #define OUT_SINK_ADDR_PARM "a2dp_sink_address"
46
47 /* NOTE: If you need to hold the adev_a2dp->lock AND the astream_out->lock,
48 you MUST take adev_a2dp lock first!!
49 */
50
51 struct astream_out;
52 struct adev_a2dp {
53 struct audio_hw_device device;
54
55 audio_mode_t mode;
56 bool bt_enabled;
57 bool suspended;
58
59 pthread_mutex_t lock;
60
61 struct astream_out *output;
62 };
63
64 struct astream_out {
65 struct audio_stream_out stream;
66
67 uint32_t sample_rate;
68 size_t buffer_size;
69 uint32_t channels;
70 int format;
71
72 int fd;
73 bool standby;
74 int start_count;
75 int retry_count;
76 void* data;
77
78 pthread_mutex_t lock;
79
80 audio_devices_t device;
81 uint64_t last_write_time;
82 uint32_t buffer_duration_us;
83
84 bool bt_enabled;
85 bool suspended;
86 char a2dp_addr[20];
87 };
88
system_time(void)89 static uint64_t system_time(void)
90 {
91 struct timespec t;
92
93 t.tv_sec = t.tv_nsec = 0;
94 clock_gettime(CLOCK_MONOTONIC, &t);
95
96 return t.tv_sec*1000000000LL + t.tv_nsec;
97 }
98
99 /** audio_stream_out implementation **/
out_get_sample_rate(const struct audio_stream * stream)100 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
101 {
102 const struct astream_out *out = (const struct astream_out *)stream;
103 return out->sample_rate;
104 }
105
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)106 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
107 {
108 struct astream_out *out = (struct astream_out *)stream;
109
110 LOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
111 return 0;
112 }
113
out_get_buffer_size(const struct audio_stream * stream)114 static size_t out_get_buffer_size(const struct audio_stream *stream)
115 {
116 const struct astream_out *out = (const struct astream_out *)stream;
117 return out->buffer_size;
118 }
119
out_get_channels(const struct audio_stream * stream)120 static uint32_t out_get_channels(const struct audio_stream *stream)
121 {
122 const struct astream_out *out = (const struct astream_out *)stream;
123 return out->channels;
124 }
125
out_get_format(const struct audio_stream * stream)126 static int out_get_format(const struct audio_stream *stream)
127 {
128 const struct astream_out *out = (const struct astream_out *)stream;
129 return out->format;
130 }
131
out_set_format(struct audio_stream * stream,int format)132 static int out_set_format(struct audio_stream *stream, int format)
133 {
134 struct astream_out *out = (struct astream_out *)stream;
135 LOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
136 return 0;
137 }
138
out_dump(const struct audio_stream * stream,int fd)139 static int out_dump(const struct audio_stream *stream, int fd)
140 {
141 return 0;
142 }
143
out_get_latency(const struct audio_stream_out * stream)144 static uint32_t out_get_latency(const struct audio_stream_out *stream)
145 {
146 const struct astream_out *out = (const struct astream_out *)stream;
147
148 return (out->buffer_duration_us / 1000) + 200;
149 }
150
out_set_volume(struct audio_stream_out * stream,float left,float right)151 static int out_set_volume(struct audio_stream_out *stream, float left,
152 float right)
153 {
154 return -ENOSYS;
155 }
156
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)157 static int out_get_render_position(const struct audio_stream_out *stream,
158 uint32_t *dsp_frames)
159 {
160 return -ENOSYS;
161 }
162
_out_init_locked(struct astream_out * out,const char * addr)163 static int _out_init_locked(struct astream_out *out, const char *addr)
164 {
165 int ret;
166
167 if (out->data)
168 return 0;
169
170 /* XXX: shouldn't this use the sample_rate/channel_count from 'out'? */
171 ret = a2dp_init(44100, 2, &out->data);
172 if (ret < 0) {
173 LOGE("a2dp_init failed err: %d\n", ret);
174 out->data = NULL;
175 return ret;
176 }
177
178 /* XXX: is this even necessary? */
179 if (addr)
180 strlcpy(out->a2dp_addr, addr, sizeof(out->a2dp_addr));
181 a2dp_set_sink(out->data, out->a2dp_addr);
182
183 return 0;
184 }
185
_out_validate_parms(struct astream_out * out,int format,uint32_t chans,uint32_t rate)186 static bool _out_validate_parms(struct astream_out *out, int format,
187 uint32_t chans, uint32_t rate)
188 {
189 if ((format && (format != out->format)) ||
190 (chans && (chans != out->channels)) ||
191 (rate && (rate != out->sample_rate)))
192 return false;
193 return true;
194 }
195
out_standby_stream_locked(struct astream_out * out)196 static int out_standby_stream_locked(struct astream_out *out)
197 {
198 int ret = 0;
199
200 if (out->standby || !out->data)
201 return 0;
202
203 LOGV_IF(!out->bt_enabled, "Standby skip stop: enabled %d", out->bt_enabled);
204 if (out->bt_enabled)
205 ret = a2dp_stop(out->data);
206 release_wake_lock(A2DP_WAKE_LOCK_NAME);
207 out->standby = true;
208
209 return ret;
210 }
211
out_close_stream_locked(struct astream_out * out)212 static int out_close_stream_locked(struct astream_out *out)
213 {
214 out_standby_stream_locked(out);
215
216 if (out->data) {
217 LOGV("%s: calling a2dp_cleanup()", __func__);
218 a2dp_cleanup(out->data);
219 out->data = NULL;
220 }
221
222 return 0;
223 }
224
out_standby(struct audio_stream * stream)225 static int out_standby(struct audio_stream *stream)
226 {
227 struct astream_out *out = (struct astream_out *)stream;
228
229 pthread_mutex_lock(&out->lock);
230 out_standby_stream_locked(out);
231 pthread_mutex_unlock(&out->lock);
232
233 return 0;
234 }
235
out_set_parameters(struct audio_stream * stream,const char * kvpairs)236 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
237 {
238 struct astream_out *out = (struct astream_out *)stream;
239 struct str_parms *parms;
240 char *str;
241 char value[32];
242 int ret;
243
244 parms = str_parms_create_str(kvpairs);
245
246 pthread_mutex_lock(&out->lock);
247
248 ret = str_parms_get_str(parms, OUT_SINK_ADDR_PARM, value, sizeof(value));
249 if (ret >= 0) {
250 /* strlen(00:00:00:00:00:00) == 17 */
251 if (strlen(value) == 17) {
252 strlcpy(out->a2dp_addr, value, sizeof(out->a2dp_addr));
253 if (out->data)
254 a2dp_set_sink(out->data, out->a2dp_addr);
255 } else
256 ret = -EINVAL;
257 }
258
259 pthread_mutex_unlock(&out->lock);
260 str_parms_destroy(parms);
261 return ret;
262 }
263
out_get_device(const struct audio_stream * stream)264 static audio_devices_t out_get_device(const struct audio_stream *stream)
265 {
266 const struct astream_out *out = (const struct astream_out *)stream;
267 return out->device;
268 }
269
270
out_set_device(struct audio_stream * stream,audio_devices_t device)271 static int out_set_device(struct audio_stream *stream, audio_devices_t device)
272 {
273 struct astream_out *out = (struct astream_out *)stream;
274
275 if (!audio_is_a2dp_device(device))
276 return -EINVAL;
277
278 /* XXX: if out->device ever starts getting used for anything, need to
279 * grab the out->lock */
280 out->device = device;
281 return 0;
282 }
283
out_get_parameters(const struct audio_stream * stream,const char * keys)284 static char * out_get_parameters(const struct audio_stream *stream,
285 const char *keys)
286 {
287 struct astream_out *out = (struct astream_out *)stream;
288 struct str_parms *parms;
289 struct str_parms *out_parms;
290 char *str;
291 char value[20];
292 int ret;
293
294 parms = str_parms_create_str(keys);
295 out_parms = str_parms_create();
296
297 pthread_mutex_lock(&out->lock);
298
299 ret = str_parms_get_str(parms, OUT_SINK_ADDR_PARM, value, sizeof(value));
300 if (ret >= 0)
301 str_parms_add_str(out_parms, OUT_SINK_ADDR_PARM, out->a2dp_addr);
302
303 pthread_mutex_unlock(&out->lock);
304
305 str = str_parms_to_str(out_parms);
306 str_parms_destroy(out_parms);
307 str_parms_destroy(parms);
308
309 return str;
310 }
311
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)312 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
313 size_t bytes)
314 {
315 struct astream_out *out = (struct astream_out *)stream;
316 int ret;
317 int cnt = bytes;
318 int retries = MAX_WRITE_RETRIES;
319 uint64_t now;
320 uint32_t elapsed_us;
321 const uint8_t *buf = buffer;
322
323 pthread_mutex_lock(&out->lock);
324 if (!out->bt_enabled || out->suspended) {
325 LOGV("a2dp %s: bluetooth disabled bt_en %d, suspended %d",
326 out->bt_enabled, out->suspended);
327 ret = -1;
328 goto err_bt_disabled;
329 }
330
331 if (out->standby) {
332 acquire_wake_lock(PARTIAL_WAKE_LOCK, A2DP_WAKE_LOCK_NAME);
333 out->standby = false;
334 out->last_write_time = system_time();
335 }
336
337 ret = _out_init_locked(out, NULL);
338 if (ret < 0)
339 goto err_init;
340
341 while (cnt > 0 && retries > 0) {
342 ret = a2dp_write(out->data, buf, cnt);
343 if (ret < 0) {
344 LOGE("%s: a2dp_write failed (%d)\n", __func__, ret);
345 goto err_write;
346 } else if (ret == 0) {
347 retries--;
348 continue;
349 }
350
351 cnt -= ret;
352 buf += ret;
353 }
354
355 /* XXX: PLEASE FIX ME!!!! */
356
357 /* if A2DP sink runs abnormally fast, sleep a little so that
358 * audioflinger mixer thread does no spin and starve other threads. */
359 /* NOTE: It is likely that the A2DP headset is being disconnected */
360 now = system_time();
361 elapsed_us = (now - out->last_write_time) / 1000UL;
362 if (elapsed_us < (out->buffer_duration_us / 4)) {
363 LOGV("A2DP sink runs too fast");
364 usleep(out->buffer_duration_us - elapsed_us);
365 }
366 out->last_write_time = now;
367
368 pthread_mutex_unlock(&out->lock);
369
370 return bytes;
371
372 err_write:
373 err_init:
374 err_bt_disabled:
375 out_standby_stream_locked(out);
376 pthread_mutex_unlock(&out->lock);
377
378 /* XXX: simulate audio output timing in case of error?!?! */
379 usleep(out->buffer_duration_us);
380 return ret;
381 }
382
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)383 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
384 {
385 return 0;
386 }
387
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)388 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
389 {
390 return 0;
391 }
392
_out_bt_enable(struct astream_out * out,bool enable)393 static int _out_bt_enable(struct astream_out *out, bool enable)
394 {
395 int ret = 0;
396
397 pthread_mutex_lock(&out->lock);
398 out->bt_enabled = enable;
399 if (!enable)
400 ret = out_close_stream_locked(out);
401 pthread_mutex_unlock(&out->lock);
402
403 return ret;
404 }
405
_out_a2dp_suspend(struct astream_out * out,bool suspend)406 static int _out_a2dp_suspend(struct astream_out *out, bool suspend)
407 {
408 pthread_mutex_lock(&out->lock);
409 out->suspended = suspend;
410 out_standby_stream_locked(out);
411 pthread_mutex_unlock(&out->lock);
412
413 return 0;
414 }
415
adev_open_output_stream(struct audio_hw_device * dev,uint32_t devices,int * format,uint32_t * channels,uint32_t * sample_rate,struct audio_stream_out ** stream_out)416 static int adev_open_output_stream(struct audio_hw_device *dev,
417 uint32_t devices, int *format,
418 uint32_t *channels, uint32_t *sample_rate,
419 struct audio_stream_out **stream_out)
420 {
421 struct adev_a2dp *adev = (struct adev_a2dp *)dev;
422 struct astream_out *out;
423 int ret;
424
425 pthread_mutex_lock(&adev->lock);
426
427 /* one output stream at a time */
428 if (adev->output) {
429 LOGV("output exists");
430 ret = -EBUSY;
431 goto err_output_exists;
432 }
433
434 out = calloc(1, sizeof(struct astream_out));
435 if (!out) {
436 ret = -ENOMEM;
437 goto err_alloc;
438 }
439
440 pthread_mutex_init(&out->lock, NULL);
441
442 out->stream.common.get_sample_rate = out_get_sample_rate;
443 out->stream.common.set_sample_rate = out_set_sample_rate;
444 out->stream.common.get_buffer_size = out_get_buffer_size;
445 out->stream.common.get_channels = out_get_channels;
446 out->stream.common.get_format = out_get_format;
447 out->stream.common.set_format = out_set_format;
448 out->stream.common.standby = out_standby;
449 out->stream.common.dump = out_dump;
450 out->stream.common.set_parameters = out_set_parameters;
451 out->stream.common.get_parameters = out_get_parameters;
452 out->stream.common.set_device = out_set_device;
453 out->stream.common.get_device = out_get_device;
454 out->stream.common.add_audio_effect = out_add_audio_effect;
455 out->stream.common.remove_audio_effect = out_remove_audio_effect;
456 out->stream.get_latency = out_get_latency;
457 out->stream.set_volume = out_set_volume;
458 out->stream.write = out_write;
459 out->stream.get_render_position = out_get_render_position;
460
461 out->sample_rate = 44100;
462 out->buffer_size = 512 * 20;
463 out->channels = AUDIO_CHANNEL_OUT_STEREO;
464 out->format = AUDIO_FORMAT_PCM_16_BIT;
465
466 out->fd = -1;
467 out->device = devices;
468 out->bt_enabled = adev->bt_enabled;
469 out->suspended = adev->suspended;
470
471 /* for now, buffer_duration_us is precalculated and never changed.
472 * if the sample rate or the format ever changes on the fly, we'd have
473 * to recalculate this */
474 out->buffer_duration_us = ((out->buffer_size * 1000 ) /
475 audio_stream_frame_size(&out->stream.common) /
476 out->sample_rate) * 1000;
477 if (!_out_validate_parms(out, format ? *format : 0,
478 channels ? *channels : 0,
479 sample_rate ? *sample_rate : 0)) {
480 LOGV("invalid parameters");
481 ret = -EINVAL;
482 goto err_validate_parms;
483 }
484
485 /* XXX: check return code? */
486 if (adev->bt_enabled)
487 _out_init_locked(out, "00:00:00:00:00:00");
488
489 adev->output = out;
490
491 if (format)
492 *format = out->format;
493 if (channels)
494 *channels = out->channels;
495 if (sample_rate)
496 *sample_rate = out->sample_rate;
497
498 pthread_mutex_unlock(&adev->lock);
499
500 *stream_out = &out->stream;
501
502 return 0;
503
504 err_validate_parms:
505 free(out);
506 err_alloc:
507 err_output_exists:
508 pthread_mutex_unlock(&adev->lock);
509 *stream_out = NULL;
510 return ret;
511 }
512
513 /* needs the adev->lock held */
adev_close_output_stream_locked(struct adev_a2dp * dev,struct astream_out * stream)514 static void adev_close_output_stream_locked(struct adev_a2dp *dev,
515 struct astream_out *stream)
516 {
517 struct adev_a2dp *adev = (struct adev_a2dp *)dev;
518 struct astream_out *out = (struct astream_out *)stream;
519
520 /* invalid stream? */
521 if (!adev->output || adev->output != out) {
522 LOGE("%s: unknown stream %p (ours is %p)", __func__, out, adev->output);
523 return;
524 }
525
526 pthread_mutex_lock(&out->lock);
527 out_close_stream_locked(out);
528 pthread_mutex_unlock(&out->lock);
529
530 adev->output = NULL;
531 free(out);
532 }
533
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)534 static void adev_close_output_stream(struct audio_hw_device *dev,
535 struct audio_stream_out *stream)
536 {
537 struct adev_a2dp *adev = (struct adev_a2dp *)dev;
538 struct astream_out *out = (struct astream_out *)stream;
539
540 pthread_mutex_lock(&adev->lock);
541 adev_close_output_stream_locked(adev, out);
542 pthread_mutex_unlock(&adev->lock);
543 }
544
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)545 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
546 {
547 struct adev_a2dp *adev = (struct adev_a2dp *)dev;
548 struct str_parms *parms;
549 char *str;
550 char value[8];
551 int ret;
552
553 parms = str_parms_create_str(kvpairs);
554
555 pthread_mutex_lock(&adev->lock);
556
557 ret = str_parms_get_str(parms, BLUETOOOTH_ENABLED_PARM, value,
558 sizeof(value));
559 if (ret >= 0) {
560 adev->bt_enabled = !strcmp(value, "true");
561 if (adev->output)
562 _out_bt_enable(adev->output, adev->bt_enabled);
563 }
564
565 ret = str_parms_get_str(parms, A2DP_SUSPENDED_PARM, value, sizeof(value));
566 if (ret >= 0) {
567 adev->suspended = !strcmp(value, "true");
568 if (adev->output)
569 _out_a2dp_suspend(adev->output, adev->suspended);
570 }
571
572 pthread_mutex_unlock(&adev->lock);
573
574 str_parms_destroy(parms);
575
576 return ret;
577 }
578
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)579 static char * adev_get_parameters(const struct audio_hw_device *dev,
580 const char *keys)
581 {
582 struct adev_a2dp *adev = (struct adev_a2dp *)dev;
583 struct str_parms *parms;
584 struct str_parms *out_parms;
585 char *str;
586 char value[8];
587 int ret;
588
589 parms = str_parms_create_str(keys);
590 out_parms = str_parms_create();
591
592 pthread_mutex_lock(&adev->lock);
593
594 ret = str_parms_get_str(parms, BLUETOOOTH_ENABLED_PARM, value,
595 sizeof(value));
596 if (ret >= 0)
597 str_parms_add_str(out_parms, BLUETOOOTH_ENABLED_PARM,
598 adev->bt_enabled ? "true" : "false");
599
600 ret = str_parms_get_str(parms, A2DP_SUSPENDED_PARM, value, sizeof(value));
601 if (ret >= 0)
602 str_parms_add_str(out_parms, A2DP_SUSPENDED_PARM,
603 adev->suspended ? "true" : "false");
604
605 pthread_mutex_unlock(&adev->lock);
606
607 str = str_parms_to_str(out_parms);
608 str_parms_destroy(out_parms);
609 str_parms_destroy(parms);
610
611 return str;
612 }
613
adev_init_check(const struct audio_hw_device * dev)614 static int adev_init_check(const struct audio_hw_device *dev)
615 {
616 return 0;
617 }
618
adev_set_voice_volume(struct audio_hw_device * dev,float volume)619 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
620 {
621 return -ENOSYS;
622 }
623
adev_set_master_volume(struct audio_hw_device * dev,float volume)624 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
625 {
626 return -ENOSYS;
627 }
628
adev_set_mode(struct audio_hw_device * dev,int mode)629 static int adev_set_mode(struct audio_hw_device *dev, int mode)
630 {
631 /* TODO: do we care for the mode? */
632 return 0;
633 }
634
adev_set_mic_mute(struct audio_hw_device * dev,bool state)635 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
636 {
637 return -ENOSYS;
638 }
639
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)640 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
641 {
642 return -ENOSYS;
643 }
644
adev_get_input_buffer_size(const struct audio_hw_device * dev,uint32_t sample_rate,int format,int channel_count)645 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
646 uint32_t sample_rate, int format,
647 int channel_count)
648 {
649 /* no input */
650 return 0;
651 }
652
adev_open_input_stream(struct audio_hw_device * dev,uint32_t devices,int * format,uint32_t * channels,uint32_t * sample_rate,audio_in_acoustics_t acoustics,struct audio_stream_in ** stream_in)653 static int adev_open_input_stream(struct audio_hw_device *dev, uint32_t devices,
654 int *format, uint32_t *channels,
655 uint32_t *sample_rate,
656 audio_in_acoustics_t acoustics,
657 struct audio_stream_in **stream_in)
658 {
659 return -ENOSYS;
660 }
661
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * in)662 static void adev_close_input_stream(struct audio_hw_device *dev,
663 struct audio_stream_in *in)
664 {
665 return;
666 }
667
adev_dump(const audio_hw_device_t * device,int fd)668 static int adev_dump(const audio_hw_device_t *device, int fd)
669 {
670 return 0;
671 }
672
adev_close(hw_device_t * device)673 static int adev_close(hw_device_t *device)
674 {
675 struct adev_a2dp *adev = (struct adev_a2dp *)device;
676
677 pthread_mutex_lock(&adev->lock);
678 if (adev->output)
679 adev_close_output_stream_locked(adev, adev->output);
680 pthread_mutex_unlock(&adev->lock);
681 free(adev);
682
683 return 0;
684 }
685
adev_get_supported_devices(const struct audio_hw_device * dev)686 static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev)
687 {
688 return AUDIO_DEVICE_OUT_ALL_A2DP;
689 }
690
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)691 static int adev_open(const hw_module_t* module, const char* name,
692 hw_device_t** device)
693 {
694 struct adev_a2dp *adev;
695 int ret;
696
697 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
698 return -EINVAL;
699
700 adev = calloc(1, sizeof(struct adev_a2dp));
701 if (!adev)
702 return -ENOMEM;
703
704 adev->bt_enabled = true;
705 adev->suspended = false;
706 pthread_mutex_init(&adev->lock, NULL);
707 adev->output = NULL;
708
709 adev->device.common.tag = HARDWARE_DEVICE_TAG;
710 adev->device.common.version = 0;
711 adev->device.common.module = (struct hw_module_t *) module;
712 adev->device.common.close = adev_close;
713
714 adev->device.get_supported_devices = adev_get_supported_devices;
715 adev->device.init_check = adev_init_check;
716 adev->device.set_voice_volume = adev_set_voice_volume;
717 adev->device.set_master_volume = adev_set_master_volume;
718 adev->device.set_mode = adev_set_mode;
719 adev->device.set_mic_mute = adev_set_mic_mute;
720 adev->device.get_mic_mute = adev_get_mic_mute;
721 adev->device.set_parameters = adev_set_parameters;
722 adev->device.get_parameters = adev_get_parameters;
723 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
724 adev->device.open_output_stream = adev_open_output_stream;
725 adev->device.close_output_stream = adev_close_output_stream;
726 adev->device.open_input_stream = adev_open_input_stream;
727 adev->device.close_input_stream = adev_close_input_stream;
728 adev->device.dump = adev_dump;
729
730 *device = &adev->device.common;
731
732 return 0;
733
734 err_str_parms_create:
735 free(adev);
736 return ret;
737 }
738
739 static struct hw_module_methods_t hal_module_methods = {
740 .open = adev_open,
741 };
742
743 struct audio_module HAL_MODULE_INFO_SYM = {
744 .common = {
745 .tag = HARDWARE_MODULE_TAG,
746 .version_major = 1,
747 .version_minor = 0,
748 .id = AUDIO_HARDWARE_MODULE_ID,
749 .name = "A2DP Audio HW HAL",
750 .author = "The Android Open Source Project",
751 .methods = &hal_module_methods,
752 },
753 };
754
755
756