hal: fix voice call device routing issue
voice_device_set flag is to indicate voice call device routing
update from policymanager to HAL. It is set to true in voice_extn_start_call
and reset in update_calls() which causes mismatch in flag update during back
to back voice calls scenario. Update adev->voice_device_set flag in
voice_extn_stop_call instead of update_calls().
Bug: 17149385
Cherry-pick of CAF commit: e0085d06416a8fb6d0b4503900508c16fbc98c58
Change-Id: Ie07105671f254899890bdb4c0635c7dc1f55dbff
diff --git a/hal/voice.c b/hal/voice.c
index 278f0fb..2d3ec7c 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -163,26 +163,32 @@
}
session->state.current = CALL_ACTIVE;
- return 0;
+ goto done;
error_start_voice:
stop_call(adev, usecase_id);
+done:
ALOGD("%s: exit: status(%d)", __func__, ret);
return ret;
}
-bool voice_is_in_call(struct audio_device *adev)
+bool voice_is_call_state_active(struct audio_device *adev)
{
- bool in_call = false;
+ bool call_state = false;
int ret = 0;
- ret = voice_extn_is_in_call(adev, &in_call);
+ ret = voice_extn_is_call_state_active(adev, &call_state);
if (ret == -ENOSYS) {
- in_call = (adev->voice.session[VOICE_SESS_IDX].state.current == CALL_ACTIVE) ? true : false;
+ call_state = (adev->voice.session[VOICE_SESS_IDX].state.current == CALL_ACTIVE) ? true : false;
}
- return in_call;
+ return call_state;
+}
+
+bool voice_is_in_call(struct audio_device *adev)
+{
+ return adev->voice.in_call;
}
bool voice_is_in_call_rec_stream(struct stream_in *in)
@@ -218,7 +224,7 @@
int usecase_id;
int rec_mode = INCALL_REC_NONE;
- if (voice_is_in_call(adev)) {
+ if (voice_is_call_state_active(adev)) {
switch (in->source) {
case AUDIO_SOURCE_VOICE_UPLINK:
in->usecase = USECASE_INCALL_REC_UPLINK;
@@ -327,6 +333,7 @@
if (ret == -ENOSYS) {
ret = start_call(adev, USECASE_VOICE_CALL);
}
+ adev->voice.in_call = true;
return ret;
}
@@ -335,6 +342,7 @@
{
int ret = 0;
+ adev->voice.in_call = false;
ret = voice_extn_stop_call(adev);
if (ret == -ENOSYS) {
ret = stop_call(adev, USECASE_VOICE_CALL);
@@ -389,7 +397,7 @@
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_in_call(adev))
+ if (voice_is_call_state_active(adev))
voice_update_devices_for_all_voice_usecases(adev);
}
}
@@ -434,7 +442,7 @@
adev->voice.hac = false;
adev->voice.volume = 1.0f;
adev->voice.mic_mute = false;
- adev->voice.voice_device_set = false;
+ adev->voice.in_call = false;
for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
adev->voice.session[i].pcm_rx = NULL;
adev->voice.session[i].pcm_tx = NULL;
diff --git a/hal/voice.h b/hal/voice.h
index 11f3be0..761e0c9 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -58,7 +58,7 @@
bool hac;
bool mic_mute;
float volume;
- bool voice_device_set;
+ bool in_call;
};
enum {
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 05c5fcb..6ce6df0 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -69,7 +69,7 @@
extern int start_call(struct audio_device *adev, audio_usecase_t usecase_id);
extern int stop_call(struct audio_device *adev, audio_usecase_t usecase_id);
-int voice_extn_is_in_call(struct audio_device *adev, bool *in_call);
+int voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active);
static bool is_valid_call_state(int call_state)
{
@@ -149,7 +149,6 @@
struct voice_session *session = NULL;
int fd = 0;
int ret = 0;
- bool is_in_call = false;
ALOGD("%s: enter:", __func__);
@@ -209,10 +208,6 @@
ALOGE("%s: voice_end_call() failed for usecase: %d\n",
__func__, usecase_id);
} else {
- voice_extn_is_in_call(adev, &is_in_call);
- if (!is_in_call) {
- adev->voice.voice_device_set = false;
- }
session->state.current = session->state.new;
}
break;
@@ -284,8 +279,7 @@
{
struct voice_session *session = NULL;
int i = 0;
- bool is_in_call;
- int no_of_calls_active = 0;
+ bool is_call_active;
for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
if (vsid == adev->voice.session[i].vsid) {
@@ -294,21 +288,16 @@
}
}
- for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
- if (CALL_INACTIVE != adev->voice.session[i].state.current)
- no_of_calls_active++;
- }
-
if (session) {
session->state.new = call_state;
- voice_extn_is_in_call(adev, &is_in_call);
- ALOGD("%s is_in_call:%d voice_device_set:%d, mode:%d\n",
- __func__, is_in_call, adev->voice.voice_device_set, adev->mode);
+ voice_extn_is_call_state_active(adev, &is_call_active);
+ ALOGD("%s is_call_active:%d in_call:%d, mode:%d\n",
+ __func__, is_call_active, adev->voice.in_call, adev->mode);
/* Dont start voice call before device routing for voice usescases has
* occured, otherwise voice calls will be started unintendedly on
* speaker.
*/
- if (is_in_call || adev->voice.voice_device_set) {
+ if (is_call_active || adev->voice.in_call) {
/* 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.
@@ -330,16 +319,16 @@
return 0;
}
-int voice_extn_is_in_call(struct audio_device *adev, bool *in_call)
+int voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active)
{
struct voice_session *session = NULL;
int i = 0;
- *in_call = false;
+ *is_call_active = false;
for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
session = &adev->voice.session[i];
if(session->state.current != CALL_INACTIVE){
- *in_call = true;
+ *is_call_active = true;
break;
}
}
@@ -411,7 +400,6 @@
* udpated.
*/
ALOGV("%s: enter:", __func__);
- adev->voice.voice_device_set = true;
return update_calls(adev);
}
@@ -458,6 +446,7 @@
err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_CALL_STATE, &value);
if (err >= 0) {
call_state = value;
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_CALL_STATE);
} else {
ALOGE("%s: call_state key not found", __func__);
ret = -EINVAL;
diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h
index fcc16ec..8689c9c 100644
--- a/hal/voice_extn/voice_extn.h
+++ b/hal/voice_extn/voice_extn.h
@@ -29,10 +29,11 @@
void voice_extn_get_parameters(const struct audio_device *adev,
struct str_parms *query,
struct str_parms *reply);
-int voice_extn_is_in_call(struct audio_device *adev, bool *in_call);
int voice_extn_is_in_call_rec_stream(struct stream_in *in, bool *in_call_rec);
int voice_extn_get_active_session_id(struct audio_device *adev,
uint32_t *session_id);
+int voice_extn_is_call_state_active(struct audio_device *adev,
+ bool *is_call_active);
#else
static int voice_extn_start_call(struct audio_device *adev __unused)
{
@@ -67,7 +68,8 @@
{
}
-static int voice_extn_is_in_call(struct audio_device *adev __unused, bool *in_call __unused)
+static int voice_extn_is_call_state_active(struct audio_device *adev __unused,
+ bool *is_call_active __unused)
{
return -ENOSYS;
}