From 477917f32cdd9269de924dc1bc599aa728b34084 Mon Sep 17 00:00:00 2001 From: Jaideep Sharma Date: Fri, 13 Mar 2020 18:13:33 +0530 Subject: [PATCH] hal: add support for callscreening. handle newly added callscreening mode, provide support for device selection as per this new mode. Change-Id: I3c57c9edd38cf4347d11c871e1878a4536936edc --- hal/audio_extn/audio_extn.c | 2 +- hal/audio_extn/audio_extn.h | 3 +- hal/audio_extn/passthru.c | 2 +- hal/audio_hw.c | 57 ++++++++++++++++++++------------- hal/audio_hw.h | 1 + hal/msm8916/platform.c | 10 ++++-- hal/msm8974/platform.c | 63 ++++++++++++++++++++++++++++++------- hal/msm8974/platform.h | 4 +++ hal/platform_api.h | 7 +++-- hal/voice.c | 43 +++++++++++++++++++------ hal/voice.h | 4 ++- hal/voice_extn/voice_extn.c | 5 ++- 12 files changed, 149 insertions(+), 52 deletions(-) diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c index 43c63570..c47d1387 100644 --- a/hal/audio_extn/audio_extn.c +++ b/hal/audio_extn/audio_extn.c @@ -3664,7 +3664,7 @@ int audio_extn_set_device_cfg_params(struct audio_device *adev, /* Create an out stream to get snd device from audio device */ reassign_device_list(&out.device_list, device_cfg_params->device, ""); out.sample_rate = device_cfg_params->sample_rate; - snd_device = platform_get_output_snd_device(adev->platform, &out); + snd_device = platform_get_output_snd_device(adev->platform, &out, USECASE_TYPE_MAX); backend_idx = platform_get_backend_index(snd_device); ALOGV("%s:: device %d sample_rate %d snd_device %d backend_idx %d", diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h index dc6efe17..f2152d6f 100644 --- a/hal/audio_extn/audio_extn.h +++ b/hal/audio_extn/audio_extn.h @@ -613,7 +613,8 @@ enum { typedef bool (*fp_platform_is_edid_supported_format_t)(void*, int); typedef int (*fp_platform_set_device_params_t)(struct stream_out*, int, int); typedef int (*fp_platform_edid_get_max_channels_t)(void*); -typedef snd_device_t (*fp_platform_get_output_snd_device_t)(void*, struct stream_out*); +typedef snd_device_t (*fp_platform_get_output_snd_device_t)(void*, struct stream_out*, + usecase_type_t); typedef int (*fp_platform_get_codec_backend_cfg_t)(struct audio_device*, snd_device_t, struct audio_backend_cfg*); typedef bool (*fp_platform_is_edid_supported_sample_rate_t)(void*, int); diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c index 25a18f97..271ae23e 100644 --- a/hal/audio_extn/passthru.c +++ b/hal/audio_extn/passthru.c @@ -592,7 +592,7 @@ bool passthru_is_supported_backend_edid_cfg(struct audio_device *adev, snd_device_t out_snd_device = SND_DEVICE_NONE; int max_edid_channels = fp_platform_edid_get_max_channels(out->dev->platform); - out_snd_device = fp_platform_get_output_snd_device(adev->platform, out); + out_snd_device = fp_platform_get_output_snd_device(adev->platform, out, USECASE_TYPE_MAX); if (fp_platform_get_codec_backend_cfg(adev, out_snd_device, &backend_cfg)) { ALOGE("%s: ERROR: Unable to get current backend config!!!", __func__); diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 9b8f29da..b2d87a95 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -1810,7 +1810,8 @@ static void check_usecases_codec_backend(struct audio_device *adev, usecase->out_snd_device, platform_get_input_snd_device( adev->platform, NULL, - &uc_info->device_list)); + &uc_info->device_list, + usecase->type)); enable_audio_route(adev, usecase); if (usecase->stream.out && usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) { out_set_voip_volume(&usecase->stream.out->stream, @@ -1863,9 +1864,12 @@ static void check_usecases_capture_codec_backend(struct audio_device *adev, /* * TODO: Enhance below condition to handle BT sco/USB multi recording */ - if (usecase->type != PCM_PLAYBACK && - usecase != uc_info && - (usecase->in_snd_device != snd_device || force_routing) && + + bool capture_uc_needs_routing = usecase->type != PCM_PLAYBACK && (usecase != uc_info && + (usecase->in_snd_device != snd_device || force_routing)); + bool call_proxy_snd_device = platform_is_call_proxy_snd_device(snd_device) || + platform_is_call_proxy_snd_device(usecase->in_snd_device); + if (capture_uc_needs_routing && !call_proxy_snd_device && ((backend_check_cond && (is_codec_backend_in_device_type(&usecase->device_list) || (usecase->type == VOIP_CALL))) || @@ -1875,7 +1879,7 @@ static void check_usecases_capture_codec_backend(struct audio_device *adev, platform_check_backends_match(snd_device,\ usecase->in_snd_device))) && (usecase->id != USECASE_AUDIO_SPKR_CALIB_TX)) { - ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..", + ALOGD("%s: Usecase (%s) is active on (%s) - disabling ..", __func__, use_case_table[usecase->id], platform_get_snd_device_name(usecase->in_snd_device)); disable_audio_route(adev, usecase); @@ -1912,10 +1916,15 @@ static void check_usecases_capture_codec_backend(struct audio_device *adev, usecase->in_snd_device = snd_device; if (usecase->type != VOICE_CALL) { /* Update voc calibration before enabling VoIP route */ - if (usecase->type == VOIP_CALL) + if (usecase->type == VOIP_CALL) { + snd_device_t voip_snd_device; + voip_snd_device = platform_get_output_snd_device(adev->platform, + uc_info->stream.out, + usecase->type); status = platform_switch_voice_call_device_post(adev->platform, - platform_get_output_snd_device(adev->platform, uc_info->stream.out), + voip_snd_device, usecase->in_snd_device); + } enable_audio_route(adev, usecase); } } @@ -2586,10 +2595,11 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) uc_id); } else { out_snd_device = platform_get_output_snd_device(adev->platform, - usecase->stream.out); + usecase->stream.out, usecase->type); in_snd_device = platform_get_input_snd_device(adev->platform, NULL, - &usecase->stream.out->device_list); + &usecase->stream.out->device_list, + usecase->type); } assign_devices(&usecase->device_list, &usecase->stream.out->device_list); } else if (usecase->type == TRANSCODE_LOOPBACK_RX) { @@ -2601,8 +2611,7 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) stream_out.sample_rate = usecase->stream.inout->out_config.sample_rate; stream_out.format = usecase->stream.inout->out_config.format; stream_out.channel_mask = usecase->stream.inout->out_config.channel_mask; - out_snd_device = platform_get_output_snd_device(adev->platform, - &stream_out); + out_snd_device = platform_get_output_snd_device(adev->platform, &stream_out, usecase->type); assign_devices(&usecase->device_list, &usecase->stream.inout->out_config.device_list); } else if (usecase->type == TRANSCODE_LOOPBACK_TX ) { @@ -2610,7 +2619,7 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) ALOGE("%s: stream.inout is NULL", __func__); return -EINVAL; } - in_snd_device = platform_get_input_snd_device(adev->platform, NULL, NULL); + in_snd_device = platform_get_input_snd_device(adev->platform, NULL, NULL, usecase->type); assign_devices(&usecase->device_list, &usecase->stream.inout->in_config.device_list); } else { @@ -2647,7 +2656,7 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) voip_usecase->out_snd_device, platform_get_output_snd_device( adev->platform, - usecase->stream.out)); + usecase->stream.out, usecase->type)); } if ((voip_usecase) && (is_codec_backend_out_device_type(&voip_usecase->device_list) && (is_codec_backend_out_device_type(&usecase->device_list) || @@ -2679,7 +2688,8 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) out_snd_device = audio_extn_auto_hal_get_output_snd_device(adev, uc_id); else out_snd_device = platform_get_output_snd_device(adev->platform, - usecase->stream.out); + usecase->stream.out, + usecase->type); voip_usecase = get_usecase_from_list(adev, USECASE_AUDIO_PLAYBACK_VOIP); if (voip_usecase) @@ -2730,7 +2740,8 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) in_snd_device = platform_get_input_snd_device(adev->platform, priority_in, - &out_devices); + &out_devices, + usecase->type); } } } @@ -2796,12 +2807,12 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) (usecase->type == VOIP_CALL)) && (usecase->out_snd_device != SND_DEVICE_NONE)) { /* Disable sidetone only if voice/voip call already exists */ - if (voice_is_call_state_active(adev) || + if (voice_is_call_state_active_in_call(adev) || voice_extn_compress_voip_is_started(adev)) voice_set_sidetone(adev, usecase->out_snd_device, false); /* Disable aanc only if voice call exists */ - if (voice_is_call_state_active(adev)) + if (voice_is_call_state_active_in_call(adev)) voice_check_and_update_aanc_path(adev, usecase->out_snd_device, false); } @@ -2899,11 +2910,11 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) { /* Enable aanc only if voice call exists */ - if (voice_is_call_state_active(adev)) + if (voice_is_call_state_active_in_call(adev)) voice_check_and_update_aanc_path(adev, out_snd_device, true); /* Enable sidetone only if other voice/voip call already exists */ - if (voice_is_call_state_active(adev) || + if (voice_is_call_state_active_in_call(adev) || voice_extn_compress_voip_is_started(adev)) voice_set_sidetone(adev, out_snd_device, true); } @@ -8807,9 +8818,13 @@ static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) pthread_mutex_lock(&adev->lock); if (adev->mode != mode) { - ALOGD("%s: mode %d\n", __func__, mode); + ALOGD("%s: mode %d , prev_mode %d \n", __func__, mode , adev->mode); + adev->prev_mode = adev->mode; /* prev_mode is kept to handle voip concurrency*/ adev->mode = mode; - if (voice_is_in_call(adev) && + if( mode == AUDIO_MODE_CALL_SCREEN ){ + adev->current_call_output = adev->primary_output; + voice_start_call(adev); + } else if (voice_is_in_call_or_call_screen(adev) && (mode == AUDIO_MODE_NORMAL || (mode == AUDIO_MODE_IN_COMMUNICATION && !voice_is_call_state_active(adev)))) { list_for_each(node, &adev->usecase_list) { diff --git a/hal/audio_hw.h b/hal/audio_hw.h index ce82145b..cc9e6021 100644 --- a/hal/audio_hw.h +++ b/hal/audio_hw.h @@ -612,6 +612,7 @@ struct audio_device { pthread_mutex_t cal_lock; struct mixer *mixer; audio_mode_t mode; + audio_mode_t prev_mode; audio_devices_t out_device; struct stream_out *primary_output; struct stream_out *voice_tx_output; diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c index 66add14b..235ae1f7 100644 --- a/hal/msm8916/platform.c +++ b/hal/msm8916/platform.c @@ -4199,7 +4199,8 @@ int platform_get_ext_disp_type(void *platform) return disp_type; } -snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out) +snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out, + usecase_type_t uc_type __unused) { struct platform_data *my_data = (struct platform_data *)platform; struct audio_device *adev = my_data->adev; @@ -4672,7 +4673,8 @@ static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data, snd_device_t platform_get_input_snd_device(void *platform, struct stream_in *in, - audio_devices_t out_device) + audio_devices_t out_device, + usecase_type_t uc_type __unused) { struct platform_data *my_data = (struct platform_data *)platform; struct audio_device *adev = my_data->adev; @@ -8707,3 +8709,7 @@ int platform_get_display_port_ctl_index(int controller __unused, { return -EINVAL; } + +bool platform_is_call_proxy_snd_device(snd_device_t snd_device __unused) { + return false; +} diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c index ed23acae..87df8da6 100644 --- a/hal/msm8974/platform.c +++ b/hal/msm8974/platform.c @@ -601,6 +601,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_OUT_BUS_NAV] = "bus-speaker", [SND_DEVICE_OUT_BUS_PHN] = "bus-speaker", [SND_DEVICE_OUT_BUS_RSE] = "bus-speaker", + [SND_DEVICE_OUT_CALL_PROXY] = "call-proxy", /* Capture sound devices */ [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic", @@ -740,6 +741,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_HANDSET_QMIC_AND_EC_REF_LOOPBACK] = "handset-qmic-and-ec-ref-loopback", [SND_DEVICE_IN_HANDSET_6MIC_AND_EC_REF_LOOPBACK] = "handset-6mic-and-ec-ref-loopback", [SND_DEVICE_IN_HANDSET_8MIC_AND_EC_REF_LOOPBACK] = "handset-8mic-and-ec-ref-loopback", + [SND_DEVICE_IN_CALL_PROXY] = "call-proxy-in", }; // Platform specific backend bit width table @@ -876,6 +878,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = { [SND_DEVICE_OUT_BUS_NAV] = 14, [SND_DEVICE_OUT_BUS_PHN] = 94, [SND_DEVICE_OUT_BUS_RSE] = 60, + [SND_DEVICE_OUT_CALL_PROXY] = 32, [SND_DEVICE_IN_HANDSET_MIC] = 4, [SND_DEVICE_IN_HANDSET_MIC_SB] = 163, [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = 4, @@ -1005,6 +1008,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = 4, [SND_DEVICE_IN_VOICE_HEARING_AID] = 44, [SND_DEVICE_IN_BUS] = 11, + [SND_DEVICE_IN_CALL_PROXY] = 33, }; struct name_to_index { @@ -1112,6 +1116,7 @@ static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = { {TO_NAME_INDEX(SND_DEVICE_OUT_BUS_NAV)}, {TO_NAME_INDEX(SND_DEVICE_OUT_BUS_PHN)}, {TO_NAME_INDEX(SND_DEVICE_OUT_BUS_RSE)}, + {TO_NAME_INDEX(SND_DEVICE_OUT_CALL_PROXY)}, {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)}, {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_SB)}, {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_EXTERNAL)}, @@ -1248,6 +1253,7 @@ static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = { {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC_AND_EC_REF_LOOPBACK)}, {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_6MIC_AND_EC_REF_LOOPBACK)}, {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_8MIC_AND_EC_REF_LOOPBACK)}, + {TO_NAME_INDEX(SND_DEVICE_IN_CALL_PROXY)}, }; static char * backend_tag_table[SND_DEVICE_MAX] = {0}; @@ -2215,6 +2221,8 @@ static void set_platform_defaults(struct platform_data * my_data) backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_FB_HEADSET] = strdup("speaker-and-headphones"); backend_tag_table[SND_DEVICE_OUT_VOICE_HEARING_AID] = strdup("hearing-aid"); backend_tag_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP_MMSECNS] = strdup("bt-sco-mmsecns"); + backend_tag_table[SND_DEVICE_OUT_CALL_PROXY] = strdup("call-proxy"); + backend_tag_table[SND_DEVICE_IN_CALL_PROXY] = strdup("call-proxy-in"); hw_interface_table[SND_DEVICE_OUT_HANDSET] = strdup("SLIMBUS_0_RX"); hw_interface_table[SND_DEVICE_OUT_SPEAKER] = strdup("SLIMBUS_0_RX"); @@ -2315,6 +2323,7 @@ static void set_platform_defaults(struct platform_data * my_data) hw_interface_table[SND_DEVICE_OUT_BUS_NAV] = strdup("TERT_TDM_RX_1"); hw_interface_table[SND_DEVICE_OUT_BUS_PHN] = strdup("TERT_TDM_RX_2"); hw_interface_table[SND_DEVICE_OUT_BUS_RSE] = strdup("QUAT_TDM_RX_0"); + hw_interface_table[SND_DEVICE_OUT_CALL_PROXY] = strdup("CALL_PROXY_RX"); hw_interface_table[SND_DEVICE_IN_HANDSET_MIC] = strdup("SLIMBUS_0_TX"); hw_interface_table[SND_DEVICE_IN_HANDSET_MIC_SB] = strdup("SLIMBUS_0_TX"); hw_interface_table[SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = strdup("SLIMBUS_0_TX"); @@ -2443,6 +2452,7 @@ static void set_platform_defaults(struct platform_data * my_data) hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = strdup("SLIMBUS_0_TX"); hw_interface_table[SND_DEVICE_IN_VOICE_HEARING_AID] = strdup("SLIMBUS_0_TX"); hw_interface_table[SND_DEVICE_IN_BUS] = strdup("TERT_TDM_TX_0"); + hw_interface_table[SND_DEVICE_IN_CALL_PROXY] = strdup("CALL_PROXY_TX"); my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT; /*remove ALAC & APE from DSP decoder list based on software decoder availability*/ @@ -5050,6 +5060,8 @@ int platform_get_backend_index(snd_device_t snd_device) else if ((strcmp(backend_tag_table[snd_device], "usb-headphones") == 0) || (strcmp(backend_tag_table[snd_device], "usb-headset") == 0)) port = USB_AUDIO_RX_BACKEND; + else if (strcmp(backend_tag_table[snd_device], "call-proxy") == 0) + port = CALL_PROXY_RX_BACKEND; } } else if (snd_device >= SND_DEVICE_IN_BEGIN && snd_device < SND_DEVICE_IN_END) { port = DEFAULT_CODEC_TX_BACKEND; @@ -5066,6 +5078,8 @@ int platform_get_backend_index(snd_device_t snd_device) port = HDMI_ARC_TX_BACKEND; else if (strcmp(backend_tag_table[snd_device], "headset-mic") == 0) port = HEADSET_TX_BACKEND; + else if (strcmp(backend_tag_table[snd_device], "call-proxy-in") == 0) + port = CALL_PROXY_TX_BACKEND; } } else { ALOGW("%s:napb: Invalid device - %d ", __func__, snd_device); @@ -5089,7 +5103,7 @@ int platform_send_audio_calibration(void *platform, struct audio_usecase *usecas struct audio_backend_cfg backend_cfg = {0}; bool is_bus_dev_usecase = false; - if (voice_is_in_call(my_data->adev)) + if (voice_is_in_call_or_call_screen(my_data->adev)) is_incall_rec_usecase = voice_is_in_call_rec_stream(usecase->stream.in); if (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_BUS)) @@ -5212,7 +5226,7 @@ int platform_switch_voice_call_device_pre(void *platform) int ret = 0; if (my_data->csd != NULL && - voice_is_in_call(my_data->adev)) { + voice_is_in_call_or_call_screen(my_data->adev)) { /* This must be called before disabling mixer controls on APQ side */ ret = my_data->csd->disable_device(); if (ret < 0) { @@ -5505,7 +5519,8 @@ int platform_set_mic_mute(void *platform, bool state) DEFAULT_MUTE_RAMP_DURATION_MS}; if (adev->mode != AUDIO_MODE_IN_CALL && - adev->mode != AUDIO_MODE_IN_COMMUNICATION) + adev->mode != AUDIO_MODE_IN_COMMUNICATION && + adev->mode != AUDIO_MODE_CALL_SCREEN) return 0; if (adev->enable_hfp) @@ -5951,7 +5966,8 @@ int platform_get_ext_disp_type_v2(void *platform, int controller, int stream) return disp_type; } -snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out) +snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out, + usecase_type_t uc_type) { struct platform_data *my_data = (struct platform_data *)platform; struct audio_device *adev = my_data->adev; @@ -5990,6 +6006,15 @@ snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *o } } + if (mode == AUDIO_MODE_CALL_SCREEN) { + if (uc_type == VOICE_CALL) + snd_device = SND_DEVICE_OUT_CALL_PROXY; + if (compare_device_type(&devices, AUDIO_DEVICE_OUT_TELEPHONY_TX)) + snd_device = SND_DEVICE_OUT_VOICE_TX; + if (snd_device != SND_DEVICE_NONE) + goto exit; + } + if (list_length(&devices) == 2) { bool is_active_voice_call = false; @@ -6608,7 +6633,8 @@ static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data, snd_device_t platform_get_input_snd_device(void *platform, struct stream_in *in, - struct listnode *out_devices) + struct listnode *out_devices, + usecase_type_t uc_type) { struct platform_data *my_data = (struct platform_data *)platform; struct audio_device *adev = my_data->adev; @@ -6649,6 +6675,13 @@ snd_device_t platform_get_input_snd_device(void *platform, } } + if (mode == AUDIO_MODE_CALL_SCREEN) { + if (uc_type == VOICE_CALL) + snd_device = SND_DEVICE_IN_CALL_PROXY; + if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_TELEPHONY_TX)) + snd_device = SND_DEVICE_IN_VOICE_RX; + } + if (snd_device != AUDIO_DEVICE_NONE) goto exit; @@ -7672,11 +7705,12 @@ static void set_audiocal(void *platform, struct str_parms *parms, char *value, i struct listnode cal_devices; list_init(&cal_devices); update_device_list(&cal_devices, cal.dev_id, address, true); - cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, &cal_devices); + cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, &cal_devices, + USECASE_TYPE_MAX); } else { reassign_device_list(&out.device_list, cal.dev_id, address); out.sample_rate = cal.sampling_rate; - cal.snd_dev_id = platform_get_output_snd_device(platform, &out); + cal.snd_dev_id = platform_get_output_snd_device(platform, &out, USECASE_TYPE_MAX); } } cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id); @@ -8258,11 +8292,11 @@ static void get_audiocal(void *platform, void *keys, void *pReply) { struct listnode devices; list_init(&devices); update_device_list(&devices, cal.dev_id, address, true); - cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, &devices); + cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, &devices, USECASE_TYPE_MAX); } else if (cal.dev_id) { reassign_device_list(&out.device_list, cal.dev_id, address); out.sample_rate = cal.sampling_rate; - cal.snd_dev_id = platform_get_output_snd_device(platform, &out); + cal.snd_dev_id = platform_get_output_snd_device(platform, &out, USECASE_TYPE_MAX); } cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id); if (cal.acdb_dev_id < 0) { @@ -8706,7 +8740,8 @@ static int platform_get_voice_call_backend(struct audio_device* adev) (uc->type == VOICE_CALL || uc->type == VOIP_CALL || uc->id == USECASE_AUDIO_PLAYBACK_VOIP)) { - out_snd_device = platform_get_output_snd_device(adev->platform, uc->stream.out); + out_snd_device = platform_get_output_snd_device(adev->platform, uc->stream.out, + uc->type); backend_idx = platform_get_backend_index(out_snd_device); break; } @@ -11700,7 +11735,7 @@ int platform_get_active_microphones(void *platform, unsigned int channels, list_init(&devices); snd_device_t active_input_snd_device = - platform_get_input_snd_device(platform, usecase->stream.in, &devices); + platform_get_input_snd_device(platform, usecase->stream.in, &devices, USECASE_TYPE_MAX); if (active_input_snd_device == SND_DEVICE_NONE) { ALOGI("%s: No active microphones found", __func__); goto end; @@ -11752,3 +11787,9 @@ int platform_get_controller_stream_from_params(struct str_parms *parms, } return 0; } + +bool platform_is_call_proxy_snd_device(snd_device_t snd_device) { + if (snd_device == SND_DEVICE_IN_CALL_PROXY || snd_device == SND_DEVICE_OUT_CALL_PROXY) + return true; + return false; +} diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h index be138c06..8bf96489 100644 --- a/hal/msm8974/platform.h +++ b/hal/msm8974/platform.h @@ -164,6 +164,7 @@ enum { SND_DEVICE_OUT_BUS_NAV, SND_DEVICE_OUT_BUS_PHN, SND_DEVICE_OUT_BUS_RSE, + SND_DEVICE_OUT_CALL_PROXY, SND_DEVICE_OUT_END, /* @@ -307,6 +308,7 @@ enum { SND_DEVICE_IN_HANDSET_QMIC_AND_EC_REF_LOOPBACK, SND_DEVICE_IN_HANDSET_6MIC_AND_EC_REF_LOOPBACK, SND_DEVICE_IN_HANDSET_8MIC_AND_EC_REF_LOOPBACK, + SND_DEVICE_IN_CALL_PROXY, SND_DEVICE_IN_END, SND_DEVICE_MAX = SND_DEVICE_IN_END, @@ -332,6 +334,7 @@ enum { DISP_PORT_RX_BACKEND, DISP_PORT1_RX_BACKEND, USB_AUDIO_RX_BACKEND, + CALL_PROXY_RX_BACKEND, MAX_RX_CODEC_BACKENDS = USB_AUDIO_RX_BACKEND, /* TX BE follows RX BE */ SLIMBUS_0_TX, @@ -342,6 +345,7 @@ enum { HDMI_TX_BACKEND, HDMI_ARC_TX_BACKEND, HEADSET_TX_BACKEND, + CALL_PROXY_TX_BACKEND, MAX_CODEC_BACKENDS }; diff --git a/hal/platform_api.h b/hal/platform_api.h index fbf159ac..05ddcb10 100644 --- a/hal/platform_api.h +++ b/hal/platform_api.h @@ -204,10 +204,12 @@ void platform_set_speaker_gain_in_combo(struct audio_device *adev, int platform_set_mic_mute(void *platform, bool state); int platform_get_sample_rate(void *platform, uint32_t *rate); int platform_set_device_mute(void *platform, bool state, char *dir); -snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out); +snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out, + usecase_type_t uc_type); snd_device_t platform_get_input_snd_device(void *platform, struct stream_in *in, - struct listnode *out_devices); + struct listnode *out_devices, + usecase_type_t uc_type); int platform_set_hdmi_channels(void *platform, int channel_count); int platform_edid_get_max_channels(void *platform); void platform_add_operator_specific_device(snd_device_t snd_device, @@ -415,4 +417,5 @@ int platform_set_channel_allocation_v2(void *platform, int channel_alloc, int platform_set_hdmi_channels_v2(void *platform, int channel_count, int controller, int stream); int platform_get_display_port_ctl_index(int controller, int stream); +bool platform_is_call_proxy_snd_device(snd_device_t snd_device); #endif // AUDIO_PLATFORM_API_H diff --git a/hal/voice.c b/hal/voice.c index 818eb949..72c3372b 100644 --- a/hal/voice.c +++ b/hal/voice.c @@ -167,11 +167,11 @@ int voice_stop_usecase(struct audio_device *adev, audio_usecase_t usecase_id) session->state.current = CALL_INACTIVE; /* Disable sidetone only when no calls are active */ - if (!voice_is_call_state_active(adev)) + if (!voice_is_call_state_active_in_call(adev)) voice_set_sidetone(adev, uc_info->out_snd_device, false); /* Disable aanc only when no calls are active */ - if (!voice_is_call_state_active(adev)) + if (!voice_is_call_state_active_in_call(adev)) voice_check_and_update_aanc_path(adev, uc_info->out_snd_device, false); ret = platform_stop_voice_call(adev->platform, session->vsid); @@ -221,6 +221,7 @@ int voice_start_usecase(struct audio_device *adev, audio_usecase_t usecase_id) uint32_t sample_rate = 8000; struct voice_session *session = NULL; struct pcm_config voice_config = pcm_config_voice_call; + bool is_in_call = (AUDIO_MODE_IN_CALL == adev->mode); ALOGD("%s: enter usecase:%s", __func__, use_case_table[usecase_id]); @@ -242,7 +243,7 @@ int voice_start_usecase(struct audio_device *adev, audio_usecase_t usecase_id) list_init(&uc_info->device_list); assign_devices(&uc_info->device_list, &adev->current_call_output->device_list); - if (list_length(&uc_info->device_list) == 2) { + if (is_in_call && list_length(&uc_info->device_list) == 2) { ALOGE("%s: Invalid combo device(%#x) for voice call", __func__, get_device_types(&uc_info->device_list)); ret = -EIO; @@ -361,11 +362,11 @@ int voice_start_usecase(struct audio_device *adev, audio_usecase_t usecase_id) #endif /* Enable aanc only when no calls are active */ - if (!voice_is_call_state_active(adev)) + if (!voice_is_call_state_active_in_call(adev)) voice_check_and_update_aanc_path(adev, uc_info->out_snd_device, true); /* Enable sidetone only when no calls are already active */ - if (!voice_is_call_state_active(adev)) + if (!voice_is_call_state_active_in_call(adev)) voice_set_sidetone(adev, uc_info->out_snd_device, true); voice_set_volume(adev, adev->voice.volume); @@ -387,8 +388,10 @@ done: return ret; } -bool voice_is_call_state_active(struct audio_device *adev) -{ +/* +* helper function to check whether call is active or not. +*/ +static inline bool voice_is_active(struct audio_device *adev) { bool call_state = false; int ret = 0; @@ -400,7 +403,29 @@ bool voice_is_call_state_active(struct audio_device *adev) return call_state; } +/* +* checks if call is active and in IN_CALL mode. +*/ +bool voice_is_call_state_active_in_call(struct audio_device *adev) +{ + bool call_state = voice_is_active(adev); + return call_state && adev->mode == AUDIO_MODE_IN_CALL; +} + +/* +* returns true if call is active no matter what mode is. +*/ +bool voice_is_call_state_active(struct audio_device *adev) +{ + return voice_is_active(adev); +} + bool voice_is_in_call(const struct audio_device *adev) +{ + return adev->voice.in_call && adev->mode == AUDIO_MODE_IN_CALL; +} + +bool voice_is_in_call_or_call_screen(const struct audio_device *adev) { return adev->voice.in_call; } @@ -442,7 +467,7 @@ bool voice_check_voicecall_usecases_active(struct audio_device *adev) list_for_each(node, &adev->usecase_list) { usecase = node_to_item(node, struct audio_usecase, list); - if (usecase->type == VOICE_CALL) { + if (usecase->type == VOICE_CALL && adev->mode != AUDIO_MODE_CALL_SCREEN) { ALOGV("%s: voice usecase:%s is active", __func__, use_case_table[usecase->id]); return true; @@ -748,7 +773,7 @@ int voice_set_parameters(struct audio_device *adev, struct str_parms *parms) if (tty_mode != adev->voice.tty_mode) { adev->voice.tty_mode = tty_mode; adev->acdb_settings = (adev->acdb_settings & TTY_MODE_CLEAR) | tty_mode; - if (voice_is_call_state_active(adev)) + if (voice_is_call_state_active_in_call(adev)) voice_update_devices_for_all_voice_usecases(adev); } } diff --git a/hal/voice.h b/hal/voice.h index 188345d3..94782b81 100644 --- a/hal/voice.h +++ b/hal/voice.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. * Not a contribution. * * Copyright (C) 2013 The Android Open Source Project @@ -80,6 +80,7 @@ void voice_get_parameters(struct audio_device *adev, struct str_parms *query, struct str_parms *reply); void voice_init(struct audio_device *adev); bool voice_is_in_call(const struct audio_device *adev); +bool voice_is_in_call_or_call_screen(const struct audio_device *adev); bool voice_is_in_call_rec_stream(const struct stream_in *in); int voice_set_mic_mute(struct audio_device *dev, bool state); bool voice_get_mic_mute(struct audio_device *dev); @@ -99,6 +100,7 @@ void voice_check_and_update_aanc_path(struct audio_device *adev, snd_device_t out_snd_device, bool enable); bool voice_is_call_state_active(struct audio_device *adev); +bool voice_is_call_state_active_in_call(struct audio_device *adev); void voice_set_device_mute_flag (struct audio_device *adev, bool state); snd_device_t voice_get_incall_rec_backend_device(struct stream_in *in); bool voice_check_voicecall_usecases_active(struct audio_device *adev); diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c index e2dc984c..c2e419a2 100644 --- a/hal/voice_extn/voice_extn.c +++ b/hal/voice_extn/voice_extn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. * Not a contribution. * * Copyright (C) 2013 The Android Open Source Project @@ -363,8 +363,7 @@ static int update_call_states(struct audio_device *adev, * occured, otherwise voice calls will be started unintendedly on * speaker. */ - if (is_call_active || - (adev->voice.in_call && adev->mode == AUDIO_MODE_IN_CALL)) { + if (is_call_active || voice_is_in_call(adev)) { /* Device routing is not triggered for voice calls on the subsequent * subs, Hence update the call states if voice call is already * active on other sub.