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

Commit cdae3cef authored by Pavlin Radoslavov's avatar Pavlin Radoslavov Committed by android-build-merger
Browse files

Explicitly stop streaming when switching streaming to another device

am: e3d7fa1c

Change-Id: I7e4483090fb78525daebc60f251621c576a8e43d
parents 88368aeb e3d7fa1c
Loading
Loading
Loading
Loading
+77 −25
Original line number Diff line number Diff line
@@ -294,6 +294,9 @@ static void bta_av_save_addr(tBTA_AV_SCB* p_scb, const RawAddress& bd_addr) {
 *
 ******************************************************************************/
static void notify_start_failed(tBTA_AV_SCB* p_scb) {
  LOG_ERROR(LOG_TAG, "%s: peer %s role:0x%x channel:%d handle:0x%x", __func__,
            p_scb->PeerAddress().ToString().c_str(), p_scb->role, p_scb->chnl,
            p_scb->hndl);
  tBTA_AV_START start;
  /* if start failed, clear role */
  p_scb->role &= ~BTA_AV_ROLE_START_INT;
@@ -675,7 +678,8 @@ void bta_av_switch_role(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
  bool initiator = false;

  APPL_TRACE_DEBUG("%s: q_tag:%d, wait:0x%x, role:0x%x", __func__, p_scb->q_tag,
  APPL_TRACE_DEBUG("%s: peer %s q_tag:%d, wait:0x%x, role:0x%x", __func__,
                   p_scb->PeerAddress().ToString().c_str(), p_scb->q_tag,
                   p_scb->wait, p_scb->role);
  if (p_scb->role & BTA_AV_ROLE_START_INT) initiator = true;

@@ -726,12 +730,14 @@ void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
      }
    } else {
      APPL_TRACE_WARNING(
          "%s: unexpected role switch event: q_tag = %d wait = %d", __func__,
          p_scb->q_tag, p_scb->wait);
          "%s: peer %s unexpected role switch event: q_tag = %d wait = 0x%x",
          __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->q_tag,
          p_scb->wait);
    }
  }

  APPL_TRACE_DEBUG("%s: wait:0x%x, role:0x%x", __func__, p_scb->wait,
  APPL_TRACE_DEBUG("%s: peer %s wait:0x%x, role:0x%x", __func__,
                   p_scb->PeerAddress().ToString().c_str(), p_scb->wait,
                   p_scb->role);
}

@@ -886,7 +892,8 @@ void bta_av_cleanup(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
  tBTA_AV_CONN_CHG msg;
  uint8_t role = BTA_AV_ROLE_AD_INT;

  APPL_TRACE_DEBUG("%s", __func__);
  LOG_INFO(LOG_TAG, "%s peer %s", __func__,
           p_scb->PeerAddress().ToString().c_str());

  /* free any buffers */
  p_scb->sdp_discovery_started = false;
@@ -1830,8 +1837,11 @@ void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
  uint8_t clear_policy = 0;
  uint8_t cur_role;

  APPL_TRACE_DEBUG("%s: sco_occupied:%d, role:0x%x, started:%d", __func__,
                   bta_av_cb.sco_occupied, p_scb->role, p_scb->started);
  LOG_INFO(LOG_TAG,
           "%s: peer %s sco_occupied:%s role:0x%x started:%s wait:0x%x",
           __func__, p_scb->PeerAddress().ToString().c_str(),
           logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role,
           logbool(p_scb->started).c_str(), p_scb->wait);
  if (bta_av_cb.sco_occupied) {
    bta_av_start_failed(p_scb, p_data);
    return;
@@ -1847,23 +1857,50 @@ void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {

  bta_sys_clear_policy(BTA_ID_AV, clear_policy, p_scb->PeerAddress());

  if ((!p_scb->started) && ((p_scb->role & BTA_AV_ROLE_START_INT) == 0)) {
    p_scb->role |= BTA_AV_ROLE_START_INT;
    bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());

    AVDT_StartReq(&p_scb->avdt_handle, 1);
  } else if (p_scb->started) {
  if (p_scb->started) {
    p_scb->role |= BTA_AV_ROLE_START_INT;
    if (p_scb->wait == 0) {
    if (p_scb->wait != 0) {
      LOG_WARN(
          LOG_TAG,
          "%s: peer %s start stream request ignored: "
          "already waiting: sco_occupied:%s role:0x%x started:%s wait:0x%x",
          __func__, p_scb->PeerAddress().ToString().c_str(),
          logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role,
          logbool(p_scb->started).c_str(), p_scb->wait);
      return;
    }
    if (p_scb->role & BTA_AV_ROLE_SUSPEND) {
      notify_start_failed(p_scb);
    } else {
      bta_av_start_ok(p_scb, NULL);
    }
    return;
  }

  if ((p_scb->role & BTA_AV_ROLE_START_INT) != 0) {
    LOG_WARN(
        LOG_TAG,
        "%s: peer %s start stream request ignored: "
        "already initiated: sco_occupied:%s role:0x%x started:%s wait:0x%x",
        __func__, p_scb->PeerAddress().ToString().c_str(),
        logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role,
        logbool(p_scb->started).c_str(), p_scb->wait);
    return;
  }
  APPL_TRACE_DEBUG("%s: started %d role:0x%x", __func__, p_scb->started,
                   p_scb->role);

  p_scb->role |= BTA_AV_ROLE_START_INT;
  bta_sys_busy(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress());
  uint16_t result = AVDT_StartReq(&p_scb->avdt_handle, 1);
  if (result != AVDT_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: AVDT_StartReq failed for peer %s result:%d",
              __func__, p_scb->PeerAddress().ToString().c_str(), result);
  }
  LOG_INFO(LOG_TAG,
           "%s: peer %s start requested: sco_occupied:%s role:0x%x "
           "started:%s wait:0x%x",
           __func__, p_scb->PeerAddress().ToString().c_str(),
           logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role,
           logbool(p_scb->started).c_str(), p_scb->wait);
}

/*******************************************************************************
@@ -1924,7 +1961,8 @@ void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
  suspend_rsp.hndl = p_scb->hndl;

  if (p_data && p_data->api_stop.suspend) {
    APPL_TRACE_DEBUG("%s: suspending: %d, sup:%d", __func__, start,
    APPL_TRACE_DEBUG("%s: peer %s suspending: %d, sup:%d", __func__,
                     p_scb->PeerAddress().ToString().c_str(), start,
                     p_scb->suspend_sup);
    if ((start) && (p_scb->suspend_sup)) {
      sus_evt = false;
@@ -2190,9 +2228,9 @@ void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
  uint8_t cur_role;
  uint8_t local_tsep = p_scb->seps[p_scb->sep_idx].tsep;

  APPL_TRACE_DEBUG("%s: peer %s handle:%d wait:0x%x role:0x%x local_tsep:%d",
                   __func__, p_scb->PeerAddress().ToString().c_str(),
                   p_scb->hndl, p_scb->wait, p_scb->role, local_tsep);
  LOG_INFO(LOG_TAG, "%s: peer %s handle:%d wait:0x%x role:0x%x local_tsep:%d",
           __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl,
           p_scb->wait, p_scb->role, local_tsep);

  p_scb->started = true;

@@ -2870,6 +2908,12 @@ void bta_av_security_rej(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
 ******************************************************************************/
void bta_av_chk_2nd_start(tBTA_AV_SCB* p_scb,
                          UNUSED_ATTR tBTA_AV_DATA* p_data) {
  LOG_INFO(LOG_TAG,
           "%s: peer %s channel:%d bta_av_cb.audio_open_cnt:%d role:0x%x "
           "features:0x%x",
           __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->chnl,
           bta_av_cb.audio_open_cnt, p_scb->role, bta_av_cb.features);

  if ((p_scb->chnl == BTA_AV_CHNL_AUDIO) && (bta_av_cb.audio_open_cnt >= 2) &&
      (((p_scb->role & BTA_AV_ROLE_AD_ACP) == 0) ||  // Outgoing connection or
       (bta_av_cb.features & BTA_AV_FEAT_ACP_START))) {  // Auto-starting option
@@ -2880,10 +2924,18 @@ void bta_av_chk_2nd_start(tBTA_AV_SCB* p_scb,
      bool new_started = false;
      for (int i = 0; i < BTA_AV_NUM_STRS; i++) {
        tBTA_AV_SCB* p_scbi = bta_av_cb.p_scb[i];
        if (p_scb == p_scbi) {
          continue;
        }
        if (p_scbi && p_scbi->chnl == BTA_AV_CHNL_AUDIO && p_scbi->co_started) {
          if (!new_started) {
            // Start the new stream
            new_started = true;
            LOG_INFO(LOG_TAG,
                     "%s: starting new stream for peer %s because peer %s "
                     "already started",
                     __func__, p_scb->PeerAddress().ToString().c_str(),
                     p_scbi->PeerAddress().ToString().c_str());
            bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
          }
          // May need to update the flush timeout of this already started stream
+3 −2
Original line number Diff line number Diff line
@@ -1075,8 +1075,9 @@ static uint8_t bta_av_get_shdl(tBTA_AV_SCB* p_scb) {
void bta_av_stream_chg(tBTA_AV_SCB* p_scb, bool started) {
  uint8_t started_msk = BTA_AV_HNDL_TO_MSK(p_scb->hdi);

  APPL_TRACE_DEBUG("%s: started:%d started_msk:x%x", __func__, started,
                   started_msk);
  APPL_TRACE_DEBUG("%s: peer %s started:%s started_msk:0x%x", __func__,
                   p_scb->PeerAddress().ToString().c_str(),
                   logbool(started).c_str(), started_msk);

  if (started) {
    bta_av_cb.audio_streams |= started_msk;
+19 −4
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
 *
 ******************************************************************************/

#define LOG_TAG "bt_bta_av"

#include <base/logging.h>

#include "bt_target.h"
@@ -36,6 +38,7 @@
#include "bta_sys.h"

#include "osi/include/allocator.h"
#include "osi/include/log.h"

/*****************************************************************************
 *  Constants
@@ -153,9 +156,9 @@ void BTA_AvDeregister(tBTA_AV_HNDL hndl) {
 ******************************************************************************/
void BTA_AvOpen(const RawAddress& bd_addr, tBTA_AV_HNDL handle, bool use_rc,
                tBTA_SEC sec_mask, uint16_t uuid) {
  APPL_TRACE_DEBUG("%s: peer %s handle:0x%x use_rc=%s sec_mask=0x%x uuid=0x%x",
  LOG_INFO(LOG_TAG, "%s: peer %s handle:0x%x use_rc=%s sec_mask=0x%x uuid=0x%x",
           __func__, bd_addr.ToString().c_str(), handle,
                   (use_rc) ? "true" : "false", sec_mask, uuid)
           (use_rc) ? "true" : "false", sec_mask, uuid);

  tBTA_AV_API_OPEN* p_buf =
      (tBTA_AV_API_OPEN*)osi_malloc(sizeof(tBTA_AV_API_OPEN));
@@ -181,7 +184,7 @@ void BTA_AvOpen(const RawAddress& bd_addr, tBTA_AV_HNDL handle, bool use_rc,
 *
 ******************************************************************************/
void BTA_AvClose(tBTA_AV_HNDL handle) {
  APPL_TRACE_DEBUG("%s: handle:0x%x", __func__, handle);
  LOG_INFO(LOG_TAG, "%s: handle:0x%x", __func__, handle);

  BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR));

@@ -201,6 +204,8 @@ void BTA_AvClose(tBTA_AV_HNDL handle) {
 *
 ******************************************************************************/
void BTA_AvDisconnect(const RawAddress& bd_addr) {
  LOG_INFO(LOG_TAG, "%s: peer %s", __func__, bd_addr.ToString().c_str());

  tBTA_AV_API_DISCNT* p_buf =
      (tBTA_AV_API_DISCNT*)osi_malloc(sizeof(tBTA_AV_API_DISCNT));

@@ -220,6 +225,8 @@ void BTA_AvDisconnect(const RawAddress& bd_addr) {
 *
 ******************************************************************************/
void BTA_AvStart(tBTA_AV_HNDL handle) {
  LOG_INFO(LOG_TAG, "%s: handle=%d", __func__, handle);

  BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR));

  p_buf->event = BTA_AV_API_START_EVT;
@@ -238,6 +245,8 @@ void BTA_AvStart(tBTA_AV_HNDL handle) {
 *
 ******************************************************************************/
void BTA_AvOffloadStart(tBTA_AV_HNDL hndl) {
  LOG_INFO(LOG_TAG, "%s: handle=%d", __func__, hndl);

  BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR));

  p_buf->event = BTA_AV_API_OFFLOAD_START_EVT;
@@ -278,6 +287,9 @@ void BTA_AvOffloadStartRsp(tBTA_AV_HNDL hndl, tBTA_AV_STATUS status) {
 *
 ******************************************************************************/
void BTA_AvStop(tBTA_AV_HNDL handle, bool suspend) {
  LOG_INFO(LOG_TAG, "%s: handle=%d suspend=%s", __func__, handle,
           logbool(suspend).c_str());

  tBTA_AV_API_STOP* p_buf =
      (tBTA_AV_API_STOP*)osi_malloc(sizeof(tBTA_AV_API_STOP));

@@ -306,6 +318,9 @@ void BTA_AvStop(tBTA_AV_HNDL handle, bool suspend) {
void BTA_AvReconfig(tBTA_AV_HNDL hndl, bool suspend, uint8_t sep_info_idx,
                    uint8_t* p_codec_info, uint8_t num_protect,
                    const uint8_t* p_protect_info) {
  LOG_INFO(LOG_TAG, "%s: handle=%d suspend=%s sep_info_idx=%d", __func__, hndl,
           logbool(suspend).c_str(), sep_info_idx);

  tBTA_AV_API_RCFG* p_buf =
      (tBTA_AV_API_RCFG*)osi_malloc(sizeof(tBTA_AV_API_RCFG) + num_protect);

+18 −6
Original line number Diff line number Diff line
@@ -839,6 +839,13 @@ bool bta_av_chk_start(tBTA_AV_SCB* p_scb) {
      }
    }
  }

  LOG_INFO(LOG_TAG,
           "%s: peer %s channel:%d bta_av_cb.audio_open_cnt:%d role:0x%x "
           "features:0x%x start:%s",
           __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->chnl,
           bta_av_cb.audio_open_cnt, p_scb->role, bta_av_cb.features,
           logbool(start).c_str());
  return start;
}

@@ -1078,10 +1085,11 @@ bool bta_av_link_role_ok(tBTA_AV_SCB* p_scb, uint8_t bits) {
  bool is_ok = true;

  if (BTM_GetRole(p_scb->PeerAddress(), &role) == BTM_SUCCESS) {
    LOG_INFO(LOG_TAG,
             "%s: hndl:x%x role:%d conn_audio:x%x bits:%d features:x%x",
             __func__, p_scb->hndl, role, bta_av_cb.conn_audio, bits,
             bta_av_cb.features);
    LOG_INFO(
        LOG_TAG,
        "%s: peer %s hndl:0x%x role:%d conn_audio:0x%x bits:%d features:0x%x",
        __func__, p_scb->PeerAddress().ToString().c_str(), p_scb->hndl, role,
        bta_av_cb.conn_audio, bits, bta_av_cb.features);
    if (BTM_ROLE_MASTER != role &&
        (A2DP_BitsSet(bta_av_cb.conn_audio) > bits ||
         (bta_av_cb.features & BTA_AV_FEAT_MASTER))) {
@@ -1089,9 +1097,13 @@ bool bta_av_link_role_ok(tBTA_AV_SCB* p_scb, uint8_t bits) {
        bta_sys_clear_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH,
                             p_scb->PeerAddress());

      if (BTM_CMD_STARTED !=
          BTM_SwitchRole(p_scb->PeerAddress(), BTM_ROLE_MASTER, NULL)) {
      tBTM_STATUS status =
          BTM_SwitchRole(p_scb->PeerAddress(), BTM_ROLE_MASTER, NULL);
      if (status != BTM_CMD_STARTED) {
        /* can not switch role on SCB - start the timer on SCB */
        LOG_ERROR(LOG_TAG,
                  "%s: peer %s BTM_SwitchRole(BTM_ROLE_MASTER) error: %d",
                  __func__, p_scb->PeerAddress().ToString().c_str(), status);
      }
      is_ok = false;
      p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_START;
+4 −2
Original line number Diff line number Diff line
@@ -2659,8 +2659,10 @@ static void handle_role_change(const RawAddress& bd_addr, uint8_t new_role,

  tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
  if (!p_dev) return;
  APPL_TRACE_DEBUG("role chg info:x%x new_role:%d dev count:%d", p_dev->info,
                   new_role, bta_dm_cb.device_list.count);
  LOG_INFO(LOG_TAG,
           "%s: peer %s info:0x%x new_role:0x%x dev count:%d hci_status=%d",
           __func__, bd_addr.ToString().c_str(), p_dev->info, new_role,
           bta_dm_cb.device_list.count, hci_status);
  if (p_dev->info & BTA_DM_DI_AV_ACTIVE) {
    bool need_policy_change = false;

Loading