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

Commit 8f902303 authored by Jack He's avatar Jack He Committed by Andre Eisenbach
Browse files

A2DP: Advance btif profile queue on OPENING->other_state transition

* Entering BTIF_AV_STATE_OPENING is only possible through
  BTIF_AV_CONNECT_REQ_EVT (initiated by us) OR
  BTA_AV_PENDING_EVT (initiated by remote)
  from BTIF_AV_STATE_IDLE
* If we go from BTIF_AV_CONNECT_REQ_EVT, we must have a pending
  connection request in btif_profile_queue that should be advanced when
  we quit BTIF_AV_STATE_OPENING state
* This CL adds a flag to indicate whether an AV connection is initiated
  by us and only advance queue when it is
* Also add queue advancement in BTA_AV_REJECT_EVT and BTA_AV_CLOSE_EVT

Bug: 67317954
Test: make
Change-Id: I16dc8ebf76c6edaacb1f7a4a44e604170ff9a8b0
parent d6e64421
Loading
Loading
Loading
Loading
+31 −12
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ typedef enum {
typedef struct {
  tBTA_AV_HNDL bta_handle;
  RawAddress peer_bda;
  bool self_initiated_connection;
  btif_sm_handle_t sm_handle;
  uint8_t flags;
  tBTA_AV_EDR edr;
@@ -98,7 +99,7 @@ typedef struct {
static btav_source_callbacks_t* bt_av_src_callbacks = NULL;
static btav_sink_callbacks_t* bt_av_sink_callbacks = NULL;
static btif_av_cb_t btif_av_cb = {
    0, {{0}}, 0, 0, 0, 0, std::vector<btav_a2dp_codec_config_t>()};
    0, {{0}}, false, 0, 0, 0, 0, std::vector<btav_a2dp_codec_config_t>()};
static alarm_t* av_open_on_rc_timer = NULL;

/* both interface and media task needs to be ready to alloc incoming request */
@@ -353,10 +354,12 @@ static bool btif_av_state_idle_handler(btif_sm_event_t event, void* p_data) {
      if (event == BTIF_AV_CONNECT_REQ_EVT) {
        btif_av_connect_req_t* connect_req_p = (btif_av_connect_req_t*)p_data;
        btif_av_cb.peer_bda = *connect_req_p->target_bda;
        btif_av_cb.self_initiated_connection = true;
        BTA_AvOpen(btif_av_cb.peer_bda, btif_av_cb.bta_handle, true,
                   BTA_SEC_AUTHENTICATE, connect_req_p->uuid);
      } else if (event == BTA_AV_PENDING_EVT) {
        btif_av_cb.peer_bda = ((tBTA_AV*)p_data)->pend.bd_addr;
        btif_av_cb.self_initiated_connection = false;
        if (bt_av_src_callbacks != NULL) {
          BTA_AvOpen(btif_av_cb.peer_bda, btif_av_cb.bta_handle, true,
                     BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SOURCE);
@@ -519,6 +522,9 @@ static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      if (btif_av_cb.self_initiated_connection) {
        btif_queue_advance();
      }
      break;

    case BTA_AV_OPEN_EVT: {
@@ -569,7 +575,9 @@ static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
        /* Bring up AVRCP connection too */
        BTA_AvOpenRc(btif_av_cb.bta_handle);
      }
      if (btif_av_cb.self_initiated_connection) {
        btif_queue_advance();
      }
    } break;

    case BTIF_AV_SOURCE_CONFIG_REQ_EVT:
@@ -599,16 +607,19 @@ static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
      // callback
      btif_av_connect_req_t* connect_req_p = (btif_av_connect_req_t*)p_data;
      if (btif_av_cb.peer_bda == *connect_req_p->target_bda) {
        BTIF_TRACE_DEBUG(
            "%s: Same device moved to Opening state,ignore Connect Req",
            __func__);
        BTIF_TRACE_DEBUG("%s: device %s is already connecting, ignore request",
                         __func__, btif_av_cb.peer_bda.ToString().c_str());
      } else {
        BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request",
                         __func__);
        BTIF_TRACE_WARNING(
            "%s: device %s is already connecting, reject "
            "connection request to %s",
            __func__, btif_av_cb.peer_bda.ToString().c_str(),
            *connect_req_p->target_bda);
        btif_report_connection_state(
            BTAV_CONNECTION_STATE_DISCONNECTED,
            ((btif_av_connect_req_t*)p_data)->target_bda);
      }
      // Ignore all connection request if we are already opening
      btif_queue_advance();
    } break;

@@ -617,12 +628,15 @@ static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
      // callback
      if (((tBTA_AV*)p_data)->pend.bd_addr == btif_av_cb.peer_bda) {
        BTIF_TRACE_DEBUG(
            "%s: Same device moved to Opening state,ignore Pending Req",
            __func__);
            "%s: device %s is already connecting, ignore incoming request",
            __func__, btif_av_cb.peer_bda.ToString().c_str());
        break;
      } else {
        BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request",
                         __func__);
        BTIF_TRACE_WARNING(
            "%s: device %s is already connecting, reject "
            "connection request from %s",
            __func__, btif_av_cb.peer_bda.ToString().c_str(),
            ((tBTA_AV*)p_data)->pend.bd_addr.ToString().c_str());
        BTA_AvDisconnect(((tBTA_AV*)p_data)->pend.bd_addr);
        break;
      }
@@ -638,14 +652,19 @@ static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      if (btif_av_cb.self_initiated_connection) {
        btif_queue_advance();
      }
      break;

    case BTIF_AV_DISCONNECT_REQ_EVT:
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));
      BTA_AvClose(btif_av_cb.bta_handle);
      btif_queue_advance();
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      if (btif_av_cb.self_initiated_connection) {
        btif_queue_advance();
      }
      break;

      CHECK_RC_EVENT(event, (tBTA_AV*)p_data);