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