audio: Enable voice call support
Pair-Programmed-With: Andreas Schneider <asn@cryptomilk.org>
Change-Id: I284f21240e56dda93cb8a2ab98b903ff712504a6
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 986ef0a..c147acf 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -502,11 +502,11 @@
static int set_voice_volume_l(struct audio_device *adev, float volume)
{
int err = 0;
- (void)volume;
if (adev->mode == AUDIO_MODE_IN_CALL) {
- /* TODO */
+ set_voice_session_volume(adev->voice.session, volume);
}
+
return err;
}
@@ -861,6 +861,7 @@
if (usecase->type == VOICE_CALL) {
out_snd_device = get_output_snd_device(adev, active_out->devices);
+ prepare_voice_session(adev->voice.session, active_out->devices);
in_snd_device = get_input_snd_device(adev, active_out->devices);
usecase->devices = active_out->devices;
} else {
@@ -925,6 +926,11 @@
/* Enable new sound devices */
if (out_snd_device != SND_DEVICE_NONE) {
+ /* We need to update the audio path if we switch the out devices */
+ if (adev->voice.in_call) {
+ set_voice_session_audio_path(adev->voice.session);
+ }
+
enable_snd_device(adev, usecase, out_snd_device, false);
}
@@ -2079,6 +2085,11 @@
#endif
#endif
+ if (in->dev->voice.in_call) {
+ ALOGV("%s: in_call, not handling PCMs", __func__);
+ goto skip_pcm_handling;
+ }
+
/* Open the PCM device.
* The HW is limited to support only the default pcm_profile settings.
* As such a change in aux_channels will not have an effect.
@@ -2116,6 +2127,7 @@
}
}
+skip_pcm_handling:
/* force read and proc buffer reallocation in case of frame size or
* channel count change */
in->proc_buf_frames = 0;
@@ -2250,6 +2262,11 @@
if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
pcm_device_id = pcm_device_deep_buffer.id;
+ if (out->dev->voice.in_call) {
+ ALOGV("%s: in_call, not opening PCMs", __func__);
+ return ret;
+ }
+
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
__func__, pcm_device_card, pcm_device_id);
@@ -2396,14 +2413,14 @@
return ret;
}
-static int stop_voice_call(struct audio_device *adev)
+int stop_voice_call(struct audio_device *adev)
{
struct audio_usecase *uc_info;
ALOGV("%s: enter", __func__);
adev->voice.in_call = false;
- /* TODO: implement voice call stop */
+ stop_voice_session(adev->voice.session);
uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
if (uc_info == NULL) {
@@ -2415,7 +2432,6 @@
disable_snd_device(adev, uc_info, uc_info->out_snd_device, false);
disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
- uc_release_pcm_devices(uc_info);
list_remove(&uc_info->adev_list_node);
free(uc_info);
@@ -2424,7 +2440,7 @@
}
/* always called with adev lock held */
-static int start_voice_call(struct audio_device *adev)
+int start_voice_call(struct audio_device *adev)
{
struct audio_usecase *uc_info;
int ret = 0;
@@ -2436,6 +2452,12 @@
ret = -ENOMEM;
goto exit;
}
+ /*
+ * We set this early so that functions called after this is being set
+ * can use it. It is e.g. needed in select_devices() to inform the RILD
+ * which output device we use.
+ */
+ adev->voice.in_call = true;
uc_info->id = USECASE_VOICE_CALL;
uc_info->type = VOICE_CALL;
@@ -2444,19 +2466,19 @@
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
- uc_select_pcm_devices(uc_info);
+ list_init(&uc_info->mixer_list);
+ list_add_tail(&uc_info->mixer_list,
+ &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
select_devices(adev, USECASE_VOICE_CALL);
-
- /* TODO: implement voice call start */
+ start_voice_session(adev->voice.session);
/* set cached volume */
set_voice_volume_l(adev, adev->voice.volume);
- adev->voice.in_call = true;
exit:
ALOGV("%s: exit", __func__);
return ret;
@@ -4317,7 +4339,7 @@
}
}
- adev->voice.session = voice_session_init();
+ adev->voice.session = voice_session_init(adev);
if (adev->voice.session == NULL) {
ALOGE("%s: Failed to initialize voice session data", __func__);