• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2009-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /*****************************************************************************
20  *
21  *  Filename:      audio_a2dp_hw.c
22  *
23  *  Description:   Implements hal for bluedroid a2dp audio device
24  *
25  *****************************************************************************/
26 
27 #include <errno.h>
28 #include <inttypes.h>
29 #include <pthread.h>
30 #include <stdint.h>
31 #include <sys/time.h>
32 #include <sys/socket.h>
33 #include <sys/un.h>
34 #include <sys/poll.h>
35 #include <sys/errno.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38 #include <fcntl.h>
39 #include <cutils/str_parms.h>
40 #include <cutils/sockets.h>
41 
42 #include <system/audio.h>
43 #include <hardware/audio.h>
44 
45 #include <hardware/hardware.h>
46 #include "audio_a2dp_hw.h"
47 #include "bt_utils.h"
48 
49 #define LOG_TAG "bt_a2dp_hw"
50 #include "osi/include/log.h"
51 
52 /*****************************************************************************
53 **  Constants & Macros
54 ******************************************************************************/
55 
56 #define CTRL_CHAN_RETRY_COUNT 3
57 #define USEC_PER_SEC 1000000L
58 
59 #define CASE_RETURN_STR(const) case const: return #const;
60 
61 #define FNLOG()             LOG_VERBOSE("%s", __FUNCTION__);
62 #define DEBUG(fmt, ...)     LOG_VERBOSE("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
63 #define INFO(fmt, ...)      LOG_INFO("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
64 #define ERROR(fmt, ...)     LOG_ERROR("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
65 
66 #define ASSERTC(cond, msg, val) if (!(cond)) {ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
67 
68 /*****************************************************************************
69 **  Local type definitions
70 ******************************************************************************/
71 
72 typedef enum {
73     AUDIO_A2DP_STATE_STARTING,
74     AUDIO_A2DP_STATE_STARTED,
75     AUDIO_A2DP_STATE_STOPPING,
76     AUDIO_A2DP_STATE_STOPPED,
77     AUDIO_A2DP_STATE_SUSPENDED, /* need explicit set param call to resume (suspend=false) */
78     AUDIO_A2DP_STATE_STANDBY    /* allows write to autoresume */
79 } a2dp_state_t;
80 
81 struct a2dp_stream_in;
82 struct a2dp_stream_out;
83 
84 struct a2dp_audio_device {
85     struct audio_hw_device device;
86     struct a2dp_stream_in  *input;
87     struct a2dp_stream_out *output;
88 };
89 
90 struct a2dp_config {
91     uint32_t                rate;
92     uint32_t                channel_flags;
93     int                     format;
94 };
95 
96 /* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
97 
98 struct a2dp_stream_common {
99     pthread_mutex_t         lock;
100     int                     ctrl_fd;
101     int                     audio_fd;
102     size_t                  buffer_sz;
103     struct a2dp_config      cfg;
104     a2dp_state_t            state;
105 };
106 
107 struct a2dp_stream_out {
108     struct audio_stream_out stream;
109     struct a2dp_stream_common common;
110     uint64_t frames_presented; // frames written, never reset
111     uint64_t frames_rendered;  // frames written, reset on standby
112 };
113 
114 struct a2dp_stream_in {
115     struct audio_stream_in  stream;
116     struct a2dp_stream_common common;
117 };
118 
119 /*****************************************************************************
120 **  Static variables
121 ******************************************************************************/
122 
123 /*****************************************************************************
124 **  Static functions
125 ******************************************************************************/
126 
127 static size_t out_get_buffer_size(const struct audio_stream *stream);
128 
129 /*****************************************************************************
130 **  Externs
131 ******************************************************************************/
132 
133 /*****************************************************************************
134 **  Functions
135 ******************************************************************************/
136 
137 /*****************************************************************************
138 **   Miscellaneous helper functions
139 ******************************************************************************/
140 
dump_a2dp_ctrl_event(char event)141 static const char* dump_a2dp_ctrl_event(char event)
142 {
143     switch(event)
144     {
145         CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
146         CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
147         CASE_RETURN_STR(A2DP_CTRL_CMD_START)
148         CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
149         CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
150         default:
151             return "UNKNOWN MSG ID";
152     }
153 }
154 
155 /* logs timestamp with microsec precision
156    pprev is optional in case a dedicated diff is required */
ts_log(char * tag,int val,struct timespec * pprev_opt)157 static void ts_log(char *tag, int val, struct timespec *pprev_opt)
158 {
159     struct timespec now;
160     static struct timespec prev = {0,0};
161     unsigned long long now_us;
162     unsigned long long diff_us;
163     UNUSED(tag);
164     UNUSED(val);
165 
166     clock_gettime(CLOCK_MONOTONIC, &now);
167 
168     now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
169 
170     if (pprev_opt)
171     {
172         diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
173         *pprev_opt = now;
174         DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
175     }
176     else
177     {
178         diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
179         prev = now;
180         DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
181     }
182 }
183 
calc_audiotime(struct a2dp_config cfg,int bytes)184 static int calc_audiotime(struct a2dp_config cfg, int bytes)
185 {
186     int chan_count = popcount(cfg.channel_flags);
187 
188     ASSERTC(cfg.format == AUDIO_FORMAT_PCM_16_BIT,
189             "unsupported sample sz", cfg.format);
190 
191     return bytes*(1000000/(chan_count*2))/cfg.rate;
192 }
193 
194 /*****************************************************************************
195 **
196 **   bluedroid stack adaptation
197 **
198 *****************************************************************************/
199 
skt_connect(char * path,size_t buffer_sz)200 static int skt_connect(char *path, size_t buffer_sz)
201 {
202     int ret;
203     int skt_fd;
204     struct sockaddr_un remote;
205     int len;
206 
207     INFO("connect to %s (sz %zu)", path, buffer_sz);
208 
209     skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
210 
211     if(socket_local_client_connect(skt_fd, path,
212             ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
213     {
214         ERROR("failed to connect (%s)", strerror(errno));
215         close(skt_fd);
216         return -1;
217     }
218 
219     len = buffer_sz;
220     ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
221 
222     /* only issue warning if failed */
223     if (ret < 0)
224         ERROR("setsockopt failed (%s)", strerror(errno));
225 
226     ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
227 
228     /* only issue warning if failed */
229     if (ret < 0)
230         ERROR("setsockopt failed (%s)", strerror(errno));
231 
232     INFO("connected to stack fd = %d", skt_fd);
233 
234     return skt_fd;
235 }
236 
skt_read(int fd,void * p,size_t len)237 static int skt_read(int fd, void *p, size_t len)
238 {
239     int read;
240     struct pollfd pfd;
241     struct timespec ts;
242 
243     FNLOG();
244 
245     ts_log("skt_read recv", len, NULL);
246 
247     if ((read = TEMP_FAILURE_RETRY(recv(fd, p, len, MSG_NOSIGNAL))) == -1)
248     {
249         ERROR("write failed with errno=%d\n", errno);
250         return -1;
251     }
252 
253     return read;
254 }
255 
skt_write(int fd,const void * p,size_t len)256 static int skt_write(int fd, const void *p, size_t len)
257 {
258     int sent;
259     struct pollfd pfd;
260 
261     FNLOG();
262 
263     pfd.fd = fd;
264     pfd.events = POLLOUT;
265 
266     /* poll for 500 ms */
267 
268     /* send time out */
269     if (TEMP_FAILURE_RETRY(poll(&pfd, 1, 500)) == 0)
270         return 0;
271 
272     ts_log("skt_write", len, NULL);
273 
274     if ((sent = TEMP_FAILURE_RETRY(send(fd, p, len, MSG_NOSIGNAL))) == -1)
275     {
276         ERROR("write failed with errno=%d\n", errno);
277         return -1;
278     }
279 
280     return sent;
281 }
282 
skt_disconnect(int fd)283 static int skt_disconnect(int fd)
284 {
285     INFO("fd %d", fd);
286 
287     if (fd != AUDIO_SKT_DISCONNECTED)
288     {
289         shutdown(fd, SHUT_RDWR);
290         close(fd);
291     }
292     return 0;
293 }
294 
295 
296 
297 /*****************************************************************************
298 **
299 **  AUDIO CONTROL PATH
300 **
301 *****************************************************************************/
302 
a2dp_ctrl_receive(struct a2dp_stream_common * common,void * buffer,int length)303 static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length)
304 {
305     int ret = TEMP_FAILURE_RETRY(recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
306     if (ret < 0)
307     {
308         ERROR("ack failed (%s)", strerror(errno));
309         if (errno == EINTR)
310         {
311             /* retry again */
312             ret = TEMP_FAILURE_RETRY(recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
313             if (ret < 0)
314             {
315                ERROR("ack failed (%s)", strerror(errno));
316                skt_disconnect(common->ctrl_fd);
317                common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
318                return -1;
319             }
320         }
321         else
322         {
323                skt_disconnect(common->ctrl_fd);
324                common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
325                return -1;
326 
327         }
328     }
329     return ret;
330 }
331 
a2dp_command(struct a2dp_stream_common * common,char cmd)332 static int a2dp_command(struct a2dp_stream_common *common, char cmd)
333 {
334     char ack;
335 
336     DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd));
337 
338     /* send command */
339     if (TEMP_FAILURE_RETRY(send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL)) == -1)
340     {
341         ERROR("cmd failed (%s)", strerror(errno));
342         skt_disconnect(common->ctrl_fd);
343         common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
344         return -1;
345     }
346 
347     /* wait for ack byte */
348     if (a2dp_ctrl_receive(common, &ack, 1) < 0)
349         return -1;
350 
351     DEBUG("A2DP COMMAND %s DONE STATUS %d", dump_a2dp_ctrl_event(cmd), ack);
352 
353     if (ack == A2DP_CTRL_ACK_INCALL_FAILURE)
354         return ack;
355     if (ack != A2DP_CTRL_ACK_SUCCESS)
356         return -1;
357 
358     return 0;
359 }
360 
check_a2dp_ready(struct a2dp_stream_common * common)361 static int check_a2dp_ready(struct a2dp_stream_common *common)
362 {
363     if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0)
364     {
365         ERROR("check a2dp ready failed");
366         return -1;
367     }
368     return 0;
369 }
370 
a2dp_read_audio_config(struct a2dp_stream_common * common)371 static int a2dp_read_audio_config(struct a2dp_stream_common *common)
372 {
373     char cmd = A2DP_CTRL_GET_AUDIO_CONFIG;
374     uint32_t sample_rate;
375     uint8_t channel_count;
376 
377     if (a2dp_command(common, A2DP_CTRL_GET_AUDIO_CONFIG) < 0)
378     {
379         ERROR("check a2dp ready failed");
380         return -1;
381     }
382 
383     if (a2dp_ctrl_receive(common, &sample_rate, 4) < 0)
384         return -1;
385     if (a2dp_ctrl_receive(common, &channel_count, 1) < 0)
386         return -1;
387 
388     common->cfg.channel_flags = (channel_count == 1 ? AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO);
389     common->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
390     common->cfg.rate = sample_rate;
391 
392     INFO("got config %d %d", common->cfg.format, common->cfg.rate);
393 
394     return 0;
395 }
396 
a2dp_open_ctrl_path(struct a2dp_stream_common * common)397 static void a2dp_open_ctrl_path(struct a2dp_stream_common *common)
398 {
399     int i;
400 
401     /* retry logic to catch any timing variations on control channel */
402     for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++)
403     {
404         /* connect control channel if not already connected */
405         if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0)
406         {
407             /* success, now check if stack is ready */
408             if (check_a2dp_ready(common) == 0)
409                 break;
410 
411             ERROR("error : a2dp not ready, wait 250 ms and retry");
412             TEMP_FAILURE_RETRY(usleep(250000));
413             skt_disconnect(common->ctrl_fd);
414             common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
415         }
416 
417         /* ctrl channel not ready, wait a bit */
418         TEMP_FAILURE_RETRY(usleep(250000));
419     }
420 }
421 
422 /*****************************************************************************
423 **
424 ** AUDIO DATA PATH
425 **
426 *****************************************************************************/
427 
a2dp_stream_common_init(struct a2dp_stream_common * common)428 static void a2dp_stream_common_init(struct a2dp_stream_common *common)
429 {
430     pthread_mutexattr_t lock_attr;
431 
432     FNLOG();
433 
434     pthread_mutexattr_init(&lock_attr);
435     pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
436     pthread_mutex_init(&common->lock, &lock_attr);
437 
438     common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
439     common->audio_fd = AUDIO_SKT_DISCONNECTED;
440     common->state = AUDIO_A2DP_STATE_STOPPED;
441 
442     /* manages max capacity of socket pipe */
443     common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
444 }
445 
start_audio_datapath(struct a2dp_stream_common * common)446 static int start_audio_datapath(struct a2dp_stream_common *common)
447 {
448     INFO("state %d", common->state);
449 
450     if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
451         INFO("%s AUDIO_SKT_DISCONNECTED", __func__);
452         return -1;
453     }
454 
455     int oldstate = common->state;
456     common->state = AUDIO_A2DP_STATE_STARTING;
457 
458     int a2dp_status = a2dp_command(common, A2DP_CTRL_CMD_START);
459     if (a2dp_status < 0)
460     {
461         ERROR("%s Audiopath start failed (status %d)", __func__, a2dp_status);
462 
463         common->state = oldstate;
464         return -1;
465     }
466     else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE)
467     {
468         ERROR("%s Audiopath start failed - in call, move to suspended", __func__);
469         common->state = oldstate;
470         return -1;
471     }
472 
473     /* connect socket if not yet connected */
474     if (common->audio_fd == AUDIO_SKT_DISCONNECTED)
475     {
476         common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
477         if (common->audio_fd < 0)
478         {
479             common->state = oldstate;
480             return -1;
481         }
482 
483         common->state = AUDIO_A2DP_STATE_STARTED;
484     }
485 
486     return 0;
487 }
488 
stop_audio_datapath(struct a2dp_stream_common * common)489 static int stop_audio_datapath(struct a2dp_stream_common *common)
490 {
491     int oldstate = common->state;
492 
493     INFO("state %d", common->state);
494 
495     if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
496          return -1;
497 
498     /* prevent any stray output writes from autostarting the stream
499        while stopping audiopath */
500     common->state = AUDIO_A2DP_STATE_STOPPING;
501 
502     if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0)
503     {
504         ERROR("audiopath stop failed");
505         common->state = oldstate;
506         return -1;
507     }
508 
509     common->state = AUDIO_A2DP_STATE_STOPPED;
510 
511     /* disconnect audio path */
512     skt_disconnect(common->audio_fd);
513     common->audio_fd = AUDIO_SKT_DISCONNECTED;
514 
515     return 0;
516 }
517 
suspend_audio_datapath(struct a2dp_stream_common * common,bool standby)518 static int suspend_audio_datapath(struct a2dp_stream_common *common, bool standby)
519 {
520     INFO("state %d", common->state);
521 
522     if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
523          return -1;
524 
525     if (common->state == AUDIO_A2DP_STATE_STOPPING)
526         return -1;
527 
528     if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0)
529         return -1;
530 
531     if (standby)
532         common->state = AUDIO_A2DP_STATE_STANDBY;
533     else
534         common->state = AUDIO_A2DP_STATE_SUSPENDED;
535 
536     /* disconnect audio path */
537     skt_disconnect(common->audio_fd);
538 
539     common->audio_fd = AUDIO_SKT_DISCONNECTED;
540 
541     return 0;
542 }
543 
544 
545 /*****************************************************************************
546 **
547 **  audio output callbacks
548 **
549 *****************************************************************************/
550 
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)551 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
552                          size_t bytes)
553 {
554     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
555     int sent;
556 
557     DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
558 
559     pthread_mutex_lock(&out->common.lock);
560 
561     if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
562     {
563         DEBUG("stream suspended");
564         pthread_mutex_unlock(&out->common.lock);
565         return -1;
566     }
567 
568     /* only allow autostarting if we are in stopped or standby */
569     if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) ||
570         (out->common.state == AUDIO_A2DP_STATE_STANDBY))
571     {
572         if (start_audio_datapath(&out->common) < 0)
573         {
574             /* emulate time this write represents to avoid very fast write
575                failures during transition periods or remote suspend */
576 
577             int us_delay = calc_audiotime(out->common.cfg, bytes);
578 
579             DEBUG("emulate a2dp write delay (%d us)", us_delay);
580 
581             TEMP_FAILURE_RETRY(usleep(us_delay));
582             pthread_mutex_unlock(&out->common.lock);
583             return -1;
584         }
585     }
586     else if (out->common.state != AUDIO_A2DP_STATE_STARTED)
587     {
588         ERROR("stream not in stopped or standby");
589         pthread_mutex_unlock(&out->common.lock);
590         return -1;
591     }
592 
593     pthread_mutex_unlock(&out->common.lock);
594     sent = skt_write(out->common.audio_fd, buffer,  bytes);
595 
596     if (sent == -1) {
597         skt_disconnect(out->common.audio_fd);
598         out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
599         if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
600             out->common.state = AUDIO_A2DP_STATE_STOPPED;
601         else
602             ERROR("write failed : stream suspended, avoid resetting state");
603     } else {
604         const size_t frames = bytes / audio_stream_out_frame_size(stream);
605         out->frames_rendered += frames;
606         out->frames_presented += frames;
607     }
608 
609     DEBUG("wrote %d bytes out of %zu bytes", sent, bytes);
610     return sent;
611 }
612 
613 
out_get_sample_rate(const struct audio_stream * stream)614 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
615 {
616     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
617 
618     DEBUG("rate %" PRIu32,out->common.cfg.rate);
619 
620     return out->common.cfg.rate;
621 }
622 
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)623 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
624 {
625     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
626 
627     DEBUG("out_set_sample_rate : %" PRIu32, rate);
628 
629     if (rate != AUDIO_STREAM_DEFAULT_RATE)
630     {
631         ERROR("only rate %d supported", AUDIO_STREAM_DEFAULT_RATE);
632         return -1;
633     }
634 
635     out->common.cfg.rate = rate;
636 
637     return 0;
638 }
639 
out_get_buffer_size(const struct audio_stream * stream)640 static size_t out_get_buffer_size(const struct audio_stream *stream)
641 {
642     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
643 
644     DEBUG("buffer_size : %zu", out->common.buffer_sz);
645 
646     return out->common.buffer_sz;
647 }
648 
out_get_channels(const struct audio_stream * stream)649 static uint32_t out_get_channels(const struct audio_stream *stream)
650 {
651     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
652 
653     DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_flags);
654 
655     return out->common.cfg.channel_flags;
656 }
657 
out_get_format(const struct audio_stream * stream)658 static audio_format_t out_get_format(const struct audio_stream *stream)
659 {
660     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
661     DEBUG("format 0x%x", out->common.cfg.format);
662     return out->common.cfg.format;
663 }
664 
out_set_format(struct audio_stream * stream,audio_format_t format)665 static int out_set_format(struct audio_stream *stream, audio_format_t format)
666 {
667     UNUSED(format);
668     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
669     DEBUG("setting format not yet supported (0x%x)", format);
670     return -ENOSYS;
671 }
672 
out_standby(struct audio_stream * stream)673 static int out_standby(struct audio_stream *stream)
674 {
675     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
676     int retVal = 0;
677 
678     FNLOG();
679 
680     pthread_mutex_lock(&out->common.lock);
681     // Do nothing in SUSPENDED state.
682     if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
683         retVal = suspend_audio_datapath(&out->common, true);
684     out->frames_rendered = 0; // rendered is reset, presented is not
685     pthread_mutex_unlock (&out->common.lock);
686 
687     return retVal;
688 }
689 
out_dump(const struct audio_stream * stream,int fd)690 static int out_dump(const struct audio_stream *stream, int fd)
691 {
692     UNUSED(fd);
693     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
694     FNLOG();
695     return 0;
696 }
697 
out_set_parameters(struct audio_stream * stream,const char * kvpairs)698 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
699 {
700     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
701     struct str_parms *parms;
702     char keyval[16];
703     int retval;
704     int status = 0;
705 
706     INFO("state %d", out->common.state);
707 
708     parms = str_parms_create_str(kvpairs);
709 
710     /* dump params */
711     str_parms_dump(parms);
712 
713     retval = str_parms_get_str(parms, "closing", keyval, sizeof(keyval));
714 
715     if (retval >= 0)
716     {
717         if (strcmp(keyval, "true") == 0)
718         {
719             DEBUG("stream closing, disallow any writes");
720             pthread_mutex_lock(&out->common.lock);
721             out->common.state = AUDIO_A2DP_STATE_STOPPING;
722             pthread_mutex_unlock(&out->common.lock);
723         }
724     }
725 
726     retval = str_parms_get_str(parms, "A2dpSuspended", keyval, sizeof(keyval));
727 
728     if (retval >= 0)
729     {
730         pthread_mutex_lock(&out->common.lock);
731         if (strcmp(keyval, "true") == 0)
732         {
733             if (out->common.state == AUDIO_A2DP_STATE_STARTED)
734                 status = suspend_audio_datapath(&out->common, false);
735         }
736         else
737         {
738             /* Do not start the streaming automatically. If the phone was streaming
739              * prior to being suspended, the next out_write shall trigger the
740              * AVDTP start procedure */
741             if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
742                 out->common.state = AUDIO_A2DP_STATE_STANDBY;
743             /* Irrespective of the state, return 0 */
744         }
745         pthread_mutex_unlock(&out->common.lock);
746     }
747 
748     str_parms_destroy(parms);
749 
750     return status;
751 }
752 
out_get_parameters(const struct audio_stream * stream,const char * keys)753 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
754 {
755     UNUSED(keys);
756     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
757 
758     FNLOG();
759 
760     /* add populating param here */
761 
762     return strdup("");
763 }
764 
out_get_latency(const struct audio_stream_out * stream)765 static uint32_t out_get_latency(const struct audio_stream_out *stream)
766 {
767     int latency_us;
768 
769     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
770 
771     FNLOG();
772 
773     latency_us = ((out->common.buffer_sz * 1000 ) /
774                     audio_stream_out_frame_size(&out->stream) /
775                     out->common.cfg.rate) * 1000;
776 
777 
778     return (latency_us / 1000) + 200;
779 }
780 
out_set_volume(struct audio_stream_out * stream,float left,float right)781 static int out_set_volume(struct audio_stream_out *stream, float left,
782                           float right)
783 {
784     UNUSED(stream);
785     UNUSED(left);
786     UNUSED(right);
787 
788     FNLOG();
789 
790     /* volume controlled in audioflinger mixer (digital) */
791 
792     return -ENOSYS;
793 }
794 
out_get_presentation_position(const struct audio_stream_out * stream,uint64_t * frames,struct timespec * timestamp)795 static int out_get_presentation_position(const struct audio_stream_out *stream,
796                                          uint64_t *frames, struct timespec *timestamp)
797 {
798     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
799 
800     FNLOG();
801     if (stream == NULL || frames == NULL || timestamp == NULL)
802         return -EINVAL;
803 
804     int ret = -EWOULDBLOCK;
805     pthread_mutex_lock(&out->common.lock);
806     uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
807     if (out->frames_presented >= latency_frames) {
808         *frames = out->frames_presented - latency_frames;
809         clock_gettime(CLOCK_MONOTONIC, timestamp); // could also be associated with out_write().
810         ret = 0;
811     }
812     pthread_mutex_unlock(&out->common.lock);
813     return ret;
814 }
815 
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)816 static int out_get_render_position(const struct audio_stream_out *stream,
817                                    uint32_t *dsp_frames)
818 {
819     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
820 
821     FNLOG();
822     if (stream == NULL || dsp_frames == NULL)
823         return -EINVAL;
824 
825     pthread_mutex_lock(&out->common.lock);
826     uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
827     if (out->frames_rendered >= latency_frames) {
828         *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
829     } else {
830         *dsp_frames = 0;
831     }
832     pthread_mutex_unlock(&out->common.lock);
833     return 0;
834 }
835 
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)836 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
837 {
838     UNUSED(stream);
839     UNUSED(effect);
840 
841     FNLOG();
842     return 0;
843 }
844 
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)845 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
846 {
847     UNUSED(stream);
848     UNUSED(effect);
849 
850     FNLOG();
851     return 0;
852 }
853 
854 /*
855  * AUDIO INPUT STREAM
856  */
857 
in_get_sample_rate(const struct audio_stream * stream)858 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
859 {
860     struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
861 
862     FNLOG();
863     return in->common.cfg.rate;
864 }
865 
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)866 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
867 {
868     struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
869 
870     FNLOG();
871 
872     if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
873         return 0;
874     else
875         return -1;
876 }
877 
in_get_buffer_size(const struct audio_stream * stream)878 static size_t in_get_buffer_size(const struct audio_stream *stream)
879 {
880     UNUSED(stream);
881 
882     FNLOG();
883     return 320;
884 }
885 
in_get_channels(const struct audio_stream * stream)886 static uint32_t in_get_channels(const struct audio_stream *stream)
887 {
888     struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
889 
890     FNLOG();
891     return in->common.cfg.channel_flags;
892 }
893 
in_get_format(const struct audio_stream * stream)894 static audio_format_t in_get_format(const struct audio_stream *stream)
895 {
896     UNUSED(stream);
897 
898     FNLOG();
899     return AUDIO_FORMAT_PCM_16_BIT;
900 }
901 
in_set_format(struct audio_stream * stream,audio_format_t format)902 static int in_set_format(struct audio_stream *stream, audio_format_t format)
903 {
904     UNUSED(stream);
905     UNUSED(format);
906 
907     FNLOG();
908     if (format == AUDIO_FORMAT_PCM_16_BIT)
909         return 0;
910     else
911         return -1;
912 }
913 
in_standby(struct audio_stream * stream)914 static int in_standby(struct audio_stream *stream)
915 {
916     UNUSED(stream);
917 
918     FNLOG();
919     return 0;
920 }
921 
in_dump(const struct audio_stream * stream,int fd)922 static int in_dump(const struct audio_stream *stream, int fd)
923 {
924     UNUSED(stream);
925     UNUSED(fd);
926 
927     FNLOG();
928     return 0;
929 }
930 
in_set_parameters(struct audio_stream * stream,const char * kvpairs)931 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
932 {
933     UNUSED(stream);
934     UNUSED(kvpairs);
935 
936     FNLOG();
937     return 0;
938 }
939 
in_get_parameters(const struct audio_stream * stream,const char * keys)940 static char * in_get_parameters(const struct audio_stream *stream,
941                                 const char *keys)
942 {
943     UNUSED(stream);
944     UNUSED(keys);
945 
946     FNLOG();
947     return strdup("");
948 }
949 
in_set_gain(struct audio_stream_in * stream,float gain)950 static int in_set_gain(struct audio_stream_in *stream, float gain)
951 {
952     UNUSED(stream);
953     UNUSED(gain);
954 
955     FNLOG();
956     return 0;
957 }
958 
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)959 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
960                        size_t bytes)
961 {
962     struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
963     int read;
964 
965     DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
966 
967     if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED)
968     {
969         DEBUG("stream suspended");
970         return -1;
971     }
972 
973     /* only allow autostarting if we are in stopped or standby */
974     if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) ||
975         (in->common.state == AUDIO_A2DP_STATE_STANDBY))
976     {
977         pthread_mutex_lock(&in->common.lock);
978 
979         if (start_audio_datapath(&in->common) < 0)
980         {
981             /* emulate time this write represents to avoid very fast write
982                failures during transition periods or remote suspend */
983 
984             int us_delay = calc_audiotime(in->common.cfg, bytes);
985 
986             DEBUG("emulate a2dp read delay (%d us)", us_delay);
987 
988             TEMP_FAILURE_RETRY(usleep(us_delay));
989             pthread_mutex_unlock(&in->common.lock);
990             return -1;
991         }
992 
993         pthread_mutex_unlock(&in->common.lock);
994     }
995     else if (in->common.state != AUDIO_A2DP_STATE_STARTED)
996     {
997         ERROR("stream not in stopped or standby");
998         return -1;
999     }
1000 
1001     read = skt_read(in->common.audio_fd, buffer, bytes);
1002 
1003     if (read == -1)
1004     {
1005         skt_disconnect(in->common.audio_fd);
1006         in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
1007         in->common.state = AUDIO_A2DP_STATE_STOPPED;
1008     } else if (read == 0) {
1009         DEBUG("read time out - return zeros");
1010         memset(buffer, 0, bytes);
1011         read = bytes;
1012     }
1013 
1014     DEBUG("read %d bytes out of %zu bytes", read, bytes);
1015     return read;
1016 }
1017 
in_get_input_frames_lost(struct audio_stream_in * stream)1018 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
1019 {
1020     UNUSED(stream);
1021 
1022     FNLOG();
1023     return 0;
1024 }
1025 
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)1026 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1027 {
1028     UNUSED(stream);
1029     UNUSED(effect);
1030 
1031     FNLOG();
1032     return 0;
1033 }
1034 
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)1035 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1036 {
1037     UNUSED(stream);
1038     UNUSED(effect);
1039 
1040     FNLOG();
1041 
1042     return 0;
1043 }
1044 
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)1045 static int adev_open_output_stream(struct audio_hw_device *dev,
1046                                    audio_io_handle_t handle,
1047                                    audio_devices_t devices,
1048                                    audio_output_flags_t flags,
1049                                    struct audio_config *config,
1050                                    struct audio_stream_out **stream_out,
1051                                    const char *address)
1052 
1053 {
1054     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1055     struct a2dp_stream_out *out;
1056     int ret = 0;
1057     int i;
1058     UNUSED(address);
1059     UNUSED(handle);
1060     UNUSED(devices);
1061     UNUSED(flags);
1062 
1063     INFO("opening output");
1064 
1065     out = (struct a2dp_stream_out *)calloc(1, sizeof(struct a2dp_stream_out));
1066 
1067     if (!out)
1068         return -ENOMEM;
1069 
1070     out->stream.common.get_sample_rate = out_get_sample_rate;
1071     out->stream.common.set_sample_rate = out_set_sample_rate;
1072     out->stream.common.get_buffer_size = out_get_buffer_size;
1073     out->stream.common.get_channels = out_get_channels;
1074     out->stream.common.get_format = out_get_format;
1075     out->stream.common.set_format = out_set_format;
1076     out->stream.common.standby = out_standby;
1077     out->stream.common.dump = out_dump;
1078     out->stream.common.set_parameters = out_set_parameters;
1079     out->stream.common.get_parameters = out_get_parameters;
1080     out->stream.common.add_audio_effect = out_add_audio_effect;
1081     out->stream.common.remove_audio_effect = out_remove_audio_effect;
1082     out->stream.get_latency = out_get_latency;
1083     out->stream.set_volume = out_set_volume;
1084     out->stream.write = out_write;
1085     out->stream.get_render_position = out_get_render_position;
1086     out->stream.get_presentation_position = out_get_presentation_position;
1087 
1088 
1089     /* initialize a2dp specifics */
1090     a2dp_stream_common_init(&out->common);
1091 
1092     out->common.cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG;
1093     out->common.cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
1094     out->common.cfg.rate = AUDIO_STREAM_DEFAULT_RATE;
1095 
1096    /* set output config values */
1097    if (config)
1098    {
1099       config->format = out_get_format((const struct audio_stream *)&out->stream);
1100       config->sample_rate = out_get_sample_rate((const struct audio_stream *)&out->stream);
1101       config->channel_mask = out_get_channels((const struct audio_stream *)&out->stream);
1102    }
1103     *stream_out = &out->stream;
1104     a2dp_dev->output = out;
1105 
1106     a2dp_open_ctrl_path(&out->common);
1107     if (out->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
1108     {
1109         ERROR("ctrl socket failed to connect (%s)", strerror(errno));
1110         ret = -1;
1111         goto err_open;
1112     }
1113 
1114     DEBUG("success");
1115     /* Delay to ensure Headset is in proper state when START is initiated
1116        from DUT immediately after the connection due to ongoing music playback. */
1117     TEMP_FAILURE_RETRY(usleep(250000));
1118     return 0;
1119 
1120 err_open:
1121     free(out);
1122     *stream_out = NULL;
1123     a2dp_dev->output = NULL;
1124     ERROR("failed");
1125     return ret;
1126 }
1127 
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)1128 static void adev_close_output_stream(struct audio_hw_device *dev,
1129                                      struct audio_stream_out *stream)
1130 {
1131     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1132     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
1133 
1134     INFO("closing output (state %d)", out->common.state);
1135 
1136     pthread_mutex_lock(&out->common.lock);
1137     if ((out->common.state == AUDIO_A2DP_STATE_STARTED) || (out->common.state == AUDIO_A2DP_STATE_STOPPING))
1138         stop_audio_datapath(&out->common);
1139 
1140     skt_disconnect(out->common.ctrl_fd);
1141     free(stream);
1142     a2dp_dev->output = NULL;
1143     pthread_mutex_unlock(&out->common.lock);
1144 
1145     DEBUG("done");
1146 }
1147 
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)1148 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1149 {
1150     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1151     struct a2dp_stream_out *out = a2dp_dev->output;
1152     int retval = 0;
1153 
1154     if (out == NULL)
1155         return retval;
1156 
1157     INFO("state %d", out->common.state);
1158 
1159     retval = out->stream.common.set_parameters((struct audio_stream *)out, kvpairs);
1160 
1161     return retval;
1162 }
1163 
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)1164 static char * adev_get_parameters(const struct audio_hw_device *dev,
1165                                   const char *keys)
1166 {
1167     struct str_parms *parms;
1168     UNUSED(dev);
1169 
1170     FNLOG();
1171 
1172     parms = str_parms_create_str(keys);
1173 
1174     str_parms_dump(parms);
1175 
1176     str_parms_destroy(parms);
1177 
1178     return strdup("");
1179 }
1180 
adev_init_check(const struct audio_hw_device * dev)1181 static int adev_init_check(const struct audio_hw_device *dev)
1182 {
1183     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device*)dev;
1184 
1185     FNLOG();
1186 
1187     return 0;
1188 }
1189 
adev_set_voice_volume(struct audio_hw_device * dev,float volume)1190 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1191 {
1192     UNUSED(dev);
1193     UNUSED(volume);
1194 
1195     FNLOG();
1196 
1197     return -ENOSYS;
1198 }
1199 
adev_set_master_volume(struct audio_hw_device * dev,float volume)1200 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1201 {
1202     UNUSED(dev);
1203     UNUSED(volume);
1204 
1205     FNLOG();
1206 
1207     return -ENOSYS;
1208 }
1209 
adev_set_mode(struct audio_hw_device * dev,int mode)1210 static int adev_set_mode(struct audio_hw_device *dev, int mode)
1211 {
1212     UNUSED(dev);
1213     UNUSED(mode);
1214 
1215     FNLOG();
1216 
1217     return 0;
1218 }
1219 
adev_set_mic_mute(struct audio_hw_device * dev,bool state)1220 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1221 {
1222     UNUSED(dev);
1223     UNUSED(state);
1224 
1225     FNLOG();
1226 
1227     return -ENOSYS;
1228 }
1229 
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)1230 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1231 {
1232     UNUSED(dev);
1233     UNUSED(state);
1234 
1235     FNLOG();
1236 
1237     return -ENOSYS;
1238 }
1239 
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)1240 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
1241                                          const struct audio_config *config)
1242 {
1243     UNUSED(dev);
1244     UNUSED(config);
1245 
1246     FNLOG();
1247 
1248     return 320;
1249 }
1250 
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,audio_source_t source)1251 static int adev_open_input_stream(struct audio_hw_device *dev,
1252                                   audio_io_handle_t handle,
1253                                   audio_devices_t devices,
1254                                   struct audio_config *config,
1255                                   struct audio_stream_in **stream_in,
1256                                   audio_input_flags_t flags,
1257                                   const char *address,
1258                                   audio_source_t source)
1259 {
1260     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1261     struct a2dp_stream_in *in;
1262     int ret;
1263     UNUSED(address);
1264     UNUSED(config);
1265     UNUSED(devices);
1266     UNUSED(flags);
1267     UNUSED(handle);
1268     UNUSED(source);
1269 
1270     FNLOG();
1271 
1272     in = (struct a2dp_stream_in *)calloc(1, sizeof(struct a2dp_stream_in));
1273 
1274     if (!in)
1275         return -ENOMEM;
1276 
1277     in->stream.common.get_sample_rate = in_get_sample_rate;
1278     in->stream.common.set_sample_rate = in_set_sample_rate;
1279     in->stream.common.get_buffer_size = in_get_buffer_size;
1280     in->stream.common.get_channels = in_get_channels;
1281     in->stream.common.get_format = in_get_format;
1282     in->stream.common.set_format = in_set_format;
1283     in->stream.common.standby = in_standby;
1284     in->stream.common.dump = in_dump;
1285     in->stream.common.set_parameters = in_set_parameters;
1286     in->stream.common.get_parameters = in_get_parameters;
1287     in->stream.common.add_audio_effect = in_add_audio_effect;
1288     in->stream.common.remove_audio_effect = in_remove_audio_effect;
1289     in->stream.set_gain = in_set_gain;
1290     in->stream.read = in_read;
1291     in->stream.get_input_frames_lost = in_get_input_frames_lost;
1292 
1293     /* initialize a2dp specifics */
1294     a2dp_stream_common_init(&in->common);
1295 
1296     *stream_in = &in->stream;
1297     a2dp_dev->input = in;
1298 
1299     a2dp_open_ctrl_path(&in->common);
1300     if (in->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
1301     {
1302         ERROR("ctrl socket failed to connect (%s)", strerror(errno));
1303         ret = -1;
1304         goto err_open;
1305     }
1306 
1307     if (a2dp_read_audio_config(&in->common) < 0) {
1308         ERROR("a2dp_read_audio_config failed (%s)", strerror(errno));
1309         ret = -1;
1310         goto err_open;
1311     }
1312 
1313     DEBUG("success");
1314     return 0;
1315 
1316 err_open:
1317     free(in);
1318     *stream_in = NULL;
1319     a2dp_dev->input = NULL;
1320     ERROR("failed");
1321     return ret;
1322 }
1323 
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * stream)1324 static void adev_close_input_stream(struct audio_hw_device *dev,
1325                                    struct audio_stream_in *stream)
1326 {
1327     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1328     struct a2dp_stream_in* in = (struct a2dp_stream_in *)stream;
1329     a2dp_state_t state = in->common.state;
1330 
1331     INFO("closing input (state %d)", state);
1332 
1333     if ((state == AUDIO_A2DP_STATE_STARTED) || (state == AUDIO_A2DP_STATE_STOPPING))
1334         stop_audio_datapath(&in->common);
1335 
1336     skt_disconnect(in->common.ctrl_fd);
1337     free(stream);
1338     a2dp_dev->input = NULL;
1339 
1340     DEBUG("done");
1341 }
1342 
adev_dump(const audio_hw_device_t * device,int fd)1343 static int adev_dump(const audio_hw_device_t *device, int fd)
1344 {
1345     UNUSED(device);
1346     UNUSED(fd);
1347 
1348     FNLOG();
1349 
1350     return 0;
1351 }
1352 
adev_close(hw_device_t * device)1353 static int adev_close(hw_device_t *device)
1354 {
1355     FNLOG();
1356 
1357     free(device);
1358     return 0;
1359 }
1360 
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)1361 static int adev_open(const hw_module_t* module, const char* name,
1362                      hw_device_t** device)
1363 {
1364     struct a2dp_audio_device *adev;
1365     int ret;
1366 
1367     INFO(" adev_open in A2dp_hw module");
1368     FNLOG();
1369 
1370     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1371     {
1372         ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
1373         return -EINVAL;
1374     }
1375 
1376     adev = calloc(1, sizeof(struct a2dp_audio_device));
1377 
1378     if (!adev)
1379         return -ENOMEM;
1380 
1381     adev->device.common.tag = HARDWARE_DEVICE_TAG;
1382     adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1383     adev->device.common.module = (struct hw_module_t *) module;
1384     adev->device.common.close = adev_close;
1385 
1386     adev->device.init_check = adev_init_check;
1387     adev->device.set_voice_volume = adev_set_voice_volume;
1388     adev->device.set_master_volume = adev_set_master_volume;
1389     adev->device.set_mode = adev_set_mode;
1390     adev->device.set_mic_mute = adev_set_mic_mute;
1391     adev->device.get_mic_mute = adev_get_mic_mute;
1392     adev->device.set_parameters = adev_set_parameters;
1393     adev->device.get_parameters = adev_get_parameters;
1394     adev->device.get_input_buffer_size = adev_get_input_buffer_size;
1395     adev->device.open_output_stream = adev_open_output_stream;
1396     adev->device.close_output_stream = adev_close_output_stream;
1397     adev->device.open_input_stream = adev_open_input_stream;
1398     adev->device.close_input_stream = adev_close_input_stream;
1399     adev->device.dump = adev_dump;
1400 
1401     adev->output = NULL;
1402 
1403 
1404     *device = &adev->device.common;
1405 
1406     return 0;
1407 }
1408 
1409 static struct hw_module_methods_t hal_module_methods = {
1410     .open = adev_open,
1411 };
1412 
1413 struct audio_module HAL_MODULE_INFO_SYM = {
1414     .common = {
1415         .tag = HARDWARE_MODULE_TAG,
1416         .version_major = 1,
1417         .version_minor = 0,
1418         .id = AUDIO_HARDWARE_MODULE_ID,
1419         .name = "A2DP Audio HW HAL",
1420         .author = "The Android Open Source Project",
1421         .methods = &hal_module_methods,
1422     },
1423 };
1424