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

Commit 66de9c1a authored by Jack He's avatar Jack He
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
(cherry picked from commit 8f902303)
parent d8816233
Loading
Loading
Loading
Loading
+29 −13
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 */
@@ -355,10 +356,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);
@@ -524,6 +527,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: {
@@ -575,7 +581,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:
@@ -609,16 +617,17 @@ static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
      RawAddress& target_bda = *connect_req_p->target_bda;
      if (btif_av_cb.peer_bda == target_bda) {
        BTIF_TRACE_WARNING(
            "%s: Same device moved to Opening state, ignore Connect request: "
            "target_bda=%s",
            __func__, target_bda.ToString().c_str());
            "%s: device %s is already connecting, ignore Connect request",
            __func__, btif_av_cb.peer_bda.ToString().c_str());
      } else {
        BTIF_TRACE_WARNING("%s: Moved from idle by incoming Connect request: ",
                           "target_bda=%s", __func__,
        BTIF_TRACE_WARNING(
            "%s: device %s is already connecting, reject Connect request to %s",
            __func__, btif_av_cb.peer_bda.ToString().c_str(),
            target_bda.ToString().c_str());
        btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                     &target_bda);
      }
      // Ignore all connection request if we are already opening
      btif_queue_advance();
    } break;

@@ -628,12 +637,14 @@ static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
      const RawAddress& bd_addr = ((tBTA_AV*)p_data)->pend.bd_addr;
      if (bd_addr == btif_av_cb.peer_bda) {
        BTIF_TRACE_WARNING(
            "%s: Same device moved to Opening state, ignore Pending request: ",
            "bd_addr=%s", __func__, bd_addr.ToString().c_str());
            "%s: device %s is already connecting, ignore incoming request",
            __func__, btif_av_cb.peer_bda.ToString().c_str());
      } else {
        BTIF_TRACE_WARNING(
            "%s: Moved from idle by outgoing Connection request: bd_addr=%s",
            __func__, bd_addr.ToString().c_str());
            "%s: device %s is already connecting, reject incoming request "
            "from %s",
            __func__, btif_av_cb.peer_bda.ToString().c_str(),
            bd_addr.ToString().c_str());
        BTA_AvDisconnect(bd_addr);
      }
    } break;
@@ -650,14 +661,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);