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

Commit ecd7462d authored by Sandeep Samdaria's avatar Sandeep Samdaria
Browse files

Allow both category of A2DP devices to be connected

Problem: When both A2DP profiles are enabled, only one category
of devices can be connected. If source devices are connected,
then sink device connection are rejected and vice-versa.

Solution: Stack should not differentiate the incoming device
connection and should allow both sink and source devices to be
connected to source and sink profile respectively.

Test: atest net_bt_*
Bug: 325519534
Bug: 321806163
Change-Id: I385b64fc551b49a90c51c132c32634d627b4725b
parent f532b9a6
Loading
Loading
Loading
Loading
+42 −23
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@
#include <android_bluetooth_flags.h>
#include <android_bluetooth_sysprop.h>
#include <base/functional/bind.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <bluetooth/log.h>
#include <frameworks/proto_logging/stats/enums/bluetooth/a2dp/enums.pb.h>
@@ -406,6 +405,7 @@ class BtifAvSource {
  btav_source_callbacks_t* Callbacks() { return callbacks_; }
  bool Enabled() const { return enabled_; }
  bool A2dpOffloadEnabled() const { return a2dp_offload_enabled_; }
  // TODO: b/321806163: Remove this method as part of flag cleanup
  void SetInvalidPeerCheck(bool invalid_peer_check) {
    invalid_peer_check_ = invalid_peer_check;
  }
@@ -644,6 +644,7 @@ class BtifAvSink {
  btav_sink_callbacks_t* Callbacks() { return callbacks_; }
  bool Enabled() const { return enabled_; }

  // TODO: b/321806163: Remove this method as part of flag cleanup
  void SetInvalidPeerCheck(bool invalid_peer_check) {
    invalid_peer_check_ = invalid_peer_check;
  }
@@ -872,7 +873,7 @@ static BtifAvPeer* btif_av_find_peer(const RawAddress& peer_address,
        return sinkPeer;
      }
    }
    LOG_INFO("Unable to find the peer %s",
    log::info("Unable to find the peer {}",
              ADDRESS_TO_LOGGABLE_CSTR(peer_address));
    return nullptr;
  }
@@ -1321,7 +1322,9 @@ BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address,

bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const {
  int connected = 0;
  if (btif_av_src_sink_coexist_enabled() && invalid_peer_check_) {

  if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink) &&
      btif_av_src_sink_coexist_enabled() && invalid_peer_check_) {
    log::info(
        "invalid_peer_check_ so allow to connect here, when BTA_AV_OPEN_EVT "
        "coming, would check again!");
@@ -1337,8 +1340,10 @@ bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const {
      case BtifAvStateMachine::kStateStarted:
        if (peer->PeerAddress() == peer_address) {
          /* we should check if another role is used */
          if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable())
          if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink) &&
              btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) {
            break;
          }

          return true;  // Already connected or accounted for
        }
@@ -1348,7 +1353,8 @@ bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const {
        break;
    }
  }
  if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) {
  if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink) &&
      btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) {
    log::info("connected={}, max_connected_peers_={}, sink_peers={}", connected,
              max_connected_peers_, (int)btif_av_sink.Peers().size());
    /* if source device connected, don't connect sink device */
@@ -1576,7 +1582,8 @@ BtifAvPeer* BtifAvSink::FindOrCreatePeer(const RawAddress& peer_address,
bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const {
  int connected = 0;

  if (btif_av_src_sink_coexist_enabled() && invalid_peer_check_) {
  if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink) &&
      btif_av_src_sink_coexist_enabled() && invalid_peer_check_) {
    log::info(
        "invalid_peer_check_ so allow to connect here, when BTA_AV_OPEN_EVT "
        "coming, would check again!");
@@ -1590,8 +1597,10 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const {
      case BtifAvStateMachine::kStateOpened:
      case BtifAvStateMachine::kStateStarted:
        if (peer->PeerAddress() == peer_address) {
          if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) {
            /* we should check if another role is used */
            if (btif_av_both_enable()) break;
          }
          return true;  // Already connected or accounted for
        }
        connected++;
@@ -1612,7 +1621,7 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const {
        break;
    }
  }
  if (btif_av_both_enable()) {
  if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink) && btif_av_both_enable()) {
    log::info("connected={}, max_connected_peers_={}, source_peers={}",
              connected, max_connected_peers_,
              (int)btif_av_source.Peers().size());
@@ -1835,6 +1844,8 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) {
      if (peer_.IsSink()) {
        can_connect = btif_av_source.AllowedToConnect(peer_.PeerAddress());
        if (!can_connect) {
          log::error("Source profile doesn't allow connection to peer:{}",
                     ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()));
          if (btif_av_src_sink_coexist_enabled())
            BTA_AvCloseRc(((tBTA_AV*)p_data)->rc_open.rc_handle);
          else
@@ -1843,6 +1854,8 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) {
      } else if (peer_.IsSource()) {
        can_connect = btif_av_sink.AllowedToConnect(peer_.PeerAddress());
        if (!can_connect) {
          log::error("Sink profile doesn't allow connection to peer:{}",
                     ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()));
          if (btif_av_src_sink_coexist_enabled())
            BTA_AvCloseRc(((tBTA_AV*)p_data)->rc_open.rc_handle);
          else
@@ -1919,6 +1932,7 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) {
                       ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()),
                       peer_.PeerSep(), p_bta_data->open.sep);
          /* if peer is wrong sep type, move it to BtifAvSxxx */
          if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) {
            if (peer_.PeerSep() == AVDT_TSEP_SNK) {
              log::verbose("set source invalid_peer_check as false");
              btif_av_source.SetInvalidPeerCheck(false);
@@ -1926,6 +1940,7 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) {
              log::verbose("set sink invalid_peer_check as false");
              btif_av_sink.SetInvalidPeerCheck(false);
            }
          }
          if (peer_.PeerSep() != p_bta_data->open.sep) {
            BtifAvPeer* tmp_peer = nullptr;
            if (peer_.PeerSep() == AVDT_TSEP_SNK) {
@@ -2125,6 +2140,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event,
                       ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()),
                       peer_.PeerSep(), p_bta_data->open.sep);
          /* if peer is wrong sep type, move it to BtifAvSxxx */
          if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) {
            if (peer_.PeerSep() == AVDT_TSEP_SNK) {
              log::verbose("set source invalid_peer_check as false");
              btif_av_source.SetInvalidPeerCheck(false);
@@ -2132,6 +2148,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event,
              log::verbose("set sink invalid_peer_check as false");
              btif_av_sink.SetInvalidPeerCheck(false);
            }
          }
          if (peer_.PeerSep() != p_bta_data->open.sep) {
            BtifAvPeer* tmp_peer = nullptr;
            if (peer_.PeerSep() == AVDT_TSEP_SNK) {
@@ -3148,7 +3165,9 @@ static BtifAvPeer* btif_av_handle_both_peer(uint8_t peer_sep,
          log::verbose("peer_sep({}), create a new sink peer", peer_sep);
          peer = btif_av_source.FindOrCreatePeer(peer_address, bta_handle);
        } else {
          if (!IS_FLAG_ENABLED(a2dp_concurrent_source_sink)) {
            btif_av_source.SetInvalidPeerCheck(true);
          }
          if (!btif_av_source.Peers().empty()) {
            log::verbose(
                "peer_sep invalid, and already has sink peer, so try create a "