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