AudioHardwareALSA.cpp revision 5ff7a02ca497656b711919b81a783e6a10cdcc76
1/* AudioHardwareALSA.cpp 2 ** 3 ** Copyright 2008-2010 Wind River Systems 4 ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. 5 ** 6 ** Licensed under the Apache License, Version 2.0 (the "License"); 7 ** you may not use this file except in compliance with the License. 8 ** You may obtain a copy of the License at 9 ** 10 ** http://www.apache.org/licenses/LICENSE-2.0 11 ** 12 ** Unless required by applicable law or agreed to in writing, software 13 ** distributed under the License is distributed on an "AS IS" BASIS, 14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 ** See the License for the specific language governing permissions and 16 ** limitations under the License. 17 */ 18 19#include <errno.h> 20#include <stdarg.h> 21#include <sys/stat.h> 22#include <fcntl.h> 23#include <stdlib.h> 24#include <unistd.h> 25#include <dlfcn.h> 26#include <math.h> 27 28#define LOG_TAG "AudioHardwareALSA" 29//#define LOG_NDEBUG 0 30#define LOG_NDDEBUG 0 31#include <utils/Log.h> 32#include <utils/String8.h> 33#include <sys/prctl.h> 34#include <sys/resource.h> 35#include <sys/poll.h> 36#include <sys/ioctl.h> 37#include <cutils/properties.h> 38#include <media/AudioRecord.h> 39#include <hardware_legacy/power.h> 40 41#include "AudioHardwareALSA.h" 42#ifdef QCOM_USBAUDIO_ENABLED 43#include "AudioUsbALSA.h" 44#endif 45 46extern "C" { 47#ifdef QCOM_CSDCLIENT_ENABLED 48#include "csd_client.h" 49#endif 50#ifdef QCOM_ACDB_ENABLED 51#include "acdb-loader.h" 52#endif 53} 54 55extern "C" 56{ 57 // 58 // Function for dlsym() to look up for creating a new AudioHardwareInterface. 59 // 60 android_audio_legacy::AudioHardwareInterface *createAudioHardware(void) { 61 return android_audio_legacy::AudioHardwareALSA::create(); 62 } 63#ifdef QCOM_ACDB_ENABLED 64 static int (*acdb_init)(); 65 static void (*acdb_deallocate)(); 66#endif 67#ifdef QCOM_CSDCLIENT_ENABLED 68 static int (*csd_start_playback)(); 69 static int (*csd_stop_playback)(); 70#endif 71} // extern "C" 72 73namespace android_audio_legacy 74{ 75 76// ---------------------------------------------------------------------------- 77 78AudioHardwareInterface *AudioHardwareALSA::create() { 79 return new AudioHardwareALSA(); 80} 81 82AudioHardwareALSA::AudioHardwareALSA() : 83 mALSADevice(0),mVoipStreamCount(0),mVoipMicMute(false),mVoipBitRate(0) 84 ,mCallState(0),mAcdbHandle(NULL),mCsdHandle(NULL) 85{ 86 FILE *fp; 87 char soundCardInfo[200]; 88 hw_module_t *module; 89 char platform[128], baseband[128]; 90 int err = hw_get_module(ALSA_HARDWARE_MODULE_ID, 91 (hw_module_t const**)&module); 92 int codec_rev = 2; 93 ALOGD("hw_get_module(ALSA_HARDWARE_MODULE_ID) returned err %d", err); 94 if (err == 0) { 95 hw_device_t* device; 96 err = module->methods->open(module, ALSA_HARDWARE_NAME, &device); 97 if (err == 0) { 98 mALSADevice = (alsa_device_t *)device; 99 mALSADevice->init(mALSADevice, mDeviceList); 100 mCSCallActive = 0; 101 mVolteCallActive = 0; 102 mIsFmActive = 0; 103 mDevSettingsFlag = 0; 104#ifdef QCOM_USBAUDIO_ENABLED 105 mAudioUsbALSA = new AudioUsbALSA(); 106 musbPlaybackState = 0; 107 musbRecordingState = 0; 108#endif 109#ifdef USES_FLUENCE_INCALL 110 mDevSettingsFlag |= TTY_OFF | DMIC_FLAG; 111#else 112 mDevSettingsFlag |= TTY_OFF; 113#endif 114 mBluetoothVGS = false; 115 mFusion3Platform = false; 116 117#ifdef QCOM_ACDB_ENABLED 118 mAcdbHandle = ::dlopen("/system/lib/libacdbloader.so", RTLD_NOW); 119 if (mAcdbHandle == NULL) { 120 ALOGE("AudioHardware: DLOPEN not successful for ACDBLOADER"); 121 } else { 122 ALOGD("AudioHardware: DLOPEN successful for ACDBLOADER"); 123 acdb_init = (int (*)())::dlsym(mAcdbHandle,"acdb_loader_init_ACDB"); 124 if (acdb_init == NULL) { 125 ALOGE("dlsym:Error:%s Loading acdb_loader_init_ACDB", dlerror()); 126 }else { 127 acdb_init(); 128 acdb_deallocate = (void (*)())::dlsym(mAcdbHandle,"acdb_loader_deallocate_ACDB"); 129 } 130 } 131#endif 132 133#ifdef QCOM_CSDCLIENT_ENABLED 134 mCsdHandle = ::dlopen("/system/lib/libcsd-client.so", RTLD_NOW); 135 if (mCsdHandle == NULL) { 136 ALOGE("AudioHardware: DLOPEN not successful for CSD CLIENT"); 137 } else { 138 ALOGD("AudioHardware: DLOPEN successful for CSD CLIENT"); 139 csd_start_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_start_playback"); 140 csd_stop_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_stop_playback"); 141 } 142 mALSADevice->setCsdHandle(mCsdHandle); 143#endif 144 if((fp = fopen("/proc/asound/cards","r")) == NULL) { 145 ALOGE("Cannot open /proc/asound/cards file to get sound card info"); 146 } else { 147 while((fgets(soundCardInfo, sizeof(soundCardInfo), fp) != NULL)) { 148 ALOGV("SoundCardInfo %s", soundCardInfo); 149 if (strstr(soundCardInfo, "msm8960-tabla1x-snd-card")) { 150 codec_rev = 1; 151 break; 152 } else if (strstr(soundCardInfo, "msm-snd-card")) { 153 codec_rev = 2; 154 break; 155 } else if (strstr(soundCardInfo, "msm8930-sitar-snd-card")) { 156 codec_rev = 3; 157 break; 158 } 159 } 160 fclose(fp); 161 } 162 163 if (codec_rev == 1) { 164 ALOGV("Detected tabla 1.x sound card"); 165 snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm"); 166 } else if (codec_rev == 3) { 167 ALOGV("Detected sitar 1.x sound card"); 168 snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Sitar"); 169 } else { 170 property_get("ro.board.platform", platform, ""); 171 property_get("ro.baseband", baseband, ""); 172 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) { 173 ALOGV("Detected Fusion tabla 2.x"); 174 mFusion3Platform = true; 175 snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x_Fusion3"); 176 } else { 177 ALOGV("Detected tabla 2.x sound card"); 178 snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x"); 179 } 180 } 181 182 if (mUcMgr < 0) { 183 ALOGE("Failed to open ucm instance: %d", errno); 184 } else { 185 ALOGI("ucm instance opened: %u", (unsigned)mUcMgr); 186 mUcMgr->acdb_handle = NULL; 187#ifdef QCOM_ACDB_ENABLED 188 if (mAcdbHandle) { 189 mUcMgr->acdb_handle = static_cast<void*> (mAcdbHandle); 190 } 191#endif 192 } 193 } else { 194 ALOGE("ALSA Module could not be opened!!!"); 195 } 196 } else { 197 ALOGE("ALSA Module not found!!!"); 198 } 199} 200 201AudioHardwareALSA::~AudioHardwareALSA() 202{ 203 if (mUcMgr != NULL) { 204#if LOCAL_LOGD 205 ALOGD("closing ucm instance: %u", (unsigned)mUcMgr); 206#endif 207 snd_use_case_mgr_close(mUcMgr); 208 } 209 if (mALSADevice) { 210 mALSADevice->common.close(&mALSADevice->common); 211 } 212 for(ALSAHandleList::iterator it = mDeviceList.begin(); 213 it != mDeviceList.end(); ++it) { 214 it->useCase[0] = 0; 215 mDeviceList.erase(it); 216 } 217#ifdef QCOM_ACDB_ENABLED 218 if (acdb_deallocate == NULL) { 219 ALOGE("dlsym: Error:%s Loading acdb_deallocate_ACDB", dlerror()); 220 } else { 221 acdb_deallocate(); 222 } 223 if (mAcdbHandle) { 224 ::dlclose(mAcdbHandle); 225 mAcdbHandle = NULL; 226 } 227#endif 228#ifdef QCOM_USBAUDIO_ENABLED 229 delete mAudioUsbALSA; 230#endif 231 232#ifdef QCOM_CSDCLEINT_ENABLED 233 if (mCsdHandle) { 234 ::dlclose(mCsdHandle); 235 mCsdHandle = NULL; 236 } 237#endif 238} 239 240status_t AudioHardwareALSA::initCheck() 241{ 242 if (!mALSADevice) 243 return NO_INIT; 244 245 return NO_ERROR; 246} 247 248status_t AudioHardwareALSA::setVoiceVolume(float v) 249{ 250 ALOGV("setVoiceVolume(%f)\n", v); 251 if (v < 0.0) { 252 ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 253 v = 0.0; 254 } else if (v > 1.0) { 255 ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 256 v = 1.0; 257 } 258 259 int newMode = mode(); 260 ALOGV("setVoiceVolume newMode %d",newMode); 261 int vol = lrint(v * 100.0); 262 263 // Voice volume levels from android are mapped to driver volume levels as follows. 264 // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0 265 // So adjust the volume to get the correct volume index in driver 266 vol = 100 - vol; 267 268 if (mALSADevice) { 269 if(newMode == AudioSystem::MODE_IN_COMMUNICATION) { 270 mALSADevice->setVoipVolume(vol); 271 } else if (newMode == AudioSystem::MODE_IN_CALL){ 272 if (mCSCallActive == CS_ACTIVE) 273 mALSADevice->setVoiceVolume(vol); 274 if (mVolteCallActive == IMS_ACTIVE) 275 mALSADevice->setVoLTEVolume(vol); 276 } 277 } 278 279 return NO_ERROR; 280} 281 282#ifdef QCOM_FM_ENABLED 283status_t AudioHardwareALSA::setFmVolume(float value) 284{ 285 status_t status = NO_ERROR; 286 287 int vol; 288 289 if (value < 0.0) { 290 ALOGW("setFmVolume(%f) under 0.0, assuming 0.0\n", value); 291 value = 0.0; 292 } else if (value > 1.0) { 293 ALOGW("setFmVolume(%f) over 1.0, assuming 1.0\n", value); 294 value = 1.0; 295 } 296 vol = lrint((value * 0x2000) + 0.5); 297 298#if LOCAL_LOGD 299 ALOGD("setFmVolume(%f)\n", value); 300 ALOGD("Setting FM volume to %d (available range is 0 to 0x2000)\n", vol); 301#endif 302 303 mALSADevice->setFmVolume(vol); 304 305 return status; 306} 307#endif 308 309status_t AudioHardwareALSA::setMasterVolume(float volume) 310{ 311 return NO_ERROR; 312} 313 314status_t AudioHardwareALSA::setMode(int mode) 315{ 316 status_t status = NO_ERROR; 317 318 if (mode != mMode) { 319 status = AudioHardwareBase::setMode(mode); 320 } 321 322 if (mode == AudioSystem::MODE_IN_CALL) { 323 mCallState = CS_ACTIVE; 324 }else if (mode == AudioSystem::MODE_NORMAL) { 325 mCallState = 0; 326 } 327 328 return status; 329} 330 331status_t AudioHardwareALSA::setParameters(const String8& keyValuePairs) 332{ 333 AudioParameter param = AudioParameter(keyValuePairs); 334 String8 key; 335 String8 value; 336 status_t status = NO_ERROR; 337 int device; 338 int btRate; 339 int state; 340#if LOCAL_LOGD 341 ALOGD("setParameters() %s", keyValuePairs.string()); 342#endif 343 344 key = String8(TTY_MODE_KEY); 345 if (param.get(key, value) == NO_ERROR) { 346 mDevSettingsFlag &= TTY_CLEAR; 347 if (value == "tty_full") { 348 mDevSettingsFlag |= TTY_FULL; 349 } else if (value == "tty_hco") { 350 mDevSettingsFlag |= TTY_HCO; 351 } else if (value == "tty_vco") { 352 mDevSettingsFlag |= TTY_VCO; 353 } else { 354 mDevSettingsFlag |= TTY_OFF; 355 } 356 ALOGI("Changed TTY Mode=%s", value.string()); 357 mALSADevice->setFlags(mDevSettingsFlag); 358 if(mMode != AudioSystem::MODE_IN_CALL){ 359 return NO_ERROR; 360 } 361 doRouting(0); 362 } 363 364 key = String8(FLUENCE_KEY); 365 if (param.get(key, value) == NO_ERROR) { 366 if (value == "quadmic") { 367 mDevSettingsFlag |= QMIC_FLAG; 368 mDevSettingsFlag &= (~DMIC_FLAG); 369 ALOGV("Fluence quadMic feature Enabled"); 370 } else if (value == "dualmic") { 371 mDevSettingsFlag |= DMIC_FLAG; 372 mDevSettingsFlag &= (~QMIC_FLAG); 373 ALOGV("Fluence dualmic feature Enabled"); 374 } else if (value == "none") { 375 mDevSettingsFlag &= (~DMIC_FLAG); 376 mDevSettingsFlag &= (~QMIC_FLAG); 377 ALOGV("Fluence feature Disabled"); 378 } 379 mALSADevice->setFlags(mDevSettingsFlag); 380 doRouting(0); 381 } 382 383#ifdef QCOM_CSDCLIENT_ENABLED 384 if (mFusion3Platform) { 385 key = String8(INCALLMUSIC_KEY); 386 if (param.get(key, value) == NO_ERROR) { 387 if (value == "true") { 388 ALOGV("Enabling Incall Music setting in the setparameter\n"); 389 if (csd_start_playback == NULL) { 390 ALOGE("dlsym: Error:%s Loading csd_client_start_playback", dlerror()); 391 } else { 392 csd_start_playback(); 393 } 394 } else { 395 ALOGV("Disabling Incall Music setting in the setparameter\n"); 396 if (csd_stop_playback == NULL) { 397 ALOGE("dlsym: Error:%s Loading csd_client_stop_playback", dlerror()); 398 } else { 399 csd_stop_playback(); 400 } 401 } 402 } 403 } 404#endif 405 406 key = String8(ANC_KEY); 407 if (param.get(key, value) == NO_ERROR) { 408 if (value == "true") { 409 ALOGV("Enabling ANC setting in the setparameter\n"); 410 mDevSettingsFlag |= ANC_FLAG; 411 } else { 412 ALOGV("Disabling ANC setting in the setparameter\n"); 413 mDevSettingsFlag &= (~ANC_FLAG); 414 } 415 mALSADevice->setFlags(mDevSettingsFlag); 416 doRouting(0); 417 } 418 419 key = String8(AudioParameter::keyRouting); 420 if (param.getInt(key, device) == NO_ERROR) { 421 // Ignore routing if device is 0. 422 if(device) { 423 doRouting(device); 424 } 425 param.remove(key); 426 } 427 428 key = String8(BT_SAMPLERATE_KEY); 429 if (param.getInt(key, btRate) == NO_ERROR) { 430 mALSADevice->setBtscoRate(btRate); 431 param.remove(key); 432 } 433 434 key = String8(BTHEADSET_VGS); 435 if (param.get(key, value) == NO_ERROR) { 436 if (value == "on") { 437 mBluetoothVGS = true; 438 } else { 439 mBluetoothVGS = false; 440 } 441 } 442 443 key = String8(WIDEVOICE_KEY); 444 if (param.get(key, value) == NO_ERROR) { 445 bool flag = false; 446 if (value == "true") { 447 flag = true; 448 } 449 if(mALSADevice) { 450 mALSADevice->enableWideVoice(flag); 451 } 452 param.remove(key); 453 } 454 455 key = String8(VOIPRATE_KEY); 456 if (param.get(key, value) == NO_ERROR) { 457 mVoipBitRate = atoi(value); 458 param.remove(key); 459 } 460 461 key = String8(FENS_KEY); 462 if (param.get(key, value) == NO_ERROR) { 463 bool flag = false; 464 if (value == "true") { 465 flag = true; 466 } 467 if(mALSADevice) { 468 mALSADevice->enableFENS(flag); 469 } 470 param.remove(key); 471 } 472 473#ifdef QCOM_FM_ENABLED 474 key = String8(AudioParameter::keyHandleFm); 475 if (param.getInt(key, device) == NO_ERROR) { 476 // Ignore if device is 0 477 if(device) { 478 handleFm(device); 479 } 480 param.remove(key); 481 } 482#endif 483 484 key = String8(ST_KEY); 485 if (param.get(key, value) == NO_ERROR) { 486 bool flag = false; 487 if (value == "true") { 488 flag = true; 489 } 490 if(mALSADevice) { 491 mALSADevice->enableSlowTalk(flag); 492 } 493 param.remove(key); 494 } 495 key = String8(MODE_CALL_KEY); 496 if (param.getInt(key,state) == NO_ERROR) { 497 if (mCallState != state) { 498 mCallState = state; 499 doRouting(0); 500 } 501 mCallState = state; 502 } 503 if (param.size()) { 504 status = BAD_VALUE; 505 } 506 return status; 507} 508 509String8 AudioHardwareALSA::getParameters(const String8& keys) 510{ 511 AudioParameter param = AudioParameter(keys); 512 String8 value; 513 514 String8 key = String8(DUALMIC_KEY); 515 if (param.get(key, value) == NO_ERROR) { 516 value = String8("false"); 517 param.add(key, value); 518 } 519 520 key = String8(FLUENCE_KEY); 521 if (param.get(key, value) == NO_ERROR) { 522 if ((mDevSettingsFlag & QMIC_FLAG) && 523 (mDevSettingsFlag & ~DMIC_FLAG)) 524 value = String8("quadmic"); 525 else if ((mDevSettingsFlag & DMIC_FLAG) && 526 (mDevSettingsFlag & ~QMIC_FLAG)) 527 value = String8("dualmic"); 528 else if ((mDevSettingsFlag & ~DMIC_FLAG) && 529 (mDevSettingsFlag & ~QMIC_FLAG)) 530 value = String8("none"); 531 param.add(key, value); 532 } 533 534#ifdef QCOM_FM_ENABLED 535 key = String8("Fm-radio"); 536 if ( param.get(key,value) == NO_ERROR ) { 537 if ( mIsFmActive ) { 538 param.addInt(String8("isFMON"), true ); 539 } 540 } 541#endif 542 543 key = String8(BTHEADSET_VGS); 544 if (param.get(key, value) == NO_ERROR) { 545 if(mBluetoothVGS) 546 param.addInt(String8("isVGS"), true); 547 } 548 549 ALOGV("AudioHardwareALSA::getParameters() %s", param.toString().string()); 550 return param.toString(); 551} 552 553#ifdef QCOM_USBAUDIO_ENABLED 554void AudioHardwareALSA::closeUSBPlayback() 555{ 556 ALOGV("closeUSBPlayback, musbPlaybackState: %d", musbPlaybackState); 557 musbPlaybackState = 0; 558 mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_KILLTHREAD); 559} 560 561void AudioHardwareALSA::closeUSBRecording() 562{ 563 ALOGV("closeUSBRecording"); 564 musbRecordingState = 0; 565 mAudioUsbALSA->exitRecordingThread(SIGNAL_EVENT_KILLTHREAD); 566} 567 568void AudioHardwareALSA::closeUsbPlaybackIfNothingActive(){ 569 ALOGV("closeUsbPlaybackIfNothingActive, musbPlaybackState: %d", musbPlaybackState); 570 if(!musbPlaybackState && mAudioUsbALSA != NULL) { 571 mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_TIMEOUT); 572 } 573} 574 575void AudioHardwareALSA::closeUsbRecordingIfNothingActive(){ 576 ALOGV("closeUsbRecordingIfNothingActive, musbRecordingState: %d", musbRecordingState); 577 if(!musbRecordingState && mAudioUsbALSA != NULL) { 578 ALOGD("Closing USB Recording Session as no stream is active"); 579 mAudioUsbALSA->setkillUsbRecordingThread(true); 580 } 581} 582 583void AudioHardwareALSA::startUsbPlaybackIfNotStarted(){ 584 ALOGV("Starting the USB playback %d kill %d", musbPlaybackState, 585 mAudioUsbALSA->getkillUsbPlaybackThread()); 586 if((!musbPlaybackState) || (mAudioUsbALSA->getkillUsbPlaybackThread() == true)) { 587 mAudioUsbALSA->startPlayback(); 588 } 589} 590 591void AudioHardwareALSA::startUsbRecordingIfNotStarted(){ 592 ALOGV("Starting the recording musbRecordingState: %d killUsbRecordingThread %d", 593 musbRecordingState, mAudioUsbALSA->getkillUsbRecordingThread()); 594 if((!musbRecordingState) || (mAudioUsbALSA->getkillUsbRecordingThread() == true)) { 595 mAudioUsbALSA->startRecording(); 596 } 597} 598#endif 599 600void AudioHardwareALSA::doRouting(int device) 601{ 602 Mutex::Autolock autoLock(mLock); 603 int newMode = mode(); 604 bool isRouted = false; 605 606 if ((device == AudioSystem::DEVICE_IN_VOICE_CALL) 607#ifdef QCOM_FM_ENABLED 608 || (device == AudioSystem::DEVICE_IN_FM_RX) 609 || (device == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) 610 || (device == AudioSystem::DEVICE_IN_FM_RX_A2DP) 611#endif 612 || (device == AudioSystem::DEVICE_IN_COMMUNICATION) 613 ) { 614 ALOGV("Ignoring routing for FM/INCALL/VOIP recording"); 615 return; 616 } 617 if (device == 0) 618 device = mCurDevice; 619 ALOGV("doRouting: device %d newMode %d mCSCallActive %d mVolteCallActive %d" 620 "mIsFmActive %d", device, newMode, mCSCallActive, mVolteCallActive, 621 mIsFmActive); 622 623 isRouted = routeVoLTECall(device, newMode); 624 isRouted |= routeVoiceCall(device, newMode); 625 626 if(!isRouted) { 627#ifdef QCOM_USBAUDIO_ENABLED 628 if(!(device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) && 629 !(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET) && 630 !(device & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) && 631 (musbPlaybackState)){ 632 //USB unplugged 633 device &= ~ AudioSystem::DEVICE_OUT_PROXY; 634 device &= ~ AudioSystem::DEVICE_IN_PROXY; 635 ALSAHandleList::iterator it = mDeviceList.end(); 636 it--; 637 mALSADevice->route(&(*it), (uint32_t)device, newMode); 638 ALOGD("USB UNPLUGGED, setting musbPlaybackState to 0"); 639 musbPlaybackState = 0; 640 musbRecordingState = 0; 641 closeUSBRecording(); 642 closeUSBPlayback(); 643 } else if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 644 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 645 ALOGD("Routing everything to prox now"); 646 ALSAHandleList::iterator it = mDeviceList.end(); 647 it--; 648 mALSADevice->route(&(*it), AudioSystem::DEVICE_OUT_PROXY, 649 newMode); 650 for(it = mDeviceList.begin(); it != mDeviceList.end(); ++it) { 651 if((!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || 652 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA))) { 653 ALOGV("doRouting: LPA device switch to proxy"); 654 startUsbPlaybackIfNotStarted(); 655 musbPlaybackState |= USBPLAYBACKBIT_LPA; 656 break; 657 } else if((!strcmp(it->useCase, SND_USE_CASE_VERB_VOICECALL)) || 658 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOICE))) { 659 ALOGV("doRouting: VOICE device switch to proxy"); 660 startUsbRecordingIfNotStarted(); 661 startUsbPlaybackIfNotStarted(); 662 musbPlaybackState |= USBPLAYBACKBIT_VOICECALL; 663 musbRecordingState |= USBPLAYBACKBIT_VOICECALL; 664 break; 665 }else if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) || 666 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) { 667 ALOGV("doRouting: FM device switch to proxy"); 668 startUsbPlaybackIfNotStarted(); 669 musbPlaybackState |= USBPLAYBACKBIT_FM; 670 break; 671 } 672 } 673 } else 674#endif 675 { 676 ALSAHandleList::iterator it = mDeviceList.end(); 677 it--; 678 mALSADevice->route(&(*it), (uint32_t)device, newMode); 679 } 680 } 681 mCurDevice = device; 682} 683 684uint32_t AudioHardwareALSA::getVoipMode(int format) 685{ 686 switch(format) { 687 case AudioSystem::PCM_16_BIT: 688 return MODE_PCM; 689 break; 690 case AudioSystem::AMR_NB: 691 return MODE_AMR; 692 break; 693 case AudioSystem::AMR_WB: 694 return MODE_AMR_WB; 695 break; 696 697#ifdef QCOM_QCHAT_ENABLED 698 case AudioSystem::EVRC: 699 return MODE_IS127; 700 break; 701 702 case AudioSystem::EVRCB: 703 return MODE_4GV_NB; 704 break; 705 case AudioSystem::EVRCWB: 706 return MODE_4GV_WB; 707 break; 708#endif 709 710 default: 711 return MODE_PCM; 712 } 713} 714 715AudioStreamOut * 716AudioHardwareALSA::openOutputStream(uint32_t devices, 717 int *format, 718 uint32_t *channels, 719 uint32_t *sampleRate, 720 status_t *status) 721{ 722 Mutex::Autolock autoLock(mLock); 723 ALOGV("openOutputStream: devices 0x%x channels %d sampleRate %d", 724 devices, *channels, *sampleRate); 725 726 audio_output_flags_t flag = static_cast<audio_output_flags_t> (*status); 727 728 status_t err = BAD_VALUE; 729 *status = NO_ERROR; 730 AudioStreamOutALSA *out = 0; 731 ALSAHandleList::iterator it; 732 733 if (devices & (devices - 1)) { 734 if (status) *status = err; 735 ALOGE("openOutputStream called with bad devices"); 736 return out; 737 } 738 739 740# if 0 741 if((devices == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) && 742 ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) { 743 bool voipstream_active = false; 744 for(it = mDeviceList.begin(); 745 it != mDeviceList.end(); ++it) { 746 if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) || 747 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) { 748 ALOGD("openOutput: it->rxHandle %d it->handle %d",it->rxHandle,it->handle); 749 voipstream_active = true; 750 break; 751 } 752 } 753 if(voipstream_active == false) { 754 mVoipStreamCount = 0; 755 mVoipMicMute = false; 756 alsa_handle_t alsa_handle; 757 unsigned long bufferSize; 758 if(*sampleRate == VOIP_SAMPLING_RATE_8K) { 759 bufferSize = VOIP_BUFFER_SIZE_8K; 760 } 761 else if(*sampleRate == VOIP_SAMPLING_RATE_16K) { 762 bufferSize = VOIP_BUFFER_SIZE_16K; 763 } 764 else { 765 ALOGE("unsupported samplerate %d for voip",*sampleRate); 766 if (status) *status = err; 767 return out; 768 } 769 alsa_handle.module = mALSADevice; 770 alsa_handle.bufferSize = bufferSize; 771 alsa_handle.devices = devices; 772 alsa_handle.handle = 0; 773 if(*format == AudioSystem::PCM_16_BIT) 774 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 775 else 776 alsa_handle.format = *format; 777 alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE; 778 alsa_handle.sampleRate = *sampleRate; 779 alsa_handle.latency = VOIP_PLAYBACK_LATENCY; 780 alsa_handle.rxHandle = 0; 781 alsa_handle.ucMgr = mUcMgr; 782 mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate); 783 char *use_case; 784 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 785 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 786 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase)); 787 } else { 788 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase)); 789 } 790 free(use_case); 791 mDeviceList.push_back(alsa_handle); 792 it = mDeviceList.end(); 793 it--; 794 ALOGV("openoutput: mALSADevice->route useCase %s mCurDevice %d mVoipStreamCount %d mode %d", it->useCase,mCurDevice,mVoipStreamCount, mode()); 795 if((mCurDevice & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 796 (mCurDevice & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)|| 797 (mCurDevice & AudioSystem::DEVICE_OUT_PROXY)){ 798 ALOGD("Routing to proxy for normal voip call in openOutputStream"); 799 mCurDevice |= AudioSystem::DEVICE_OUT_PROXY; 800 alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY; 801 mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 802 ALOGD("enabling VOIP in openoutputstream, musbPlaybackState: %d", musbPlaybackState); 803 startUsbPlaybackIfNotStarted(); 804 musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL; 805 ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState); 806 startUsbRecordingIfNotStarted(); 807 musbRecordingState |= USBRECBIT_VOIPCALL; 808 } else{ 809 mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 810 } 811 if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) { 812 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL); 813 } else { 814 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP); 815 } 816 err = mALSADevice->startVoipCall(&(*it)); 817 if (err) { 818 ALOGE("Device open failed"); 819 return NULL; 820 } 821 } 822 out = new AudioStreamOutALSA(this, &(*it)); 823 err = out->set(format, channels, sampleRate, devices); 824 if(err == NO_ERROR) { 825 mVoipStreamCount++; //increment VoipstreamCount only if success 826 ALOGD("openoutput mVoipStreamCount %d",mVoipStreamCount); 827 } 828 if (status) *status = err; 829 return out; 830 } else 831#endif 832 { 833 834 alsa_handle_t alsa_handle; 835 unsigned long bufferSize = DEFAULT_BUFFER_SIZE; 836 837 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 838 bufferSize &= ~b; 839 840 alsa_handle.module = mALSADevice; 841 alsa_handle.bufferSize = bufferSize; 842 alsa_handle.devices = devices; 843 alsa_handle.handle = 0; 844 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 845 alsa_handle.channels = DEFAULT_CHANNEL_MODE; 846 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 847 alsa_handle.latency = PLAYBACK_LATENCY; 848 alsa_handle.rxHandle = 0; 849 alsa_handle.ucMgr = mUcMgr; 850 alsa_handle.isDeepbufferOutput = false; 851 852 char *use_case; 853 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 854 855 if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 856 ALOGD("openOutputStream: DeepBuffer Output"); 857 alsa_handle.isDeepbufferOutput = true; 858 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 859 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI, sizeof(alsa_handle.useCase)); 860 } else { 861 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC, sizeof(alsa_handle.useCase)); 862 } 863 } else { 864 ALOGD("openOutputStream: Lowlatency Output"); 865 alsa_handle.bufferSize = PLAYBACK_LOW_LATENCY_BUFFER_SIZE; 866 alsa_handle.latency = PLAYBACK_LOW_LATENCY; 867 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 868 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 869 } else { 870 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 871 } 872 } 873 free(use_case); 874 mDeviceList.push_back(alsa_handle); 875 ALSAHandleList::iterator it = mDeviceList.end(); 876 it--; 877 ALOGV("useCase %s", it->useCase); 878#ifdef QCOM_USBAUDIO_ENABLED 879 if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 880 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 881 ALOGD("Routing to proxy for normal playback in openOutputStream"); 882 devices |= AudioSystem::DEVICE_OUT_PROXY; 883 } 884#endif 885 mALSADevice->route(&(*it), devices, mode()); 886 if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 887 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI)) { 888 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI); 889 } else { 890 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC); 891 } 892 } else { 893 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) { 894 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC); 895 } else { 896 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC); 897 } 898 } 899 err = mALSADevice->open(&(*it)); 900 if (err) { 901 ALOGE("Device open failed"); 902 } else { 903 out = new AudioStreamOutALSA(this, &(*it)); 904 err = out->set(format, channels, sampleRate, devices); 905 } 906 907 if (status) *status = err; 908 return out; 909 } 910} 911 912void 913AudioHardwareALSA::closeOutputStream(AudioStreamOut* out) 914{ 915 delete out; 916} 917 918#ifdef QCOM_TUNNEL_LPA_ENABLED 919AudioStreamOut * 920AudioHardwareALSA::openOutputSession(uint32_t devices, 921 int *format, 922 status_t *status, 923 int sessionId, 924 uint32_t samplingRate, 925 uint32_t channels) 926{ 927 Mutex::Autolock autoLock(mLock); 928 ALOGD("openOutputSession = %d" ,sessionId); 929 AudioStreamOutALSA *out = 0; 930 status_t err = BAD_VALUE; 931 932 alsa_handle_t alsa_handle; 933 unsigned long bufferSize = DEFAULT_BUFFER_SIZE; 934 935 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 936 bufferSize &= ~b; 937 938 alsa_handle.module = mALSADevice; 939 alsa_handle.bufferSize = bufferSize; 940 alsa_handle.devices = devices; 941 alsa_handle.handle = 0; 942 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 943 alsa_handle.channels = DEFAULT_CHANNEL_MODE; 944 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 945 alsa_handle.latency = VOICE_LATENCY; 946 alsa_handle.rxHandle = 0; 947 alsa_handle.ucMgr = mUcMgr; 948 949 char *use_case; 950 if(sessionId == TUNNEL_SESSION_ID) { 951 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 952 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 953 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_TUNNEL, sizeof(alsa_handle.useCase)); 954 } else { 955 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_TUNNEL, sizeof(alsa_handle.useCase)); 956 } 957 } else { 958 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 959 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 960 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER, sizeof(alsa_handle.useCase)); 961 } else { 962 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LPA, sizeof(alsa_handle.useCase)); 963 } 964 } 965 free(use_case); 966 mDeviceList.push_back(alsa_handle); 967 ALSAHandleList::iterator it = mDeviceList.end(); 968 it--; 969 ALOGD("useCase %s", it->useCase); 970#ifdef QCOM_USBAUDIO_ENABLED 971 if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 972 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 973 ALOGD("Routing to proxy for LPA in openOutputSession"); 974 devices |= AudioSystem::DEVICE_OUT_PROXY; 975 mALSADevice->route(&(*it), devices, mode()); 976 devices = AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 977 ALOGD("Starting USBPlayback for LPA"); 978 startUsbPlaybackIfNotStarted(); 979 musbPlaybackState |= USBPLAYBACKBIT_LPA; 980 } else 981#endif 982 { 983 mALSADevice->route(&(*it), devices, mode()); 984 } 985 if(sessionId == TUNNEL_SESSION_ID) { 986 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) { 987 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_TUNNEL); 988 } else { 989 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_TUNNEL); 990 } 991 } 992 else { 993 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) { 994 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOW_POWER); 995 } else { 996 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LPA); 997 } 998 } 999 err = mALSADevice->open(&(*it)); 1000 out = new AudioStreamOutALSA(this, &(*it)); 1001 1002 if (status) *status = err; 1003 return out; 1004} 1005 1006void 1007AudioHardwareALSA::closeOutputSession(AudioStreamOut* out) 1008{ 1009 delete out; 1010} 1011#endif 1012 1013AudioStreamIn * 1014AudioHardwareALSA::openInputStream(uint32_t devices, 1015 int *format, 1016 uint32_t *channels, 1017 uint32_t *sampleRate, 1018 status_t *status, 1019 AudioSystem::audio_in_acoustics acoustics) 1020{ 1021 Mutex::Autolock autoLock(mLock); 1022 char *use_case; 1023 int newMode = mode(); 1024 uint32_t route_devices; 1025 1026 status_t err = BAD_VALUE; 1027 AudioStreamInALSA *in = 0; 1028 ALSAHandleList::iterator it; 1029 1030 ALOGD("openInputStream: devices 0x%x channels %d sampleRate %d", devices, *channels, *sampleRate); 1031 if (devices & (devices - 1)) { 1032 if (status) *status = err; 1033 return in; 1034 } 1035 1036 if((devices == AudioSystem::DEVICE_IN_COMMUNICATION) && 1037 ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) { 1038 bool voipstream_active = false; 1039 for(it = mDeviceList.begin(); 1040 it != mDeviceList.end(); ++it) { 1041 if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) || 1042 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) { 1043 ALOGD("openInput: it->rxHandle %p it->handle %p",it->rxHandle,it->handle); 1044 voipstream_active = true; 1045 break; 1046 } 1047 } 1048 if(voipstream_active == false) { 1049 mVoipStreamCount = 0; 1050 mVoipMicMute = false; 1051 alsa_handle_t alsa_handle; 1052 unsigned long bufferSize; 1053 if(*sampleRate == VOIP_SAMPLING_RATE_8K) { 1054 bufferSize = VOIP_BUFFER_SIZE_8K; 1055 } 1056 else if(*sampleRate == VOIP_SAMPLING_RATE_16K) { 1057 bufferSize = VOIP_BUFFER_SIZE_16K; 1058 } 1059 else { 1060 ALOGE("unsupported samplerate %d for voip",*sampleRate); 1061 if (status) *status = err; 1062 return in; 1063 } 1064 alsa_handle.module = mALSADevice; 1065 alsa_handle.bufferSize = bufferSize; 1066 alsa_handle.devices = devices; 1067 alsa_handle.handle = 0; 1068 if(*format == AudioSystem::PCM_16_BIT) 1069 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1070 else 1071 alsa_handle.format = *format; 1072 alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE; 1073 alsa_handle.sampleRate = *sampleRate; 1074 alsa_handle.latency = VOIP_RECORD_LATENCY; 1075 alsa_handle.rxHandle = 0; 1076 alsa_handle.ucMgr = mUcMgr; 1077 mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate); 1078 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1079 if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1080 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase)); 1081 } else { 1082 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase)); 1083 } 1084 free(use_case); 1085 mDeviceList.push_back(alsa_handle); 1086 it = mDeviceList.end(); 1087 it--; 1088 ALOGD("mCurrDevice: %d", mCurDevice); 1089#ifdef QCOM_USBAUDIO_ENABLED 1090 if((mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1091 (mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1092 ALOGD("Routing everything from proxy for voipcall"); 1093 mALSADevice->route(&(*it), AudioSystem::DEVICE_IN_PROXY, AudioSystem::MODE_IN_COMMUNICATION); 1094 ALOGD("enabling VOIP in openInputstream, musbPlaybackState: %d", musbPlaybackState); 1095 startUsbPlaybackIfNotStarted(); 1096 musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL; 1097 ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState); 1098 startUsbRecordingIfNotStarted(); 1099 musbRecordingState |= USBRECBIT_VOIPCALL; 1100 } else 1101#endif 1102 { 1103 mALSADevice->route(&(*it),mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 1104 } 1105 if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) { 1106 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL); 1107 } else { 1108 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP); 1109 } 1110 if(sampleRate) { 1111 it->sampleRate = *sampleRate; 1112 } 1113 if(channels) 1114 it->channels = AudioSystem::popCount(*channels); 1115 err = mALSADevice->startVoipCall(&(*it)); 1116 if (err) { 1117 ALOGE("Error opening pcm input device"); 1118 return NULL; 1119 } 1120 } 1121 in = new AudioStreamInALSA(this, &(*it), acoustics); 1122 err = in->set(format, channels, sampleRate, devices); 1123 if(err == NO_ERROR) { 1124 mVoipStreamCount++; //increment VoipstreamCount only if success 1125 ALOGD("OpenInput mVoipStreamCount %d",mVoipStreamCount); 1126 } 1127 ALOGD("openInput: After Get alsahandle"); 1128 if (status) *status = err; 1129 return in; 1130 } else 1131 { 1132 for(ALSAHandleList::iterator itDev = mDeviceList.begin(); 1133 itDev != mDeviceList.end(); ++itDev) 1134 { 1135 if((0 == strncmp(itDev->useCase, SND_USE_CASE_VERB_HIFI_REC, MAX_UC_LEN)) 1136 ||(0 == strncmp(itDev->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, MAX_UC_LEN)) 1137 ||(0 == strncmp(itDev->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, MAX_UC_LEN)) 1138 ||(0 == strncmp(itDev->useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, MAX_UC_LEN)) 1139 ||(0 == strncmp(itDev->useCase, SND_USE_CASE_MOD_CAPTURE_FM, MAX_UC_LEN)) 1140#ifdef QCOM_FM_ENABLED 1141 ||(0 == strncmp(itDev->useCase, SND_USE_CASE_VERB_FM_REC, MAX_UC_LEN)) 1142#endif 1143 ) 1144 { 1145#ifdef QCOM_FM_ENABLED 1146 if(!(devices == AudioSystem::DEVICE_IN_FM_RX_A2DP)){ 1147 ALOGD("Input stream already exists, new stream not permitted: useCase:%s, devices:0x%x, module:%p", 1148 itDev->useCase, itDev->devices, itDev->module); 1149 return in; 1150 } 1151#endif 1152 } 1153#ifdef QCOM_FM_ENABLED 1154 else if ((0 == strncmp(itDev->useCase, SND_USE_CASE_VERB_FM_A2DP_REC, MAX_UC_LEN)) 1155 ||(0 == strncmp(itDev->useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, MAX_UC_LEN))) 1156 { 1157 if((devices == AudioSystem::DEVICE_IN_FM_RX_A2DP)){ 1158 ALOGD("Input stream already exists, new stream not permitted: useCase:%s, devices:0x%x, module:%p", 1159 itDev->useCase, itDev->devices, itDev->module); 1160 return in; 1161 } 1162 } 1163#endif 1164 } 1165 1166 alsa_handle_t alsa_handle; 1167 unsigned long bufferSize = DEFAULT_IN_BUFFER_SIZE; 1168 1169 alsa_handle.module = mALSADevice; 1170 alsa_handle.bufferSize = bufferSize; 1171 alsa_handle.devices = devices; 1172 alsa_handle.handle = 0; 1173 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1174 alsa_handle.channels = VOICE_CHANNEL_MODE; 1175 alsa_handle.sampleRate = android::AudioRecord::DEFAULT_SAMPLE_RATE; 1176 alsa_handle.latency = RECORD_LATENCY; 1177 alsa_handle.rxHandle = 0; 1178 alsa_handle.ucMgr = mUcMgr; 1179 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1180 if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1181 if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) && 1182 (newMode == AudioSystem::MODE_IN_CALL)) { 1183 ALOGD("openInputStream: into incall recording, channels %d", *channels); 1184 mIncallMode = *channels; 1185 if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) && 1186 (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) { 1187 if (mFusion3Platform) { 1188 mALSADevice->setVocRecMode(INCALL_REC_STEREO); 1189 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE, 1190 sizeof(alsa_handle.useCase)); 1191 } else { 1192 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL, 1193 sizeof(alsa_handle.useCase)); 1194 } 1195 } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { 1196 if (mFusion3Platform) { 1197 mALSADevice->setVocRecMode(INCALL_REC_MONO); 1198 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE, 1199 sizeof(alsa_handle.useCase)); 1200 } else { 1201 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL, 1202 sizeof(alsa_handle.useCase)); 1203 } 1204 } 1205#ifdef QCOM_FM_ENABLED 1206 } else if((devices == AudioSystem::DEVICE_IN_FM_RX)) { 1207 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_FM, sizeof(alsa_handle.useCase)); 1208 } else if(devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) { 1209 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(alsa_handle.useCase)); 1210#endif 1211 } else { 1212 char value[128]; 1213 property_get("persist.audio.lowlatency.rec",value,"0"); 1214 if (!strcmp("true", value)) { 1215 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 1216 } else { 1217 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(alsa_handle.useCase)); 1218 } 1219 } 1220 } else { 1221 if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) && 1222 (newMode == AudioSystem::MODE_IN_CALL)) { 1223 ALOGD("openInputStream: incall recording, channels %d", *channels); 1224 mIncallMode = *channels; 1225 if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) && 1226 (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) { 1227 if (mFusion3Platform) { 1228 mALSADevice->setVocRecMode(INCALL_REC_STEREO); 1229 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC, 1230 sizeof(alsa_handle.useCase)); 1231 } else { 1232 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_UL_DL_REC, 1233 sizeof(alsa_handle.useCase)); 1234 } 1235 } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { 1236 if (mFusion3Platform) { 1237 mALSADevice->setVocRecMode(INCALL_REC_MONO); 1238 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC, 1239 sizeof(alsa_handle.useCase)); 1240 } else { 1241 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DL_REC, 1242 sizeof(alsa_handle.useCase)); 1243 } 1244 } 1245#ifdef QCOM_FM_ENABLED 1246 } else if(devices == AudioSystem::DEVICE_IN_FM_RX) { 1247 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_REC, sizeof(alsa_handle.useCase)); 1248 } else if (devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) { 1249 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_A2DP_REC, sizeof(alsa_handle.useCase)); 1250#endif 1251 } else { 1252 char value[128]; 1253 property_get("persist.audio.lowlatency.rec",value,"0"); 1254 if (!strcmp("true", value)) { 1255 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(alsa_handle.useCase)); 1256 } else { 1257 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(alsa_handle.useCase)); 1258 } 1259 } 1260 } 1261 free(use_case); 1262 mDeviceList.push_back(alsa_handle); 1263 ALSAHandleList::iterator it = mDeviceList.end(); 1264 it--; 1265 //update channel info before do routing 1266 if(channels) { 1267 it->channels = AudioSystem::popCount((*channels) & 1268 (AudioSystem::CHANNEL_IN_STEREO 1269 | AudioSystem::CHANNEL_IN_MONO 1270#ifdef QCOM_SSR_ENABLED 1271 | AudioSystem::CHANNEL_IN_5POINT1 1272#endif 1273 )); 1274 ALOGV("updated channel info: channels=%d", it->channels); 1275 } 1276 if (devices == AudioSystem::DEVICE_IN_VOICE_CALL){ 1277 /* Add current devices info to devices to do route */ 1278#ifdef QCOM_USBAUDIO_ENABLED 1279 if(mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET || 1280 mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET){ 1281 ALOGD("Routing everything from proxy for VOIP call"); 1282 route_devices = devices | AudioSystem::DEVICE_IN_PROXY; 1283 } else 1284#endif 1285 { 1286 route_devices = devices | mCurDevice; 1287 } 1288 mALSADevice->route(&(*it), route_devices, mode()); 1289 } else { 1290#ifdef QCOM_USBAUDIO_ENABLED 1291 if(devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET || 1292 devices & AudioSystem::DEVICE_IN_PROXY) { 1293 devices |= AudioSystem::DEVICE_IN_PROXY; 1294 ALOGD("routing everything from proxy"); 1295 mALSADevice->route(&(*it), devices, mode()); 1296 } else 1297#endif 1298 { 1299 mALSADevice->route(&(*it), devices, mode()); 1300 } 1301 } 1302 1303 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC) || 1304 !strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) || 1305#ifdef QCOM_FM_ENABLED 1306 !strcmp(it->useCase, SND_USE_CASE_VERB_FM_REC) || 1307 !strcmp(it->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) || 1308#endif 1309 !strcmp(it->useCase, SND_USE_CASE_VERB_DL_REC) || 1310 !strcmp(it->useCase, SND_USE_CASE_VERB_UL_DL_REC) || 1311 !strcmp(it->useCase, SND_USE_CASE_VERB_INCALL_REC)) { 1312 snd_use_case_set(mUcMgr, "_verb", it->useCase); 1313 } else { 1314 snd_use_case_set(mUcMgr, "_enamod", it->useCase); 1315 } 1316 if(sampleRate) { 1317 it->sampleRate = *sampleRate; 1318 } 1319#ifdef QCOM_SSR_ENABLED 1320 if (6 == it->channels) { 1321 if (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC)) 1322 || !strncmp(it->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) { 1323 ALOGV("OpenInoutStream: Use larger buffer size for 5.1(%s) recording ", it->useCase); 1324 it->bufferSize = getInputBufferSize(it->sampleRate,*format,it->channels); 1325 } 1326 } 1327#endif 1328 err = mALSADevice->open(&(*it)); 1329 if (err) { 1330 ALOGE("Error opening pcm input device"); 1331 } else { 1332 in = new AudioStreamInALSA(this, &(*it), acoustics); 1333 err = in->set(format, channels, sampleRate, devices); 1334 } 1335 if (status) *status = err; 1336 return in; 1337 } 1338} 1339 1340void 1341AudioHardwareALSA::closeInputStream(AudioStreamIn* in) 1342{ 1343 delete in; 1344} 1345 1346status_t AudioHardwareALSA::setMicMute(bool state) 1347{ 1348 int newMode = mode(); 1349 ALOGD("setMicMute newMode %d",newMode); 1350 if(newMode == AudioSystem::MODE_IN_COMMUNICATION) { 1351 if (mVoipMicMute != state) { 1352 mVoipMicMute = state; 1353 ALOGD("setMicMute: mVoipMicMute %d", mVoipMicMute); 1354 if(mALSADevice) { 1355 mALSADevice->setVoipMicMute(state); 1356 } 1357 } 1358 } else { 1359 if (mMicMute != state) { 1360 mMicMute = state; 1361 ALOGD("setMicMute: mMicMute %d", mMicMute); 1362 if(mALSADevice) { 1363 if(mCSCallActive == CS_ACTIVE) 1364 mALSADevice->setMicMute(state); 1365 if(mVolteCallActive == IMS_ACTIVE) 1366 mALSADevice->setVoLTEMicMute(state); 1367 } 1368 } 1369 } 1370 return NO_ERROR; 1371} 1372 1373status_t AudioHardwareALSA::getMicMute(bool *state) 1374{ 1375 int newMode = mode(); 1376 if(newMode == AudioSystem::MODE_IN_COMMUNICATION) { 1377 *state = mVoipMicMute; 1378 } else { 1379 *state = mMicMute; 1380 } 1381 return NO_ERROR; 1382} 1383 1384status_t AudioHardwareALSA::dump(int fd, const Vector<String16>& args) 1385{ 1386 return NO_ERROR; 1387} 1388 1389size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 1390{ 1391 size_t bufferSize; 1392 if (format != AudioSystem::PCM_16_BIT 1393 && format != AudioSystem::AMR_NB 1394 && format != AudioSystem::AMR_WB 1395#ifdef QCOM_QCHAT_ENABLED 1396 && format != AudioSystem::EVRC 1397 && format != AudioSystem::EVRCB 1398 && format != AudioSystem::EVRCWB 1399#endif 1400 ) { 1401 ALOGW("getInputBufferSize bad format: %d", format); 1402 return 0; 1403 } 1404 if(sampleRate == 16000) { 1405 bufferSize = DEFAULT_IN_BUFFER_SIZE * 2 * channelCount; 1406 } else if(sampleRate < 44100) { 1407 bufferSize = DEFAULT_IN_BUFFER_SIZE * channelCount; 1408 } else { 1409 bufferSize = DEFAULT_IN_BUFFER_SIZE * 12; 1410 } 1411 return bufferSize; 1412} 1413 1414#ifdef QCOM_FM_ENABLED 1415void AudioHardwareALSA::handleFm(int device) 1416{ 1417int newMode = mode(); 1418 if(device & AudioSystem::DEVICE_OUT_FM && mIsFmActive == 0) { 1419 // Start FM Radio on current active device 1420 unsigned long bufferSize = FM_BUFFER_SIZE; 1421 alsa_handle_t alsa_handle; 1422 char *use_case; 1423 ALOGV("Start FM"); 1424 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1425 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1426 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DIGITAL_RADIO, sizeof(alsa_handle.useCase)); 1427 } else { 1428 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_FM, sizeof(alsa_handle.useCase)); 1429 } 1430 free(use_case); 1431 1432 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 1433 bufferSize &= ~b; 1434 alsa_handle.module = mALSADevice; 1435 alsa_handle.bufferSize = bufferSize; 1436 alsa_handle.devices = device; 1437 alsa_handle.handle = 0; 1438 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1439 alsa_handle.channels = DEFAULT_CHANNEL_MODE; 1440 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 1441 alsa_handle.latency = VOICE_LATENCY; 1442 alsa_handle.rxHandle = 0; 1443 alsa_handle.ucMgr = mUcMgr; 1444 mIsFmActive = 1; 1445 mDeviceList.push_back(alsa_handle); 1446 ALSAHandleList::iterator it = mDeviceList.end(); 1447 it--; 1448 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1449 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1450 device |= AudioSystem::DEVICE_OUT_PROXY; 1451 alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY; 1452 ALOGD("Routing to proxy for FM case"); 1453 } 1454 mALSADevice->route(&(*it), (uint32_t)device, newMode); 1455 if(!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) { 1456 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_DIGITAL_RADIO); 1457 } else { 1458 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_FM); 1459 } 1460 mALSADevice->startFm(&(*it)); 1461 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1462 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1463 ALOGD("Starting FM, musbPlaybackState %d", musbPlaybackState); 1464 startUsbPlaybackIfNotStarted(); 1465 musbPlaybackState |= USBPLAYBACKBIT_FM; 1466 } 1467 } else if (!(device & AudioSystem::DEVICE_OUT_FM) && mIsFmActive == 1) { 1468 //i Stop FM Radio 1469 ALOGV("Stop FM"); 1470 for(ALSAHandleList::iterator it = mDeviceList.begin(); 1471 it != mDeviceList.end(); ++it) { 1472 if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) || 1473 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) { 1474 mALSADevice->close(&(*it)); 1475 //mALSADevice->route(&(*it), (uint32_t)device, newMode); 1476 mDeviceList.erase(it); 1477 break; 1478 } 1479 } 1480 mIsFmActive = 0; 1481 musbPlaybackState &= ~USBPLAYBACKBIT_FM; 1482 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1483 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1484 closeUsbPlaybackIfNothingActive(); 1485 } 1486 } 1487} 1488#endif 1489 1490void AudioHardwareALSA::disableVoiceCall(char* verb, char* modifier, int mode, int device) 1491{ 1492 for(ALSAHandleList::iterator it = mDeviceList.begin(); 1493 it != mDeviceList.end(); ++it) { 1494 if((!strcmp(it->useCase, verb)) || 1495 (!strcmp(it->useCase, modifier))) { 1496 ALOGV("Disabling voice call"); 1497 mALSADevice->close(&(*it)); 1498 mALSADevice->route(&(*it), (uint32_t)device, mode); 1499 mDeviceList.erase(it); 1500 break; 1501 } 1502 } 1503#ifdef QCOM_USBAUDIO_ENABLED 1504 if(musbPlaybackState & USBPLAYBACKBIT_VOICECALL) { 1505 ALOGD("Voice call ended on USB"); 1506 musbPlaybackState &= ~USBPLAYBACKBIT_VOICECALL; 1507 musbRecordingState &= ~USBRECBIT_VOICECALL; 1508 closeUsbRecordingIfNothingActive(); 1509 closeUsbPlaybackIfNothingActive(); 1510 } 1511#endif 1512} 1513void AudioHardwareALSA::enableVoiceCall(char* verb, char* modifier, int mode, int device) 1514{ 1515// Start voice call 1516unsigned long bufferSize = DEFAULT_VOICE_BUFFER_SIZE; 1517alsa_handle_t alsa_handle; 1518char *use_case; 1519 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1520 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1521 strlcpy(alsa_handle.useCase, verb, sizeof(alsa_handle.useCase)); 1522 } else { 1523 strlcpy(alsa_handle.useCase, modifier, sizeof(alsa_handle.useCase)); 1524 } 1525 free(use_case); 1526 1527 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 1528 bufferSize &= ~b; 1529 alsa_handle.module = mALSADevice; 1530 alsa_handle.bufferSize = bufferSize; 1531 alsa_handle.devices = device; 1532 alsa_handle.handle = 0; 1533 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1534 alsa_handle.channels = VOICE_CHANNEL_MODE; 1535 alsa_handle.sampleRate = VOICE_SAMPLING_RATE; 1536 alsa_handle.latency = VOICE_LATENCY; 1537 alsa_handle.rxHandle = 0; 1538 alsa_handle.ucMgr = mUcMgr; 1539 mDeviceList.push_back(alsa_handle); 1540 ALSAHandleList::iterator it = mDeviceList.end(); 1541 it--; 1542#ifdef QCOM_USBAUDIO_ENABLED 1543 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1544 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1545 device |= AudioSystem::DEVICE_OUT_PROXY; 1546 alsa_handle.devices = device; 1547 } 1548#endif 1549 mALSADevice->route(&(*it), (uint32_t)device, mode); 1550 if (!strcmp(it->useCase, verb)) { 1551 snd_use_case_set(mUcMgr, "_verb", verb); 1552 } else { 1553 snd_use_case_set(mUcMgr, "_enamod", modifier); 1554 } 1555 mALSADevice->startVoiceCall(&(*it)); 1556#ifdef QCOM_USBAUDIO_ENABLED 1557 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1558 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1559 startUsbRecordingIfNotStarted(); 1560 startUsbPlaybackIfNotStarted(); 1561 musbPlaybackState |= USBPLAYBACKBIT_VOICECALL; 1562 musbRecordingState |= USBRECBIT_VOICECALL; 1563 } 1564#endif 1565} 1566 1567bool AudioHardwareALSA::routeVoiceCall(int device, int newMode) 1568{ 1569int csCallState = mCallState&0xF; 1570 bool isRouted = false; 1571 switch (csCallState) { 1572 case CS_INACTIVE: 1573 if (mCSCallActive != CS_INACTIVE) { 1574 ALOGD("doRouting: Disabling voice call"); 1575 disableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL, 1576 (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device); 1577 isRouted = true; 1578 mCSCallActive = CS_INACTIVE; 1579 } 1580 break; 1581 case CS_ACTIVE: 1582 if (mCSCallActive == CS_INACTIVE) { 1583 ALOGD("doRouting: Enabling CS voice call "); 1584 enableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL, 1585 (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device); 1586 isRouted = true; 1587 mCSCallActive = CS_ACTIVE; 1588 } else if (mCSCallActive == CS_HOLD) { 1589 ALOGD("doRouting: Resume voice call from hold state"); 1590 ALSAHandleList::iterator vt_it; 1591 for(vt_it = mDeviceList.begin(); 1592 vt_it != mDeviceList.end(); ++vt_it) { 1593 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL, 1594 strlen(SND_USE_CASE_VERB_VOICECALL))) || 1595 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE, 1596 strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) { 1597 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 1598 mCSCallActive = CS_ACTIVE; 1599 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0) 1600 ALOGE("VoLTE resume failed"); 1601 break; 1602 } 1603 } 1604 } 1605 break; 1606 case CS_HOLD: 1607 if (mCSCallActive == CS_ACTIVE) { 1608 ALOGD("doRouting: Voice call going to Hold"); 1609 ALSAHandleList::iterator vt_it; 1610 for(vt_it = mDeviceList.begin(); 1611 vt_it != mDeviceList.end(); ++vt_it) { 1612 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL, 1613 strlen(SND_USE_CASE_VERB_VOICECALL))) || 1614 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE, 1615 strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) { 1616 mCSCallActive = CS_HOLD; 1617 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 1618 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0) 1619 ALOGE("Voice pause failed"); 1620 break; 1621 } 1622 } 1623 } 1624 break; 1625 } 1626 return isRouted; 1627} 1628bool AudioHardwareALSA::routeVoLTECall(int device, int newMode) 1629{ 1630int volteCallState = mCallState&0xF0; 1631bool isRouted = false; 1632switch (volteCallState) { 1633 case IMS_INACTIVE: 1634 if (mVolteCallActive != IMS_INACTIVE) { 1635 ALOGD("doRouting: Disabling IMS call"); 1636 disableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE, 1637 (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device); 1638 isRouted = true; 1639 mVolteCallActive = IMS_INACTIVE; 1640 } 1641 break; 1642 case IMS_ACTIVE: 1643 if (mVolteCallActive == IMS_INACTIVE) { 1644 ALOGD("doRouting: Enabling IMS voice call "); 1645 enableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE, 1646 (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device); 1647 isRouted = true; 1648 mVolteCallActive = IMS_ACTIVE; 1649 } else if (mVolteCallActive == IMS_HOLD) { 1650 ALOGD("doRouting: Resume IMS call from hold state"); 1651 ALSAHandleList::iterator vt_it; 1652 for(vt_it = mDeviceList.begin(); 1653 vt_it != mDeviceList.end(); ++vt_it) { 1654 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE, 1655 strlen(SND_USE_CASE_VERB_VOLTE))) || 1656 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE, 1657 strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) { 1658 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 1659 mVolteCallActive = IMS_ACTIVE; 1660 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0) 1661 ALOGE("VoLTE resume failed"); 1662 break; 1663 } 1664 } 1665 } 1666 break; 1667 case IMS_HOLD: 1668 if (mVolteCallActive == IMS_ACTIVE) { 1669 ALOGD("doRouting: IMS ACTIVE going to HOLD"); 1670 ALSAHandleList::iterator vt_it; 1671 for(vt_it = mDeviceList.begin(); 1672 vt_it != mDeviceList.end(); ++vt_it) { 1673 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE, 1674 strlen(SND_USE_CASE_VERB_VOLTE))) || 1675 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE, 1676 strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) { 1677 mVolteCallActive = IMS_HOLD; 1678 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 1679 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0) 1680 ALOGE("VoLTE Pause failed"); 1681 break; 1682 } 1683 } 1684 } 1685 break; 1686 } 1687 return isRouted; 1688} 1689 1690} // namespace android_audio_legacy 1691