From f2cf5ebc7f29ac8103519bf6895ceb3bf02036f7 Mon Sep 17 00:00:00 2001 From: Cheney Ni Date: Wed, 19 Feb 2020 17:41:59 +0800 Subject: [PATCH] A2DP: Wait for previous AVDTP instance to be clean up before re-enabling MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Because more connections spend more time to disconnect, the stack may still be busy at disabling AVDTP, if we re-enable the A2dpService quickly. This change will defer BTA_AV_API_ENABLE and BTA_AV_API_REG events if the stack is still disabling the previous instance, so gives the stack half more seconds to handle its previous task. Bug: 135655859 Test: manually Change-Id: I8e700ce195aa634819ea1ad8cf5892cc35669e10 Merged-In: I8e700ce195aa634819ea1ad8cf5892cc35669e10 (cherry picked from commit 21fe257db23887b3000a6c8d38ee339fcccbdc2b) --- bta/av/bta_av_int.h | 5 +++++ bta/av/bta_av_main.cc | 28 ++++++++++++++++++++++++++-- bta/sys/bta_sys.h | 1 + bta/sys/bta_sys_main.cc | 8 ++++++++ stack/btu/btu_task.cc | 11 +++++++++++ stack/include/btu.h | 3 +++ 6 files changed, 54 insertions(+), 2 deletions(-) diff --git a/bta/av/bta_av_int.h b/bta/av/bta_av_int.h index 9c8f3dd31..3925e55c5 100644 --- a/bta/av/bta_av_int.h +++ b/bta/av/bta_av_int.h @@ -603,6 +603,7 @@ typedef struct { tBTA_SEC sec_mask; /* security mask */ tBTA_AV_HNDL handle; /* the handle for SDP activity */ bool disabling; /* true if api disabled called */ + uint8_t enabling_attempts; // counter to wait for previous disabling uint8_t disc; /* (hdi+1) or (rc_handle|BTA_AV_CHNL_MSK) if p_disc_db is in use */ uint8_t state; /* state machine state */ @@ -617,6 +618,10 @@ typedef struct { uint8_t audio_streams; /* handle mask of streaming audio channels */ } tBTA_AV_CB; +// total attempts are half seconds +constexpr uint32_t kEnablingAttemptsIntervalMs = 100; +constexpr uint8_t kEnablingAttemptsCountMaximum = 5; + // A2DP offload VSC parameters class tBT_A2DP_OFFLOAD { public: diff --git a/bta/av/bta_av_main.cc b/bta/av/bta_av_main.cc index 44da99e61..61e4b4e89 100644 --- a/bta/av/bta_av_main.cc +++ b/bta/av/bta_av_main.cc @@ -219,8 +219,17 @@ static const char* bta_av_st_code(uint8_t state); ******************************************************************************/ static void bta_av_api_enable(tBTA_AV_DATA* p_data) { if (bta_av_cb.disabling) { - APPL_TRACE_WARNING("%s: previous (reg_audio=%#x) is still disabling", - __func__, bta_av_cb.reg_audio); + APPL_TRACE_WARNING( + "%s: previous (reg_audio=%#x) is still disabling (attempts=%d)", + __func__, bta_av_cb.reg_audio, bta_av_cb.enabling_attempts); + if (++bta_av_cb.enabling_attempts <= kEnablingAttemptsCountMaximum) { + tBTA_AV_API_ENABLE* p_buf = + (tBTA_AV_API_ENABLE*)osi_malloc(sizeof(tBTA_AV_API_ENABLE)); + memcpy(p_buf, &p_data->api_enable, sizeof(tBTA_AV_API_ENABLE)); + bta_sys_sendmsg_delayed(p_buf, base::TimeDelta::FromMilliseconds( + kEnablingAttemptsIntervalMs)); + return; + } if (bta_av_cb.sdp_a2dp_handle) { SDP_DeleteRecord(bta_av_cb.sdp_a2dp_handle); bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SOURCE); @@ -495,6 +504,21 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { char* p_service_name; tBTA_UTL_COD cod; + if (bta_av_cb.disabling || + (bta_av_cb.features == 0 && bta_av_cb.sec_mask == 0)) { + APPL_TRACE_WARNING( + "%s: AV instance (features=%#x, sec_mask=%#x, reg_audio=%#x) is not " + "ready for app_id %d", + __func__, bta_av_cb.features, bta_av_cb.sec_mask, bta_av_cb.reg_audio, + p_data->api_reg.app_id); + tBTA_AV_API_REG* p_buf = + (tBTA_AV_API_REG*)osi_malloc(sizeof(tBTA_AV_API_REG)); + memcpy(p_buf, &p_data->api_reg, sizeof(tBTA_AV_API_REG)); + bta_sys_sendmsg_delayed( + p_buf, base::TimeDelta::FromMilliseconds(kEnablingAttemptsIntervalMs)); + return; + } + avdtp_stream_config.Reset(); registr.status = BTA_AV_FAIL_RESOURCES; diff --git a/bta/sys/bta_sys.h b/bta/sys/bta_sys.h index 29e9a3fda..3ceefc112 100644 --- a/bta/sys/bta_sys.h +++ b/bta/sys/bta_sys.h @@ -222,6 +222,7 @@ extern void bta_sys_deregister(uint8_t id); extern bool bta_sys_is_register(uint8_t id); extern uint16_t bta_sys_get_sys_features(void); extern void bta_sys_sendmsg(void* p_msg); +extern void bta_sys_sendmsg_delayed(void* p_msg, const base::TimeDelta& delay); extern void bta_sys_start_timer(alarm_t* alarm, uint64_t interval_ms, uint16_t event, uint16_t layer_specific); extern void bta_sys_disable(tBTA_SYS_HW_MODULE module); diff --git a/bta/sys/bta_sys_main.cc b/bta/sys/bta_sys_main.cc index 1036e7444..e81320d72 100644 --- a/bta/sys/bta_sys_main.cc +++ b/bta/sys/bta_sys_main.cc @@ -532,6 +532,14 @@ void bta_sys_sendmsg(void* p_msg) { } } +void bta_sys_sendmsg_delayed(void* p_msg, const base::TimeDelta& delay) { + if (do_in_main_thread_delayed( + FROM_HERE, base::Bind(&bta_sys_event, static_cast(p_msg)), + delay) != BT_STATUS_SUCCESS) { + LOG(ERROR) << __func__ << ": do_in_main_thread_delayed failed"; + } +} + /******************************************************************************* * * Function bta_sys_start_timer diff --git a/stack/btu/btu_task.cc b/stack/btu/btu_task.cc index 8838206b0..06d06d1b4 100644 --- a/stack/btu/btu_task.cc +++ b/stack/btu/btu_task.cc @@ -97,6 +97,17 @@ bt_status_t do_in_main_thread(const base::Location& from_here, return BT_STATUS_SUCCESS; } +bt_status_t do_in_main_thread_delayed(const base::Location& from_here, + base::OnceClosure task, + const base::TimeDelta& delay) { + if (!get_main_message_loop()->task_runner()->PostDelayedTask( + from_here, std::move(task), delay)) { + LOG(ERROR) << __func__ << ": failed from " << from_here.ToString(); + return BT_STATUS_FAIL; + } + return BT_STATUS_SUCCESS; +} + void btu_task_start_up(UNUSED_ATTR void* context) { LOG(INFO) << "Bluetooth chip preload is complete"; diff --git a/stack/include/btu.h b/stack/include/btu.h index 77d50518b..03fe2a196 100644 --- a/stack/include/btu.h +++ b/stack/include/btu.h @@ -62,6 +62,9 @@ bluetooth::common::MessageLoopThread* get_main_thread(); base::MessageLoop* get_main_message_loop(); bt_status_t do_in_main_thread(const base::Location& from_here, base::OnceClosure task); +bt_status_t do_in_main_thread_delayed(const base::Location& from_here, + base::OnceClosure task, + const base::TimeDelta& delay); void BTU_StartUp(void); void BTU_ShutDown(void); -- 2.11.0