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