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

Commit e3bb9309 authored by Jakub Rotkiewicz's avatar Jakub Rotkiewicz Committed by Gerrit Code Review
Browse files

Merge "btif_av: access peers_ only from BtifAvSource/Sink" into main

parents c16dd957 f7600ea2
Loading
Loading
Loading
Loading
+102 −48
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <chrono>
#include <cstdint>
#include <future>
#include <mutex>
#include <string>
#include <vector>

@@ -595,8 +596,22 @@ class BtifAvSource {
        peer_address, codec_preferences, std::move(peer_ready_promise));
  }

  const std::map<RawAddress, BtifAvPeer*>& Peers() const { return peers_; }
  /**
   * Get number of saved peers.
   */
  int GetPeersCount() const {
    std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
    return peers_.size();
  }

  /**
   * Dispatch SUSPEND or STOP A2DP stream event on all peer devices.
   * Returns true if succeeded.
   * @param event SUSPEND or STOP event
   */
  void DispatchSuspendStreamEvent(btif_av_sm_event_t event);

  void DumpPeersInfo(int fd);
  void RegisterAllBtaHandles();
  void DeregisterAllBtaHandles();
  void BtaHandleRegistered(uint8_t peer_id, tBTA_AV_HNDL bta_handle);
@@ -615,9 +630,8 @@ class BtifAvSource {
  std::set<RawAddress> silenced_peers_;
  RawAddress active_peer_;
  std::map<uint8_t, tBTA_AV_HNDL> peer_id2bta_handle_;
  std::mutex mutex_;
  // protect for BtifAvSource::peers_
  std::recursive_mutex btifavsource_peer_lock_;
  mutable std::recursive_mutex btifavsource_peers_lock_;
};

class BtifAvSink {
@@ -752,8 +766,15 @@ class BtifAvSink {
    active_peer_ = RawAddress::kEmpty;
  }

  const std::map<RawAddress, BtifAvPeer*>& Peers() const { return peers_; }
  /**
   * Get number of saved peers.
   */
  int GetPeersCount() const {
    std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
    return peers_.size();
  }

  void DumpPeersInfo(int fd);
  void RegisterAllBtaHandles();
  void DeregisterAllBtaHandles();
  void BtaHandleRegistered(uint8_t peer_id, tBTA_AV_HNDL bta_handle);
@@ -770,6 +791,8 @@ class BtifAvSink {
  std::map<RawAddress, BtifAvPeer*> peers_;
  RawAddress active_peer_;
  std::map<uint8_t, tBTA_AV_HNDL> peer_id2bta_handle_;
  // protect for BtifAvSink::peers_
  mutable std::recursive_mutex btifavsink_peers_lock_;
};

/*****************************************************************************
@@ -803,6 +826,7 @@ static void btif_av_handle_event(uint8_t peer_sep,
                                 const RawAddress& peer_address,
                                 tBTA_AV_HNDL bta_handle,
                                 const BtifAvEvent& btif_av_event);
static void btif_debug_av_peer_dump(int fd, const BtifAvPeer& peer);
static void btif_report_connection_state(const RawAddress& peer_address,
                                         btav_connection_state_t state,
                                         const bt_status_t status,
@@ -1235,6 +1259,7 @@ BtifAvPeer* BtifAvSource::FindPeer(const RawAddress& peer_address) {
}

BtifAvPeer* BtifAvSource::FindPeerByHandle(tBTA_AV_HNDL bta_handle) {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  for (auto it : peers_) {
    BtifAvPeer* peer = it.second;
    if (peer->BtaHandle() == bta_handle) {
@@ -1245,6 +1270,7 @@ BtifAvPeer* BtifAvSource::FindPeerByHandle(tBTA_AV_HNDL bta_handle) {
}

BtifAvPeer* BtifAvSource::FindPeerByPeerId(uint8_t peer_id) {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  for (auto it : peers_) {
    BtifAvPeer* peer = it.second;
    if (peer->PeerId() == peer_id) {
@@ -1256,7 +1282,7 @@ BtifAvPeer* BtifAvSource::FindPeerByPeerId(uint8_t peer_id) {

BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address,
                                           tBTA_AV_HNDL bta_handle) {
  std::unique_lock<std::mutex> lock1(mutex_);
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  log::verbose("peer={} bta_handle=0x{:x}", peer_address, bta_handle);

  BtifAvPeer* peer = FindPeer(peer_address);
@@ -1304,6 +1330,7 @@ BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address,
}

bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  int connected = 0;

  if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink() &&
@@ -1339,26 +1366,60 @@ bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const {
  if (!com::android::bluetooth::flags::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());
              max_connected_peers_, btif_av_sink.GetPeersCount());
    /* if source device connected, don't connect sink device */

    if (connected >= max_connected_peers_ || !btif_av_sink.Peers().empty()) {
    if (connected >= max_connected_peers_ ||
        btif_av_sink.GetPeersCount() != 0) {
      return false;
    } else {
      return true;
    }
  }
  if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
    const int sink_connected_peers_size = (int)btif_av_sink.Peers().size();
    const int sink_connected_peers_size = btif_av_sink.GetPeersCount();
    log::info(
        "connected={}, max_connected_peers_={}, sink_connected_peers_size={}",
        connected, max_connected_peers_, (int)btif_av_sink.Peers().size());
        connected, max_connected_peers_, btif_av_sink.GetPeersCount());
    return ((connected + sink_connected_peers_size) < max_connected_peers_);
  }
  return (connected < max_connected_peers_);
}

void BtifAvSource::DumpPeersInfo(int fd) {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  for (auto it : peers_) {
    const BtifAvPeer* peer = it.second;
    if (peer != nullptr) {
      btif_debug_av_peer_dump(fd, *peer);
    }
  }
}

void BtifAvSource::DispatchSuspendStreamEvent(btif_av_sm_event_t event) {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  if (event != BTIF_AV_SUSPEND_STREAM_REQ_EVT &&
      event != BTIF_AV_STOP_STREAM_REQ_EVT) {
    log::error("Invalid event: {} id: {}", dump_av_sm_event_name(event),
               (int)event);
    return;
  }
  bool av_stream_idle = true;
  for (auto it : peers_) {
    const BtifAvPeer* peer = it.second;
    if (peer->StateMachine().StateId() == BtifAvStateMachine::kStateStarted) {
      btif_av_source_dispatch_sm_event(peer->PeerAddress(), event);
      av_stream_idle = false;
    }
  }

  if (av_stream_idle) {
    btif_a2dp_on_stopped(nullptr, A2dpType::kSource);
  }
}

void BtifAvSource::DeleteIdlePeers() {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  for (auto it = peers_.begin(); it != peers_.end();) {
    BtifAvPeer* peer = it->second;
    auto prev_it = it++;
@@ -1372,6 +1433,7 @@ void BtifAvSource::DeleteIdlePeers() {
}

void BtifAvSource::CleanupAllPeers() {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  log::info("");

  while (!peers_.empty()) {
@@ -1418,6 +1480,7 @@ void BtifAvSource::BtaHandleRegistered(uint8_t peer_id,
}

BtifAvPeer* BtifAvSource::popPeer(const RawAddress& peer_address) {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  auto it = peers_.find(peer_address);
  if (it == peers_.end()) return nullptr;
  BtifAvPeer* peer = it->second;
@@ -1428,6 +1491,7 @@ BtifAvPeer* BtifAvSource::popPeer(const RawAddress& peer_address) {
}

void BtifAvSource::AddPeer(BtifAvPeer* peer) {
  std::lock_guard<std::recursive_mutex> lock(btifavsource_peers_lock_);
  log::info("peer={}, state={}", peer->PeerAddress(),
            peer->StateMachine().StateId());
  peers_.insert(std::make_pair(peer->PeerAddress(), peer));
@@ -1488,6 +1552,7 @@ BtifAvPeer* BtifAvSink::FindPeer(const RawAddress& peer_address) {
}

BtifAvPeer* BtifAvSink::FindPeerByHandle(tBTA_AV_HNDL bta_handle) {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  for (auto it : peers_) {
    BtifAvPeer* peer = it.second;
    if (peer->BtaHandle() == bta_handle) {
@@ -1498,6 +1563,7 @@ BtifAvPeer* BtifAvSink::FindPeerByHandle(tBTA_AV_HNDL bta_handle) {
}

BtifAvPeer* BtifAvSink::FindPeerByPeerId(uint8_t peer_id) {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  for (auto it : peers_) {
    BtifAvPeer* peer = it.second;
    if (peer->PeerId() == peer_id) {
@@ -1509,6 +1575,7 @@ BtifAvPeer* BtifAvSink::FindPeerByPeerId(uint8_t peer_id) {

BtifAvPeer* BtifAvSink::FindOrCreatePeer(const RawAddress& peer_address,
                                         tBTA_AV_HNDL bta_handle) {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  log::verbose("peer={} bta_handle=0x{:x}", peer_address, bta_handle);

  BtifAvPeer* peer = FindPeer(peer_address);
@@ -1556,7 +1623,18 @@ BtifAvPeer* BtifAvSink::FindOrCreatePeer(const RawAddress& peer_address,
  return peer;
}

void BtifAvSink::DumpPeersInfo(int fd) {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  for (auto it : peers_) {
    const BtifAvPeer* peer = it.second;
    if (peer != nullptr) {
      btif_debug_av_peer_dump(fd, *peer);
    }
  }
}

bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  int connected = 0;

  if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink() &&
@@ -1600,14 +1678,14 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const {
  if (!com::android::bluetooth::flags::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());
              connected, max_connected_peers_, btif_av_source.GetPeersCount());
    /* if source device connected, don't connect sink device */
    return (connected < max_connected_peers_) && btif_av_source.Peers().empty();
    return (connected < max_connected_peers_) &&
           (btif_av_source.GetPeersCount() == 0);
  }

  if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
    const int source_connected_peers_size = (int)btif_av_source.Peers().size();
    const int source_connected_peers_size = btif_av_source.GetPeersCount();
    log::info(
        "connected={}, max_connected_peers_={}, source_connected_peers_size={}",
        connected, max_connected_peers_, source_connected_peers_size);
@@ -1617,6 +1695,7 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const {
}

void BtifAvSink::DeleteIdlePeers() {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  for (auto it = peers_.begin(); it != peers_.end();) {
    BtifAvPeer* peer = it->second;
    auto prev_it = it++;
@@ -1630,6 +1709,7 @@ void BtifAvSink::DeleteIdlePeers() {
}

void BtifAvSink::CleanupAllPeers() {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  log::info("");

  while (!peers_.empty()) {
@@ -1675,6 +1755,7 @@ void BtifAvSink::BtaHandleRegistered(uint8_t peer_id, tBTA_AV_HNDL bta_handle) {
}

BtifAvPeer* BtifAvSink::popPeer(const RawAddress& peer_address) {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  auto it = peers_.find(peer_address);
  if (it == peers_.end()) return nullptr;
  BtifAvPeer* peer = it->second;
@@ -1685,6 +1766,7 @@ BtifAvPeer* BtifAvSink::popPeer(const RawAddress& peer_address) {
}

void BtifAvSink::AddPeer(BtifAvPeer* peer) {
  std::lock_guard<std::recursive_mutex> lock(btifavsink_peers_lock_);
  log::info("peer={}, state={}", peer->PeerAddress(),
            peer->StateMachine().StateId());
  peers_.insert(std::make_pair(peer->PeerAddress(), peer));
@@ -3102,12 +3184,12 @@ static BtifAvPeer* btif_av_handle_both_peer(uint8_t peer_sep,
          if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
            btif_av_source.SetInvalidPeerCheck(true);
          }
          if (!btif_av_source.Peers().empty()) {
          if (btif_av_source.GetPeersCount() != 0) {
            log::verbose(
                "peer_sep invalid, and already has sink peer, so try create a "
                "new sink peer");
            peer = btif_av_source.FindOrCreatePeer(peer_address, bta_handle);
          } else if (!btif_av_sink.Peers().empty()) {
          } else if (btif_av_sink.GetPeersCount() != 0) {
            log::verbose(
                "peer_sep invalid, and already has source peer, so try create "
                "a new source peer");
@@ -3819,27 +3901,6 @@ void btif_av_stream_start_with_latency(bool use_latency_mode) {
                                btif_av_event));
}

static void src_do_suspend_in_main_thread(btif_av_sm_event_t event) {
  if (event != BTIF_AV_SUSPEND_STREAM_REQ_EVT &&
      event != BTIF_AV_STOP_STREAM_REQ_EVT)
    return;
  auto src_do_stream_suspend = [](btif_av_sm_event_t event) {
    bool is_idle = true;
    for (auto it : btif_av_source.Peers()) {
      const BtifAvPeer* peer = it.second;
      if (peer->StateMachine().StateId() == BtifAvStateMachine::kStateStarted) {
        btif_av_source_dispatch_sm_event(peer->PeerAddress(), event);
        is_idle = false;
      }
    }
    if (is_idle) {
      btif_a2dp_on_stopped(nullptr, A2dpType::kSource);
    }
  };
  // switch to main thread to prevent a race condition of accessing peers
  do_in_main_thread(FROM_HERE, base::BindOnce(src_do_stream_suspend, event));
}

void btif_av_stream_stop(const RawAddress& peer_address) {
  log::info("peer={}", peer_address);

@@ -3850,7 +3911,7 @@ void btif_av_stream_stop(const RawAddress& peer_address) {

  // The active peer might have changed and we might be in the process
  // of reconfiguring the stream. We need to stop the appropriate peer(s).
  src_do_suspend_in_main_thread(BTIF_AV_STOP_STREAM_REQ_EVT);
  btif_av_source.DispatchSuspendStreamEvent(BTIF_AV_STOP_STREAM_REQ_EVT);
}

void btif_av_stream_suspend(void) {
@@ -3858,7 +3919,7 @@ void btif_av_stream_suspend(void) {

  // The active peer might have changed and we might be in the process
  // of reconfiguring the stream. We need to suspend the appropriate peer(s).
  src_do_suspend_in_main_thread(BTIF_AV_SUSPEND_STREAM_REQ_EVT);
  btif_av_source.DispatchSuspendStreamEvent(BTIF_AV_SUSPEND_STREAM_REQ_EVT);
}

void btif_av_stream_start_offload(void) {
@@ -4186,12 +4247,8 @@ static void btif_debug_av_source_dump(int fd) {
  if (!enabled) return;
  dprintf(fd, "  Active peer: %s\n",
          ADDRESS_TO_LOGGABLE_CSTR(btif_av_source.ActivePeer()));
  for (auto it : btif_av_source.Peers()) {
    const BtifAvPeer* peer = it.second;
    if (peer != nullptr) {
      btif_debug_av_peer_dump(fd, *peer);
    }
  }
  dprintf(fd, "  Peers:\n");
  btif_av_source.DumpPeersInfo(fd);
}

static void btif_debug_av_sink_dump(int fd) {
@@ -4202,10 +4259,7 @@ static void btif_debug_av_sink_dump(int fd) {
  dprintf(fd, "  Active peer: %s\n",
          ADDRESS_TO_LOGGABLE_CSTR(btif_av_sink.ActivePeer()));
  dprintf(fd, "  Peers:\n");
  for (auto it : btif_av_sink.Peers()) {
    const BtifAvPeer* peer = it.second;
    btif_debug_av_peer_dump(fd, *peer);
  }
  btif_av_sink.DumpPeersInfo(fd);
}

void btif_debug_av_dump(int fd) {