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

Commit ffa09b7e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hal: Add a2dp state check for device routing" into audio-userspace.lnx.2.2.c2-dev

parents e5c22c4d f6589d1b
Loading
Loading
Loading
Loading
+23 −19
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ typedef void (*audio_handoff_triggered_t)(void);
typedef void (*clear_a2dpsuspend_flag_t)(void);
typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
                               audio_format_t *codec_type);
typedef int (*audio_check_a2dp_ready_t)(void);

enum A2DP_STATE {
    A2DP_STATE_CONNECTED,
@@ -102,6 +103,7 @@ struct a2dp_data {
    audio_handoff_triggered_t audio_handoff_triggered;
    clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
    audio_get_codec_config_t audio_get_codec_config;
    audio_check_a2dp_ready_t audio_check_a2dp_ready;
    enum A2DP_STATE bt_state;
    audio_format_t bt_encoder_format;
    uint32_t enc_sampling_rate;
@@ -244,6 +246,8 @@ static void open_a2dp_output()
                          dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
            a2dp.audio_stream_close = (audio_stream_close_t)
                          dlsym(a2dp.bt_lib_handle, "audio_stream_close");
            a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t)
                        dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
        }
    }

@@ -279,27 +283,17 @@ static int close_a2dp_output()
        ALOGE("a2dp handle is not identified, Ignoring close request");
        return -ENOSYS;
    }
    if ((a2dp.bt_state == A2DP_STATE_CONNECTED) &&
        (a2dp.bt_state == A2DP_STATE_STARTED) &&
        (a2dp.bt_state == A2DP_STATE_STOPPED)) {
    if (a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
        ALOGD("calling BT stream close");
        if(a2dp.audio_stream_close() == false)
            ALOGE("failed close a2dp control path from BT library");
    }
    a2dp.a2dp_started = false;
    a2dp.a2dp_total_active_session_request = 0;
    a2dp.a2dp_suspended = false;
    a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
    a2dp.enc_sampling_rate = 48000;
    a2dp.bt_state = A2DP_STATE_DISCONNECTED;
    } else {
        ALOGD("close a2dp called in improper state");
        a2dp.a2dp_started = false;
        a2dp.a2dp_total_active_session_request = 0;
        a2dp.a2dp_suspended = false;
        a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
        a2dp.enc_sampling_rate = 48000;
        a2dp.bt_state = A2DP_STATE_DISCONNECTED;
    }

    return 0;
}
@@ -631,7 +625,6 @@ int audio_extn_a2dp_start_playback()
        if (ret != 0 ) {
           ALOGE("BT controller start failed");
           a2dp.a2dp_started = false;
           ret = -ETIMEDOUT;
        } else {
           if(configure_a2dp_encoder_format() == true) {
                a2dp.a2dp_started = true;
@@ -692,7 +685,7 @@ int audio_extn_a2dp_stop_playback()
        return -ENOSYS;
    }

    if (a2dp.a2dp_started && (a2dp.a2dp_total_active_session_request > 0))
    if (a2dp.a2dp_total_active_session_request > 0)
        a2dp.a2dp_total_active_session_request--;

    if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
@@ -810,6 +803,17 @@ void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
        *bit_width = 16;
    *sample_rate = a2dp.enc_sampling_rate;
}

bool audio_extn_a2dp_is_ready()
{
    bool ret = false;

    if ((a2dp.is_a2dp_offload_supported) &&
        (a2dp.audio_check_a2dp_ready))
           ret = a2dp.audio_check_a2dp_ready();
    return ret;
}

void audio_extn_a2dp_init (void *adev)
{
  a2dp.adev = (struct audio_device*)adev;
+2 −2
Original line number Diff line number Diff line
@@ -206,7 +206,7 @@ bool audio_extn_usb_is_capture_supported();
#define audio_extn_a2dp_set_handoff_mode(is_on)          (0)
#define audio_extn_a2dp_get_apptype_params(sample_rate,bit_width)    (0)
#define audio_extn_a2dp_get_encoder_latency()            (0)

#define audio_extn_a2dp_is_ready()                       (0)
#else
void audio_extn_a2dp_init(void *adev);
int audio_extn_a2dp_start_playback();
@@ -217,7 +217,7 @@ void audio_extn_a2dp_set_handoff_mode(bool is_on);
void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
                                        uint32_t *bit_width);
uint32_t audio_extn_a2dp_get_encoder_latency();

bool audio_extn_a2dp_is_ready();
#endif

#ifndef SSR_ENABLED
+33 −10
Original line number Diff line number Diff line
@@ -2185,6 +2185,19 @@ int start_output_stream(struct stream_out *out)
        goto error_config;
    }

    if (out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
        if (!audio_extn_a2dp_is_ready()) {
            if (out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
                //combo usecase just by pass a2dp
                ALOGW("%s: A2DP profile is not ready, route it to speaker", __func__);
                out->devices = AUDIO_DEVICE_OUT_SPEAKER;
            } else {
                ALOGE("%s: A2DP profile is not ready, return error", __func__);
                ret = -EAGAIN;
                goto error_config;
            }
        }
    }
    out->pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
    if (out->pcm_device_id < 0) {
        ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)",
@@ -2647,17 +2660,27 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
                (val == AUDIO_DEVICE_NONE)) {
                val = AUDIO_DEVICE_OUT_SPEAKER;
        }
        /* To avoid a2dp to sco overlapping force route BT usecases
         * to speaker based on Phone state
        /* To avoid a2dp to sco overlapping / BT device improper state
         * check with BT lib about a2dp streaming support before routing
         */
        if ((((val & AUDIO_DEVICE_OUT_SPEAKER) &&
                  (val & AUDIO_DEVICE_OUT_ALL_A2DP)) ||
              ((adev->snd_dev_ref_cnt[SND_DEVICE_OUT_BT_A2DP] == 0) &&
                  (val & AUDIO_DEVICE_OUT_ALL_A2DP))) &&
            ((adev->mode == AUDIO_MODE_RINGTONE) ||
            (adev->mode == AUDIO_MODE_IN_CALL))) {
            ALOGD("Forcing a2dp routing to speaker for ring/call mode");
        if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
            if (!audio_extn_a2dp_is_ready()) {
                if (val & AUDIO_DEVICE_OUT_SPEAKER) {
                    //combo usecase just by pass a2dp
                    ALOGW("%s: A2DP profile is not ready,routing to speaker only", __func__);
                    val = AUDIO_DEVICE_OUT_SPEAKER;
                } else {
                    ALOGE("%s: A2DP profile is not ready,ignoring routing request", __func__);
                    /* update device to a2dp and don't route as BT returned error
                     * However it is still possible a2dp routing called because
                     * of current active device disconnection (like wired headset)
                     */
                    out->devices = val;
                    pthread_mutex_unlock(&out->lock);
                    pthread_mutex_unlock(&adev->lock);
                    goto error;
                }
            }
        }
        /*
         * select_devices() call below switches all the usecases on the same