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

Commit edc5f95b authored by Chris Manton's avatar Chris Manton
Browse files

acl_scheduler: Allow outgoing RNR operation while incoming pending

Bug: 349197968
Bug: 355256744
Test: atest bluetooth_test_gd_unit
Flag: progress_acl_scheduler_upon_incoming_connection

Change-Id: Ie78761481411b3df7d8316e87fc1b8181edc237c
parent 84ea1979
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "hci/acl_manager/acl_scheduler.h"

#include <bluetooth/log.h>
#include <com_android_bluetooth_flags.h>

#include <deque>
#include <optional>
@@ -169,6 +170,15 @@ private:
    if (pending_outgoing_operations_.empty()) {
      return false;
    }
    if (com::android::bluetooth::flags::progress_acl_scheduler_upon_incoming_connection()) {
      if (const RemoteNameRequestQueueEntry* peek =
                  std::get_if<RemoteNameRequestQueueEntry>(&pending_outgoing_operations_.front())) {
        if (incoming_connecting_address_set_.contains(peek->address)) {
          log::info("Pending incoming connection and outgoing RNR to same peer:{}", peek->address);
          return true;
        }
      }
    }
    return incoming_connecting_address_set_.empty() && !outgoing_entry_.has_value();
  }

+40 −1
Original line number Diff line number Diff line
@@ -16,15 +16,20 @@

#include "hci/acl_manager/acl_scheduler.h"

#include <com_android_bluetooth_flags.h>
#include <flag_macros.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <chrono>
#include <future>
#include <utility>

#include "hci/address.h"
#include "os/thread.h"

#define TEST_BT com::android::bluetooth::flags

namespace bluetooth {
namespace hci {
namespace acl_manager {
@@ -262,7 +267,7 @@ TEST_F(AclSchedulerTest, DoNothingWhileIncomingConnectionsExist) {
  // an incoming connection arrives
  acl_scheduler_->RegisterPendingIncomingConnection(address1);

  // try to start an outgoing connection
  // try to start an outgoing connection to another device
  acl_scheduler_->EnqueueOutgoingAclConnection(address2, promiseCallback(std::move(promise)));

  // the outgoing_connection callback should not have executed yet
@@ -286,6 +291,40 @@ TEST_F(AclSchedulerTest, DoNothingWhileIncomingConnectionsExist) {
  EXPECT_THAT(future, IsSet());
}

TEST_F_WITH_FLAGS(AclSchedulerTest, IncomingConnectionPendingWithOutgoingRemoteNameRequest,
                  REQUIRES_FLAGS_ENABLED(
                          ACONFIG_FLAG(TEST_BT, progress_acl_scheduler_upon_incoming_connection))) {
  auto promise = std::promise<void>{};
  auto future = promise.get_future();

  // an incoming connection arrives
  acl_scheduler_->RegisterPendingIncomingConnection(address1);

  // start an outgoing RNR
  acl_scheduler_->EnqueueRemoteNameRequest(address1, promiseCallback(std::move(promise)),
                                           emptyCallback());

  // we expect the outgoing RNR to queue while incoming pending connection from same device
  EXPECT_THAT(future, IsSet());
}

TEST_F_WITH_FLAGS(AclSchedulerTest, ConnectionToSameDeviceIncomingConnectionPending,
                  REQUIRES_FLAGS_ENABLED(
                          ACONFIG_FLAG(TEST_BT, progress_acl_scheduler_upon_incoming_connection))) {
  auto promise = std::promise<void>{};
  auto future = promise.get_future();

  // an incoming connection arrives
  acl_scheduler_->RegisterPendingIncomingConnection(address1);

  // try to start an outgoing connection to same device
  acl_scheduler_->EnqueueOutgoingAclConnection(address1, promiseCallback(std::move(promise)));

  // we expect the outgoing connection to wait and then dropped once connection
  // established
  EXPECT_EQ(future.wait_for(timeout), std::future_status::timeout);
}

TEST_F(AclSchedulerTest, CancelOutgoingConnection) {
  auto promise = std::promise<void>{};
  auto future = promise.get_future();