Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f85f6a2f authored by Vidyakumar Athota's avatar Vidyakumar Athota Committed by Divya Narayanan Poojary
Browse files

hal: fix voice call device routing issue

adev->voice_device_set flag is to indicate voice call
device routing update from policymanager to HAL. It is
set to true in voice_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_stop_call instead of update_calls(). Rename
voice_device_set flag to in_call for readability.

Change-Id: Ie07105671f254899890bdb4c0635c7dc1f55dbff
parent ed32fc75
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -651,7 +651,7 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
         * usecase. This is to avoid switching devices for voice call when
         * check_usecases_codec_backend() is called below.
         */
        if (voice_is_in_call(adev)) {
        if (adev->voice.in_call && adev->mode == AUDIO_MODE_IN_CALL) {
            vc_usecase = get_usecase_from_list(adev,
                                               get_voice_usecase_id_from_list(adev));
            if ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
@@ -1507,13 +1507,6 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
            val = AUDIO_DEVICE_OUT_SPEAKER;
        }

        if ((adev->mode == AUDIO_MODE_NORMAL) &&
                 voice_is_in_call(adev) &&
                 output_drives_call(adev, out)) {
            ret = voice_stop_call(adev);
            adev->current_call_output = NULL;
        }

        /*
         * select_devices() call below switches all the usecases on the same
         * backend to the new device. Refer to check_usecases_codec_backend() in
@@ -1541,12 +1534,18 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
            if ((adev->mode == AUDIO_MODE_IN_CALL) &&
                    output_drives_call(adev, out)) {
                adev->current_call_output = out;
                if (!voice_is_in_call(adev))
                if (!adev->voice.in_call)
                    ret = voice_start_call(adev);
                else
                    voice_update_devices_for_all_voice_usecases(adev);
             }
        }

        if ((adev->mode == AUDIO_MODE_NORMAL) &&
                adev->voice.in_call &&
                output_drives_call(adev, out)) {
            ret = voice_stop_call(adev);
            adev->current_call_output = NULL;
        }

        pthread_mutex_unlock(&adev->lock);
+12 −9
Original line number Diff line number Diff line
@@ -167,26 +167,27 @@ int start_call(struct audio_device *adev, audio_usecase_t usecase_id)
    }

    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_rec_stream(struct stream_in *in)
@@ -222,7 +223,7 @@ int voice_check_and_set_incall_rec_usecase(struct audio_device *adev,
    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:
            if (audio_extn_compr_cap_enabled() &&
@@ -348,6 +349,7 @@ int voice_start_call(struct audio_device *adev)
    if (ret == -ENOSYS) {
        ret = start_call(adev, USECASE_VOICE_CALL);
    }
    adev->voice.in_call = true;

    return ret;
}
@@ -356,6 +358,7 @@ int voice_stop_call(struct audio_device *adev)
{
    int ret = 0;

    adev->voice.in_call = false;
    ret = voice_extn_stop_call(adev);
    if (ret == -ENOSYS) {
        ret = stop_call(adev, USECASE_VOICE_CALL);
@@ -409,7 +412,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_in_call(adev))
            if (voice_is_call_state_active(adev))
               voice_update_devices_for_all_voice_usecases(adev);
        }
    }
@@ -438,7 +441,7 @@ void voice_init(struct audio_device *adev)
    adev->voice.tty_mode = TTY_MODE_OFF;
    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;
+3 −2
Original line number Diff line number Diff line
@@ -60,7 +60,8 @@ struct voice {
    int tty_mode;
    bool mic_mute;
    float volume;
    bool voice_device_set;
    bool is_in_call;
    bool in_call;
};

enum {
@@ -76,8 +77,8 @@ int voice_set_parameters(struct audio_device *adev, struct str_parms *parms);
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(struct audio_device *adev);
bool voice_is_in_call_rec_stream(struct stream_in *in);
bool voice_is_call_state_active(struct audio_device *adev);
int voice_set_mic_mute(struct audio_device *dev, bool state);
bool voice_get_mic_mute(struct audio_device *dev);
int voice_set_volume(struct audio_device *adev, float volume);
+10 −27
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ struct pcm_config pcm_config_incall_music = {

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)
{
@@ -152,7 +152,6 @@ static int update_calls(struct audio_device *adev)
    struct voice_session *session = NULL;
    int fd = 0;
    int ret = 0;
    bool is_in_call = false;

    ALOGD("%s: enter:", __func__);

@@ -214,10 +213,6 @@ static int update_calls(struct audio_device *adev)
                    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;
@@ -293,8 +288,7 @@ static int update_call_states(struct audio_device *adev,
{
    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) {
@@ -303,27 +297,16 @@ static int update_call_states(struct audio_device *adev,
        }
    }

    for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
        if (CALL_INACTIVE != adev->voice.session[i].state.current)
            no_of_calls_active++;
    }

    /* When there is only one call active, wait for audio policy manager to set
     * the mode to AUDIO_MODE_NORMAL and trigger routing to end the last call.
     */
    if (no_of_calls_active == 1 && call_state == CALL_INACTIVE)
        return 0;

    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.
@@ -345,16 +328,16 @@ int voice_extn_get_active_session_id(struct audio_device *adev,
    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;
        }
    }
@@ -426,7 +409,6 @@ int voice_extn_start_call(struct audio_device *adev)
     * udpated.
     */
    ALOGV("%s: enter:", __func__);
    adev->voice.voice_device_set = true;
    return update_calls(adev);
}

@@ -473,6 +455,7 @@ int voice_extn_set_parameters(struct audio_device *adev,
        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;
+4 −2
Original line number Diff line number Diff line
@@ -32,8 +32,9 @@ int voice_extn_set_parameters(struct audio_device *adev,
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_is_call_state_active(struct audio_device *adev,
                                    bool *is_call_active);
int voice_extn_get_active_session_id(struct audio_device *adev,
                                     uint32_t *session_id);
void voice_extn_in_get_parameters(struct stream_in *in,
@@ -76,7 +77,8 @@ static void voice_extn_get_parameters(const struct audio_device *adev __unused,
{
}

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,
                                           bool *is_call_active)
{
    return -ENOSYS;
}