OSDN Git Service

Disable sniff in link policy before a2dp streaming
authorTreehugger Robot <treehugger-gerrit@google.com>
Thu, 26 Aug 2021 03:11:18 +0000 (03:11 +0000)
committerRay Kuo <kuoray@google.com>
Thu, 9 Dec 2021 02:43:40 +0000 (02:43 +0000)
Bug: 205672705
Ignore-AOSP-First: It is in the AOSP.
Original change: https://android-review.googlesource.com/c/platform/system/bt/+/1788388

Change-Id: I8390acacfb25fddcbd475144e399b3b0c4408a07
(cherry picked from commit f74c025302d034f70f14d9dd85aee44b64a04f57)

bta/av/bta_av_aact.cc
stack/acl/btm_acl.cc
stack/include/acl_api.h

index 3a55d57..e6f28a3 100644 (file)
@@ -1807,16 +1807,6 @@ void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
     return;
   }
 
-  /* disallow role switch during streaming, only if we are the central role
-   * i.e. allow role switch, if we are peripheral.
-   * It would not hurt us, if the peer device wants us to be central */
-  tHCI_ROLE cur_role;
-  if ((BTM_GetRole(p_scb->PeerAddress(), &cur_role) == BTM_SUCCESS) &&
-      (cur_role == HCI_ROLE_CENTRAL)) {
-    BTM_block_role_switch_for(p_scb->PeerAddress());
-  }
-  BTM_block_sniff_mode_for(p_scb->PeerAddress());
-
   if (p_scb->started) {
     p_scb->role |= BTA_AV_ROLE_START_INT;
     if (p_scb->wait != 0) {
@@ -1848,6 +1838,18 @@ void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
 
   p_scb->role |= BTA_AV_ROLE_START_INT;
   bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
+  /* disallow role switch during streaming, only if we are the central role
+   * i.e. allow role switch, if we are peripheral.
+   * It would not hurt us, if the peer device wants us to be central
+   * disable sniff mode unconditionally during streaming */
+  tHCI_ROLE cur_role;
+  if ((BTM_GetRole(p_scb->PeerAddress(), &cur_role) == BTM_SUCCESS) &&
+      (cur_role == HCI_ROLE_CENTRAL)) {
+    BTM_block_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
+  } else {
+    BTM_block_sniff_mode_for(p_scb->PeerAddress());
+  }
+
   uint16_t result = AVDT_StartReq(&p_scb->avdt_handle, 1);
   if (result != AVDT_SUCCESS) {
     LOG_ERROR("%s: AVDT_StartReq failed for peer %s result:%d", __func__,
@@ -1883,8 +1885,7 @@ void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
       bta_av_cb.audio_open_cnt, p_data, start);
 
   bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
-  BTM_unblock_role_switch_for(p_scb->PeerAddress());
-  BTM_unblock_sniff_mode_for(p_scb->PeerAddress());
+  BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
 
   if (p_scb->co_started) {
     uint16_t handle = get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle(
@@ -2318,10 +2319,13 @@ void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
       /* If souce is the central role, disable role switch during streaming.
        * Otherwise allow role switch, if source is peripheral.
        * Because it would not hurt source, if the peer device wants source to be
-       * central */
+       * central.
+       * disable sniff mode unconditionally during streaming */
       if ((BTM_GetRole(p_scb->PeerAddress(), &cur_role) == BTM_SUCCESS) &&
           (cur_role == HCI_ROLE_CENTRAL)) {
-        BTM_block_role_switch_for(p_scb->PeerAddress());
+        BTM_block_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
+      } else {
+        BTM_block_sniff_mode_for(p_scb->PeerAddress());
       }
     }
 
@@ -2384,8 +2388,7 @@ void bta_av_start_failed(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
     notify_start_failed(p_scb);
   }
 
-  BTM_unblock_role_switch_for(p_scb->PeerAddress());
-  BTM_unblock_sniff_mode_for(p_scb->PeerAddress());
+  BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
   p_scb->sco_suspend = false;
 }
 
@@ -2407,8 +2410,7 @@ void bta_av_str_closed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
       __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
       p_scb->open_status, p_scb->chnl, p_scb->co_started);
 
-  BTM_unblock_role_switch_for(p_scb->PeerAddress());
-  BTM_unblock_sniff_mode_for(p_scb->PeerAddress());
+  BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
   if (bta_av_cb.audio_open_cnt <= 1) {
     BTM_default_unblock_role_switch();
   }
@@ -2512,8 +2514,7 @@ void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
   }
 
   bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
-  BTM_unblock_role_switch_for(p_scb->PeerAddress());
-  BTM_unblock_sniff_mode_for(p_scb->PeerAddress());
+  BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress());
 
   /* in case that we received suspend_ind, we may need to call co_stop here */
   if (p_scb->co_started) {
index 5cacb5a..4c7e066 100644 (file)
@@ -721,6 +721,16 @@ void BTM_block_role_switch_for(const RawAddress& peer_addr) {
   btm_toggle_policy_off_for(peer_addr, HCI_ENABLE_CENTRAL_PERIPHERAL_SWITCH);
 }
 
+void BTM_unblock_role_switch_and_sniff_mode_for(const RawAddress& peer_addr) {
+  btm_toggle_policy_on_for(
+      peer_addr, HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_CENTRAL_PERIPHERAL_SWITCH);
+}
+
+void BTM_block_role_switch_and_sniff_mode_for(const RawAddress& peer_addr) {
+  btm_toggle_policy_off_for(
+      peer_addr, HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_CENTRAL_PERIPHERAL_SWITCH);
+}
+
 void StackAclBtmAcl::btm_set_default_link_policy(tLINK_POLICY settings) {
   check_link_policy(&settings);
   btm_cb.acl_cb_.btm_def_link_policy = settings;
index b4829d8..d311ffd 100644 (file)
@@ -35,6 +35,8 @@ void BTM_unblock_sniff_mode_for(const RawAddress& peer_addr);
 void BTM_block_sniff_mode_for(const RawAddress& peer_addr);
 void BTM_unblock_role_switch_for(const RawAddress& peer_addr);
 void BTM_block_role_switch_for(const RawAddress& peer_addr);
+void BTM_unblock_role_switch_and_sniff_mode_for(const RawAddress& peer_addr);
+void BTM_block_role_switch_and_sniff_mode_for(const RawAddress& peer_addr);
 
 void BTM_default_unblock_role_switch();
 void BTM_default_block_role_switch();