Loading hal/audio_extn/a2dp.c +23 −19 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; Loading Loading @@ -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"); } } Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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; Loading hal/audio_extn/audio_extn.h +2 −2 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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 Loading hal/audio_hw.c +33 −10 Original line number Diff line number Diff line Loading @@ -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)", Loading Loading @@ -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 Loading Loading
hal/audio_extn/a2dp.c +23 −19 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; Loading Loading @@ -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"); } } Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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; Loading
hal/audio_extn/audio_extn.h +2 −2 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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 Loading
hal/audio_hw.c +33 −10 Original line number Diff line number Diff line Loading @@ -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)", Loading Loading @@ -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 Loading