summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jakub Pawlowski <jpawlowski@google.com> 2024-10-09 22:08:28 +0200
committer Jakub Pawlowski <jpawlowski@google.com> 2024-10-09 22:13:04 +0200
commit8adbe408d3a34728796c4f1050df62d3a7fb56bc (patch)
tree58b51090bc762a31b5f7c0a4d11284f35f47f283
parent9a5b6b8dab52df8fbd99c57357fd03c7f080a1d6 (diff)
use_unified_connection_manager removal
Unused, out of date Test: mma -j32 Bug: 290846969 Bug: 349469413 Bug: 372202918 Flag: EXEMPT, just delting unused code under flag Change-Id: Ie01c56f81d81affeed5c7285bcf8d712b6af59b0
-rw-r--r--flags/hci.aconfig10
-rw-r--r--system/main/shim/acl.cc4
-rw-r--r--system/rust/Android.bp2
-rw-r--r--system/rust/BUILD.gn1
-rw-r--r--system/rust/src/connection.rs431
-rw-r--r--system/rust/src/connection/acceptlist_manager.rs366
-rw-r--r--system/rust/src/connection/attempt_manager.rs501
-rw-r--r--system/rust/src/connection/ffi.rs242
-rw-r--r--system/rust/src/connection/ffi/connection_shim.cc169
-rw-r--r--system/rust/src/connection/ffi/connection_shim.h72
-rw-r--r--system/rust/src/connection/le_manager.rs63
-rw-r--r--system/rust/src/connection/mocks.rs2
-rw-r--r--system/rust/src/connection/mocks/mock_le_manager.rs174
-rw-r--r--system/rust/src/core/ffi.rs7
-rw-r--r--system/rust/src/core/ffi/module.cc4
-rw-r--r--system/rust/src/core/mod.rs3
-rw-r--r--system/rust/src/lib.rs10
-rw-r--r--system/stack/acl/ble_acl.cc12
-rw-r--r--system/stack/acl/btm_acl.cc13
-rw-r--r--system/stack/btm/btm_dev.cc8
-rw-r--r--system/stack/gatt/gatt_api.cc34
-rw-r--r--system/stack/gatt/gatt_main.cc34
-rw-r--r--system/stack/gatt/gatt_utils.cc43
-rw-r--r--system/test/mock/mock_rust_ffi_connection_shim.cc36
24 files changed, 40 insertions, 2201 deletions
diff --git a/flags/hci.aconfig b/flags/hci.aconfig
index 8c5180a298..9c6d21d3a9 100644
--- a/flags/hci.aconfig
+++ b/flags/hci.aconfig
@@ -2,16 +2,6 @@ package: "com.android.bluetooth.flags"
container: "com.android.btservices"
flag {
- name: "unified_connection_manager"
- namespace: "bluetooth"
- description: "Manage connections centrally and remove the ACL shim layer"
- bug: "349469413"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "encryption_change_v2"
namespace: "bluetooth"
description: "Enable encryption change V2 event"
diff --git a/system/main/shim/acl.cc b/system/main/shim/acl.cc
index 79d6032095..7f33da446f 100644
--- a/system/main/shim/acl.cc
+++ b/system/main/shim/acl.cc
@@ -1009,9 +1009,7 @@ struct shim::Acl::impl {
auto connection = handle_to_le_connection_map_.find(handle);
if (connection != handle_to_le_connection_map_.end()) {
auto remote_address_with_type = connection->second->GetRemoteAddressWithType();
- if (!com::android::bluetooth::flags::unified_connection_manager()) {
- GetAclManager()->RemoveFromBackgroundList(remote_address_with_type);
- }
+ GetAclManager()->RemoveFromBackgroundList(remote_address_with_type);
connection->second->InitiateDisconnect(ToDisconnectReasonFromLegacy(reason));
log::debug("Disconnection initiated le remote:{} handle:{}", remote_address_with_type,
handle);
diff --git a/system/rust/Android.bp b/system/rust/Android.bp
index f3fddcd3b9..9e4cca0736 100644
--- a/system/rust/Android.bp
+++ b/system/rust/Android.bp
@@ -108,7 +108,6 @@ cc_library_static {
"-Wno-missing-prototypes",
],
srcs: [
- "src/connection/ffi/connection_shim.cc",
"src/core/ffi/module.cc",
"src/gatt/ffi/gatt_shim.cc",
],
@@ -169,7 +168,6 @@ cc_library_static {
filegroup {
name: "libbluetooth_core_rs_ffi",
srcs: [
- "src/connection/ffi.rs",
"src/core/ffi.rs",
"src/gatt/ffi.rs",
],
diff --git a/system/rust/BUILD.gn b/system/rust/BUILD.gn
index 5c386e5a0f..f9c63f4986 100644
--- a/system/rust/BUILD.gn
+++ b/system/rust/BUILD.gn
@@ -22,7 +22,6 @@ cxxbridge_libheader("cxxlibheader") {
static_library("core_rs") {
sources = [
- "src/connection/ffi/connection_shim.cc",
"src/core/ffi/module.cc",
"src/gatt/ffi/gatt_shim.cc",
]
diff --git a/system/rust/src/connection.rs b/system/rust/src/connection.rs
deleted file mode 100644
index 99dc4c6cb3..0000000000
--- a/system/rust/src/connection.rs
+++ /dev/null
@@ -1,431 +0,0 @@
-//! This module manages LE connection requests and active
-//! LE connections. In particular, it de-duplicates connection requests,
-//! avoids duplicate connections to the same devices (even with different RPAs),
-//! and retries failed connections
-
-use std::{
- cell::RefCell, collections::HashSet, fmt::Debug, future::Future, hash::Hash, ops::Deref,
- time::Duration,
-};
-
-use crate::{
- core::{
- address::AddressWithType,
- shared_box::{SharedBox, WeakBox, WeakBoxRef},
- },
- gatt::ids::ServerId,
-};
-
-use self::{
- acceptlist_manager::{determine_target_state, LeAcceptlistManager},
- attempt_manager::{ConnectionAttempts, ConnectionMode},
- le_manager::{ErrorCode, InactiveLeAclManager, LeAclManagerConnectionCallbacks},
-};
-
-mod acceptlist_manager;
-mod attempt_manager;
-mod ffi;
-pub mod le_manager;
-mod mocks;
-
-pub use ffi::{register_callbacks, LeAclManagerImpl, LeAclManagerShim};
-use log::info;
-use scopeguard::ScopeGuard;
-use tokio::{task::spawn_local, time::timeout};
-
-/// Possible errors returned when making a connection attempt
-#[derive(Debug, PartialEq, Eq)]
-pub enum CreateConnectionFailure {
- /// This client is already making a connection of the same type
- /// to the same address.
- ConnectionAlreadyPending,
-}
-
-/// Errors returned if a connection successfully starts but fails afterwards.
-#[derive(Debug, PartialEq, Eq)]
-pub enum ConnectionFailure {
- /// The connection attempt was cancelled
- Cancelled,
- /// The connection completed but with an HCI error code
- Error(ErrorCode),
-}
-
-/// Errors returned if the client fails to cancel their connection attempt
-#[derive(Debug, PartialEq, Eq)]
-pub enum CancelConnectFailure {
- /// The connection attempt does not exist
- ConnectionNotPending,
-}
-
-/// Unique identifiers for a client of the connection manager
-#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
-pub enum ConnectionManagerClient {
- /// A GATT client with given client ID
- GattClient(u8),
- /// A GATT server with given server ID
- GattServer(ServerId),
-}
-
-/// An active connection
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub struct LeConnection {
- /// The address of the peer device, as reported in the connection complete event
- /// This is guaranteed to be unique across active connections, so we can implement
- /// PartialEq/Eq on this.
- pub remote_address: AddressWithType,
-}
-
-/// Responsible for managing the initiator state and the list of
-/// devices on the filter accept list
-#[derive(Debug)]
-pub struct ConnectionManager {
- state: RefCell<ConnectionManagerState>,
-}
-
-#[derive(Debug)]
-struct ConnectionManagerState {
- /// All pending connection attempts (unresolved direct + all background)
- attempts: ConnectionAttempts,
- /// The addresses we are currently connected to
- current_connections: HashSet<AddressWithType>,
- /// Tracks the state of the LE connect list, and updates it to drive to a
- /// specified target state
- acceptlist_manager: LeAcceptlistManager,
-}
-
-struct ConnectionManagerCallbackHandler(WeakBox<ConnectionManager>);
-
-const DIRECT_CONNECTION_TIMEOUT: Duration = Duration::from_secs(
- 29, /* ugly hack to avoid fighting with le_impl timeout, until I remove that timeout */
-);
-
-impl LeAclManagerConnectionCallbacks for ConnectionManagerCallbackHandler {
- fn on_le_connect(&self, address: AddressWithType, result: Result<LeConnection, ErrorCode>) {
- self.with_manager(|manager| manager.on_le_connect(address, result))
- }
-
- fn on_disconnect(&self, address: AddressWithType) {
- self.with_manager(|manager| manager.on_disconnect(address))
- }
-}
-
-impl ConnectionManagerCallbackHandler {
- fn with_manager(&self, f: impl FnOnce(&ConnectionManager)) {
- self.0.with(|manager| f(manager.expect("got connection event after stack died").deref()))
- }
-}
-
-impl ConnectionManager {
- /// Constructor
- pub fn new(le_manager: impl InactiveLeAclManager) -> SharedBox<Self> {
- SharedBox::new_cyclic(|weak| Self {
- state: RefCell::new(ConnectionManagerState {
- attempts: ConnectionAttempts::new(),
- current_connections: HashSet::new(),
- acceptlist_manager: LeAcceptlistManager::new(
- le_manager.register_callbacks(ConnectionManagerCallbackHandler(weak)),
- ),
- }),
- })
- }
-}
-
-/// Make the state of the LeAcceptlistManager consistent with the attempts tracked in ConnectionAttempts
-fn reconcile_state(state: &mut ConnectionManagerState) {
- state
- .acceptlist_manager
- .drive_to_state(determine_target_state(&state.attempts.active_attempts()));
-}
-
-impl WeakBoxRef<'_, ConnectionManager> {
- /// Start a direct connection to a peer device from a specified client. If the peer
- /// is connected, immediately resolve the attempt.
- pub fn start_direct_connection(
- &self,
- client: ConnectionManagerClient,
- address: AddressWithType,
- ) -> Result<(), CreateConnectionFailure> {
- spawn_local(timeout(DIRECT_CONNECTION_TIMEOUT, self.direct_connection(client, address)?));
- Ok(())
- }
-
- /// Start a direct connection to a peer device from a specified client.
- ///
- /// # Cancellation Safety
- /// If this future is dropped, the connection attempt will be cancelled. It can also be cancelled
- /// from the separate API ConnectionManager#cancel_connection.
- fn direct_connection(
- &self,
- client: ConnectionManagerClient,
- address: AddressWithType,
- ) -> Result<
- impl Future<Output = Result<LeConnection, ConnectionFailure>>,
- CreateConnectionFailure,
- > {
- let mut state = self.state.borrow_mut();
-
- // if connected, this is a no-op
- let attempt_and_guard = if state.current_connections.contains(&address) {
- None
- } else {
- let pending_attempt = state.attempts.register_direct_connection(client, address)?;
- let attempt_id = pending_attempt.id;
- reconcile_state(&mut state);
- Some((
- pending_attempt,
- scopeguard::guard(self.downgrade(), move |this| {
- // remove the attempt after we are cancelled
- this.with(|this| {
- this.map(|this| {
- info!("Cancelling attempt {attempt_id:?}");
- let mut state = this.state.borrow_mut();
- state.attempts.cancel_attempt_with_id(attempt_id);
- reconcile_state(&mut state);
- })
- });
- }),
- ))
- };
-
- Ok(async move {
- let Some((attempt, guard)) = attempt_and_guard else {
- // if we did not make an attempt, the connection must be ready
- return Ok(LeConnection { remote_address: address });
- };
- // otherwise, wait until the attempt resolves
- let ret = attempt.await;
- // defuse scopeguard (no need to cancel now)
- ScopeGuard::into_inner(guard);
- ret
- })
- }
-}
-
-impl ConnectionManager {
- /// Start a background connection to a peer device with given parameters from a specified client.
- pub fn add_background_connection(
- &self,
- client: ConnectionManagerClient,
- address: AddressWithType,
- ) -> Result<(), CreateConnectionFailure> {
- let mut state = self.state.borrow_mut();
- state.attempts.register_background_connection(client, address)?;
- reconcile_state(&mut state);
- Ok(())
- }
-
- /// Cancel connection attempt from this client to the specified address with the specified mode.
- pub fn cancel_connection(
- &self,
- client: ConnectionManagerClient,
- address: AddressWithType,
- mode: ConnectionMode,
- ) -> Result<(), CancelConnectFailure> {
- let mut state = self.state.borrow_mut();
- state.attempts.cancel_attempt(client, address, mode)?;
- reconcile_state(&mut state);
- Ok(())
- }
-
- /// Cancel all connection attempts to this address
- pub fn cancel_unconditionally(&self, address: AddressWithType) {
- let mut state = self.state.borrow_mut();
- state.attempts.remove_unconditionally(address);
- reconcile_state(&mut state);
- }
-
- /// Cancel all connection attempts from this client
- pub fn remove_client(&self, client: ConnectionManagerClient) {
- let mut state = self.state.borrow_mut();
- state.attempts.remove_client(client);
- reconcile_state(&mut state);
- }
-
- fn on_le_connect(&self, address: AddressWithType, result: Result<LeConnection, ErrorCode>) {
- let mut state = self.state.borrow_mut();
- // record this connection while it exists
- state.current_connections.insert(address);
- // all completed connections remove the address from the direct list
- state.acceptlist_manager.on_connect_complete(address);
- // invoke any pending callbacks, update set of attempts
- state.attempts.process_connection(address, result);
- // update the acceptlist
- reconcile_state(&mut state);
- }
-
- fn on_disconnect(&self, address: AddressWithType) {
- let mut state = self.state.borrow_mut();
- state.current_connections.remove(&address);
- reconcile_state(&mut state);
- }
-}
-
-#[cfg(test)]
-mod test {
- use crate::{core::address::AddressType, utils::task::block_on_locally};
-
- use super::{mocks::mock_le_manager::MockLeAclManager, *};
-
- const CLIENT_1: ConnectionManagerClient = ConnectionManagerClient::GattClient(1);
- const CLIENT_2: ConnectionManagerClient = ConnectionManagerClient::GattClient(2);
-
- const ADDRESS_1: AddressWithType =
- AddressWithType { address: [1, 2, 3, 4, 5, 6], address_type: AddressType::Public };
-
- const ERROR: ErrorCode = ErrorCode(1);
-
- #[test]
- fn test_single_direct_connection() {
- block_on_locally(async {
- // arrange
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
-
- // act: initiate a direct connection
- connection_manager.as_ref().start_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // assert: the direct connection is pending
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Direct));
- assert_eq!(mock_le_manager.current_acceptlist().len(), 1);
- assert!(mock_le_manager.current_acceptlist().contains(&ADDRESS_1));
- });
- }
-
- #[test]
- fn test_failed_direct_connection() {
- block_on_locally(async {
- // arrange: one pending direct connection
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
- connection_manager.as_ref().start_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // act: the connection attempt fails
- mock_le_manager.on_le_connect(ADDRESS_1, ERROR);
-
- // assert: the direct connection has stopped
- assert_eq!(mock_le_manager.current_connection_mode(), None);
- });
- }
-
- #[test]
- fn test_single_background_connection() {
- block_on_locally(async {
- // arrange
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
-
- // act: initiate a background connection
- connection_manager.as_ref().add_background_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // assert: the background connection is pending
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Background));
- assert_eq!(mock_le_manager.current_acceptlist().len(), 1);
- assert!(mock_le_manager.current_acceptlist().contains(&ADDRESS_1));
- });
- }
-
- #[test]
- fn test_resolved_connection() {
- block_on_locally(async {
- // arrange
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
-
- // act: initiate a direct connection, that succeeds
- connection_manager.as_ref().start_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- mock_le_manager.on_le_connect(ADDRESS_1, ErrorCode::SUCCESS);
-
- // assert: no connection is pending
- assert_eq!(mock_le_manager.current_connection_mode(), None);
- });
- }
-
- #[test]
- fn test_resolved_background_connection() {
- block_on_locally(async {
- // arrange
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
-
- // act: initiate a background connection, that succeeds
- connection_manager.as_ref().add_background_connection(CLIENT_1, ADDRESS_1).unwrap();
- mock_le_manager.on_le_connect(ADDRESS_1, ErrorCode::SUCCESS);
-
- // assert: no connection is pending
- assert_eq!(mock_le_manager.current_connection_mode(), None);
- });
- }
-
- #[test]
- fn test_resolved_direct_connection_after_disconnect() {
- block_on_locally(async {
- // arrange
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
-
- // act: initiate a direct connection, that succeeds, then disconnects
- connection_manager.as_ref().start_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- mock_le_manager.on_le_connect(ADDRESS_1, ErrorCode::SUCCESS);
- mock_le_manager.on_le_disconnect(ADDRESS_1);
-
- // assert: no connection is pending
- assert_eq!(mock_le_manager.current_connection_mode(), None);
- });
- }
-
- #[test]
- fn test_resolved_background_connection_after_disconnect() {
- block_on_locally(async {
- // arrange
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
-
- // act: initiate a background connection, that succeeds, then disconnects
- connection_manager.as_ref().add_background_connection(CLIENT_1, ADDRESS_1).unwrap();
- mock_le_manager.on_le_connect(ADDRESS_1, ErrorCode::SUCCESS);
- mock_le_manager.on_le_disconnect(ADDRESS_1);
-
- // assert: the background connection has resumed
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Background));
- });
- }
-
- #[test]
- fn test_direct_connection_timeout() {
- block_on_locally(async {
- // arrange: a pending direct connection
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
- connection_manager.as_ref().start_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // act: let it timeout
- tokio::time::sleep(DIRECT_CONNECTION_TIMEOUT).await;
- // go forward one tick to ensure all timers are fired
- // (since we are using fake time, this is not a race condition)
- tokio::time::sleep(Duration::from_millis(1)).await;
-
- // assert: it is cancelled and we are idle again
- assert_eq!(mock_le_manager.current_connection_mode(), None);
- });
- }
-
- #[test]
- fn test_stacked_direct_connections_timeout() {
- block_on_locally(async {
- // arrange
- let mock_le_manager = MockLeAclManager::new();
- let connection_manager = ConnectionManager::new(mock_le_manager.clone());
-
- // act: start a direct connection
- connection_manager.as_ref().start_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- tokio::time::sleep(DIRECT_CONNECTION_TIMEOUT * 3 / 4).await;
- // act: after some time, start a second one
- connection_manager.as_ref().start_direct_connection(CLIENT_2, ADDRESS_1).unwrap();
- // act: wait for the first one (but not the second) to time out
- tokio::time::sleep(DIRECT_CONNECTION_TIMEOUT * 3 / 4).await;
-
- // assert: we are still doing a direct connection
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Direct));
- });
- }
-}
diff --git a/system/rust/src/connection/acceptlist_manager.rs b/system/rust/src/connection/acceptlist_manager.rs
deleted file mode 100644
index 4810640f3a..0000000000
--- a/system/rust/src/connection/acceptlist_manager.rs
+++ /dev/null
@@ -1,366 +0,0 @@
-//! This module takes the set of attempts from the AttemptManager, determines
-//! the target state of the LE manager, and drives it to this target state
-
-use std::collections::HashSet;
-
-use log::info;
-
-use crate::core::address::AddressWithType;
-
-use super::{
- attempt_manager::{ConnectionAttempt, ConnectionMode},
- le_manager::LeAclManager,
-};
-
-/// This struct represents the target state of the LeManager based on the
-/// set of all active connection attempts
-pub struct TargetState {
- /// These addresses should go to the LE background connect list
- pub background_list: HashSet<AddressWithType>,
- /// These addresses should go to the direct list (we are not connected to any of them)
- pub direct_list: HashSet<AddressWithType>,
-}
-
-/// Takes a list of connection attempts, and determines the target state of the LE ACL manager
-pub fn determine_target_state(attempts: &[ConnectionAttempt]) -> TargetState {
- let background_list = attempts
- .iter()
- .filter(|attempt| attempt.mode == ConnectionMode::Background)
- .map(|attempt| attempt.remote_address)
- .collect();
-
- let direct_list = attempts
- .iter()
- .filter(|attempt| attempt.mode == ConnectionMode::Direct)
- .map(|attempt| attempt.remote_address)
- .collect();
-
- TargetState { background_list, direct_list }
-}
-
-/// This struct monitors the state of the LE connect list,
-/// and drives it to the target state.
-#[derive(Debug)]
-pub struct LeAcceptlistManager {
- /// The connect list in the ACL manager
- direct_list: HashSet<AddressWithType>,
- /// The background connect list in the ACL manager
- background_list: HashSet<AddressWithType>,
- /// An interface into the LE ACL manager (le_impl.h)
- le_manager: Box<dyn LeAclManager>,
-}
-
-impl LeAcceptlistManager {
- /// Constructor
- pub fn new(le_manager: impl LeAclManager + 'static) -> Self {
- Self {
- direct_list: HashSet::new(),
- background_list: HashSet::new(),
- le_manager: Box::new(le_manager),
- }
- }
-
- /// The state of the LE connect list (as per le_impl.h) updates on a completed connection
- pub fn on_connect_complete(&mut self, address: AddressWithType) {
- if address == AddressWithType::EMPTY {
- return;
- }
- // le_impl pulls the device out of the direct connect list (but not the background list) on connection (regardless of status)
- self.direct_list.remove(&address);
- }
-
- /// Drive the state of the connect list to the target state
- pub fn drive_to_state(&mut self, target: TargetState) {
- // First, pull out anything in the ACL manager that we don't need
- // recall that cancel_connect() removes addresses from *both* lists (!)
- for address in self.direct_list.difference(&target.direct_list) {
- info!("Cancelling connection attempt to {address:?}");
- self.le_manager.remove_from_all_lists(*address);
- self.background_list.remove(address);
- }
- self.direct_list = self.direct_list.intersection(&target.direct_list).copied().collect();
-
- for address in self.background_list.difference(&target.background_list) {
- info!("Cancelling connection attempt to {address:?}");
- self.le_manager.remove_from_all_lists(*address);
- self.direct_list.remove(address);
- }
- self.background_list =
- self.background_list.intersection(&target.background_list).copied().collect();
-
- // now everything extra has been removed, we can put things back in
- for address in target.direct_list.difference(&self.direct_list) {
- info!("Starting direct connection to {address:?}");
- self.le_manager.add_to_direct_list(*address);
- }
- for address in target.background_list.difference(&self.background_list) {
- info!("Starting background connection to {address:?}");
- self.le_manager.add_to_background_list(*address);
- }
-
- // we should now be in a consistent state!
- self.direct_list = target.direct_list;
- self.background_list = target.background_list;
- }
-}
-
-#[cfg(test)]
-mod test {
- use crate::{
- connection::{
- le_manager::ErrorCode, mocks::mock_le_manager::MockActiveLeAclManager,
- ConnectionManagerClient,
- },
- core::address::AddressType,
- };
-
- use super::*;
-
- const CLIENT: ConnectionManagerClient = ConnectionManagerClient::GattClient(1);
-
- const ADDRESS_1: AddressWithType =
- AddressWithType { address: [1, 2, 3, 4, 5, 6], address_type: AddressType::Public };
- const ADDRESS_2: AddressWithType =
- AddressWithType { address: [1, 2, 3, 4, 5, 6], address_type: AddressType::Random };
- const ADDRESS_3: AddressWithType =
- AddressWithType { address: [1, 2, 3, 4, 5, 7], address_type: AddressType::Random };
-
- #[test]
- fn test_determine_target_state() {
- let target = determine_target_state(&[
- ConnectionAttempt {
- client: CLIENT,
- mode: ConnectionMode::Background,
- remote_address: ADDRESS_1,
- },
- ConnectionAttempt {
- client: CLIENT,
- mode: ConnectionMode::Background,
- remote_address: ADDRESS_1,
- },
- ConnectionAttempt {
- client: CLIENT,
- mode: ConnectionMode::Background,
- remote_address: ADDRESS_2,
- },
- ConnectionAttempt {
- client: CLIENT,
- mode: ConnectionMode::Direct,
- remote_address: ADDRESS_2,
- },
- ConnectionAttempt {
- client: CLIENT,
- mode: ConnectionMode::Direct,
- remote_address: ADDRESS_3,
- },
- ]);
-
- assert_eq!(target.background_list.len(), 2);
- assert!(target.background_list.contains(&ADDRESS_1));
- assert!(target.background_list.contains(&ADDRESS_2));
- assert_eq!(target.direct_list.len(), 2);
- assert!(target.direct_list.contains(&ADDRESS_2));
- assert!(target.direct_list.contains(&ADDRESS_3));
- }
-
- #[test]
- fn test_add_to_direct_list() {
- // arrange
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
-
- // act: request a device to be present in the direct list
- manager.drive_to_state(TargetState {
- background_list: [].into(),
- direct_list: [ADDRESS_1].into(),
- });
-
- // assert: that the device has been added
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Direct));
- assert_eq!(mock_le_manager.current_acceptlist().len(), 1);
- assert!(mock_le_manager.current_acceptlist().contains(&ADDRESS_1));
- }
-
- #[test]
- fn test_add_to_background_list() {
- // arrange
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
-
- // act: request a device to be present in the direct list
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
-
- // assert: that the device has been added
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Background));
- assert_eq!(mock_le_manager.current_acceptlist().len(), 1);
- assert!(mock_le_manager.current_acceptlist().contains(&ADDRESS_1));
- }
-
- #[test]
- fn test_background_connection_upgrade_to_direct() {
- // arrange: a pending background connection
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
-
- // act: initiate a direct connection to the same device
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [ADDRESS_1].into(),
- });
-
- // assert: we are now doing a direct connection
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Direct));
- }
-
- #[test]
- fn test_direct_connection_cancel_while_background() {
- // arrange: a pending background connection
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
-
- // act: initiate a direct connection to the same device, then remove it
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [ADDRESS_1].into(),
- });
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
-
- // assert: we have returned to a background connection
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Background));
- }
-
- #[test]
- fn test_direct_connection_cancel_then_resume_while_background() {
- // arrange: a pending background connection
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
-
- // act: initiate a direct connection to the same device, cancel it, then resume
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [ADDRESS_1].into(),
- });
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [ADDRESS_1].into(),
- });
-
- // assert: we have returned to a direct connection
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Direct));
- }
-
- #[test]
- fn test_remove_background_connection_then_add() {
- // arrange
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
-
- // act: add then remove a background connection
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
- manager.drive_to_state(TargetState { background_list: [].into(), direct_list: [].into() });
-
- // assert: we have stopped our connection
- assert_eq!(mock_le_manager.current_connection_mode(), None);
- }
-
- #[test]
- fn test_background_connection_remove_then_add() {
- // arrange
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
-
- // act: add, remove, then re-add a background connection
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
- manager.drive_to_state(TargetState { background_list: [].into(), direct_list: [].into() });
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [].into(),
- });
-
- // assert: we resume our background connection
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Background));
- }
- #[test]
- fn test_retry_direct_connection_after_disconnect() {
- // arrange
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
-
- // act: initiate a direct connection
- manager.drive_to_state(TargetState {
- background_list: [].into(),
- direct_list: [ADDRESS_1].into(),
- });
- // act: the connection succeeds (and later disconnects)
- mock_le_manager.on_le_connect(ADDRESS_1, ErrorCode::SUCCESS);
- manager.on_connect_complete(ADDRESS_1);
- // the peer later disconnects
- mock_le_manager.on_le_disconnect(ADDRESS_1);
- // act: retry the direct connection
- manager.drive_to_state(TargetState {
- background_list: [].into(),
- direct_list: [ADDRESS_1].into(),
- });
-
- // assert: we have resumed the direct connection
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Direct));
- assert_eq!(mock_le_manager.current_acceptlist().len(), 1);
- assert!(mock_le_manager.current_acceptlist().contains(&ADDRESS_1));
- }
-
- #[test]
- fn test_background_connection_remove_then_add_while_direct() {
- // arrange: a pending direct connection
- let mock_le_manager = MockActiveLeAclManager::new();
- let mut manager = LeAcceptlistManager::new(mock_le_manager.clone());
- manager.drive_to_state(TargetState {
- background_list: [].into(),
- direct_list: [ADDRESS_1].into(),
- });
-
- // act: add, remove, then re-add a background connection
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [ADDRESS_1].into(),
- });
- manager.drive_to_state(TargetState {
- background_list: [].into(),
- direct_list: [ADDRESS_1].into(),
- });
- manager.drive_to_state(TargetState {
- background_list: [ADDRESS_1].into(),
- direct_list: [ADDRESS_1].into(),
- });
-
- // assert: we remain doing our direct connection
- assert_eq!(mock_le_manager.current_connection_mode(), Some(ConnectionMode::Direct));
- }
-}
diff --git a/system/rust/src/connection/attempt_manager.rs b/system/rust/src/connection/attempt_manager.rs
deleted file mode 100644
index 54a2e66240..0000000000
--- a/system/rust/src/connection/attempt_manager.rs
+++ /dev/null
@@ -1,501 +0,0 @@
-use std::{
- collections::{hash_map::Entry, HashMap},
- future::{Future, IntoFuture},
-};
-
-use tokio::sync::oneshot;
-
-use crate::core::address::AddressWithType;
-
-use super::{
- le_manager::ErrorCode, CancelConnectFailure, ConnectionFailure, ConnectionManagerClient,
- CreateConnectionFailure, LeConnection,
-};
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
-pub enum ConnectionMode {
- Background,
- Direct,
-}
-
-#[derive(Debug)]
-struct ConnectionAttemptData {
- id: AttemptId,
- conn_tx: Option<oneshot::Sender<Result<LeConnection, ErrorCode>>>,
-}
-
-#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
-pub struct ConnectionAttempt {
- pub client: ConnectionManagerClient,
- pub mode: ConnectionMode,
- pub remote_address: AddressWithType,
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct AttemptId(u64);
-
-#[derive(Debug)]
-pub struct ConnectionAttempts {
- attempt_id: AttemptId,
- attempts: HashMap<ConnectionAttempt, ConnectionAttemptData>,
-}
-
-#[derive(Debug)]
-pub struct PendingConnectionAttempt<F> {
- pub id: AttemptId,
- f: F,
-}
-
-impl<F> IntoFuture for PendingConnectionAttempt<F>
-where
- F: Future<Output = Result<LeConnection, ConnectionFailure>>,
-{
- type Output = F::Output;
- type IntoFuture = F;
-
- fn into_future(self) -> Self::IntoFuture {
- self.f
- }
-}
-
-impl ConnectionAttempts {
- /// Constructor
- pub fn new() -> Self {
- Self { attempt_id: AttemptId(0), attempts: HashMap::new() }
- }
-
- fn new_attempt_id(&mut self) -> AttemptId {
- let AttemptId(id) = self.attempt_id;
- self.attempt_id = AttemptId(id.wrapping_add(1));
- AttemptId(id)
- }
-
- /// Register a pending direct connection to the peer. Note that the peer MUST NOT be connected at this point.
- /// Returns the AttemptId of this attempt, as well as a future resolving with the connection (once created) or an
- /// error.
- ///
- /// Note that only one connection attempt from the same (client, address, mode) tuple can be pending at any time.
- ///
- /// # Cancellation Safety
- /// If this future is cancelled, the attempt will NOT BE REMOVED! It must be cancelled explicitly. To avoid
- /// cancelling the wrong future, the returned ID should be used.
- pub fn register_direct_connection(
- &mut self,
- client: ConnectionManagerClient,
- address: AddressWithType,
- ) -> Result<
- PendingConnectionAttempt<impl Future<Output = Result<LeConnection, ConnectionFailure>>>,
- CreateConnectionFailure,
- > {
- let attempt =
- ConnectionAttempt { client, mode: ConnectionMode::Direct, remote_address: address };
-
- let id = self.new_attempt_id();
- let Entry::Vacant(entry) = self.attempts.entry(attempt) else {
- return Err(CreateConnectionFailure::ConnectionAlreadyPending);
- };
- let (tx, rx) = oneshot::channel();
- entry.insert(ConnectionAttemptData { conn_tx: Some(tx), id });
-
- Ok(PendingConnectionAttempt {
- id,
- f: async move {
- rx.await
- .map_err(|_| ConnectionFailure::Cancelled)?
- .map_err(ConnectionFailure::Error)
- },
- })
- }
-
- /// Register a pending background connection to the peer. Returns the AttemptId of this attempt.
- ///
- /// Note that only one connection attempt from the same (client, address, mode) tuple can be pending at any time.
- pub fn register_background_connection(
- &mut self,
- client: ConnectionManagerClient,
- address: AddressWithType,
- ) -> Result<AttemptId, CreateConnectionFailure> {
- let attempt =
- ConnectionAttempt { client, mode: ConnectionMode::Background, remote_address: address };
-
- let id = self.new_attempt_id();
- let Entry::Vacant(entry) = self.attempts.entry(attempt) else {
- return Err(CreateConnectionFailure::ConnectionAlreadyPending);
- };
- entry.insert(ConnectionAttemptData { conn_tx: None, id });
-
- Ok(id)
- }
-
- /// Cancel connection attempts with the specified mode from this client to the specified address.
- pub fn cancel_attempt(
- &mut self,
- client: ConnectionManagerClient,
- address: AddressWithType,
- mode: ConnectionMode,
- ) -> Result<(), CancelConnectFailure> {
- let existing =
- self.attempts.remove(&ConnectionAttempt { client, mode, remote_address: address });
-
- if existing.is_some() {
- // note: dropping the ConnectionAttemptData is sufficient to close the channel and send a cancellation error
- Ok(())
- } else {
- Err(CancelConnectFailure::ConnectionNotPending)
- }
- }
-
- /// Cancel the connection attempt with the given ID.
- pub fn cancel_attempt_with_id(&mut self, id: AttemptId) {
- self.attempts.retain(|_, attempt| attempt.id != id);
- }
-
- /// Cancel all connection attempts to this address
- pub fn remove_unconditionally(&mut self, address: AddressWithType) {
- self.attempts.retain(|attempt, _| attempt.remote_address != address);
- }
-
- /// Cancel all connection attempts from this client
- pub fn remove_client(&mut self, client: ConnectionManagerClient) {
- self.attempts.retain(|attempt, _| attempt.client != client);
- }
-
- /// List all active connection attempts. Note that we can have active background (but NOT) direct
- /// connection attempts to connected devices, as we will resume the connection attempt when the
- /// peer disconnects from us.
- pub fn active_attempts(&self) -> Vec<ConnectionAttempt> {
- self.attempts.keys().cloned().collect()
- }
-
- /// Handle a successful connection by notifying clients and resolving direct connect attempts
- pub fn process_connection(
- &mut self,
- address: AddressWithType,
- result: Result<LeConnection, ErrorCode>,
- ) {
- let interested_clients = self
- .attempts
- .keys()
- .filter(|attempt| attempt.remote_address == address)
- .copied()
- .collect::<Vec<_>>();
-
- for attempt in interested_clients {
- if attempt.mode == ConnectionMode::Direct {
- // TODO(aryarahul): clean up these unwraps
- let _ = self.attempts.remove(&attempt).unwrap().conn_tx.unwrap().send(result);
- } else {
- // TODO(aryarahul): inform background clients of the connection
- }
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use crate::{
- core::address::AddressType,
- utils::task::{block_on_locally, try_await},
- };
-
- use super::*;
-
- const CLIENT_1: ConnectionManagerClient = ConnectionManagerClient::GattClient(1);
- const CLIENT_2: ConnectionManagerClient = ConnectionManagerClient::GattClient(2);
-
- const ADDRESS_1: AddressWithType =
- AddressWithType { address: [1, 2, 3, 4, 5, 6], address_type: AddressType::Public };
- const ADDRESS_2: AddressWithType =
- AddressWithType { address: [1, 2, 3, 4, 5, 6], address_type: AddressType::Random };
-
- const CONNECTION_1: LeConnection = LeConnection { remote_address: ADDRESS_1 };
- const CONNECTION_2: LeConnection = LeConnection { remote_address: ADDRESS_2 };
-
- #[test]
- fn test_direct_connection() {
- block_on_locally(async {
- // arrange
- let mut attempts = ConnectionAttempts::new();
-
- // act: start a pending direct connection
- let _ = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // assert: this attempt is pending
- assert_eq!(attempts.active_attempts().len(), 1);
- assert_eq!(attempts.active_attempts()[0].client, CLIENT_1);
- assert_eq!(attempts.active_attempts()[0].mode, ConnectionMode::Direct);
- assert_eq!(attempts.active_attempts()[0].remote_address, ADDRESS_1);
- });
- }
-
- #[test]
- fn test_cancel_direct_connection() {
- block_on_locally(async {
- // arrange: one pending direct connection
- let mut attempts = ConnectionAttempts::new();
- let pending_direct_connection =
- attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // act: cancel it
- attempts.cancel_attempt(CLIENT_1, ADDRESS_1, ConnectionMode::Direct).unwrap();
- let resp = pending_direct_connection.await;
-
- // assert: the original future resolved, and the attempt is cleared
- assert_eq!(resp, Err(ConnectionFailure::Cancelled));
- assert!(attempts.active_attempts().is_empty());
- });
- }
-
- #[test]
- fn test_multiple_direct_connections() {
- block_on_locally(async {
- // arrange
- let mut attempts = ConnectionAttempts::new();
-
- // act: start two direct connections
- attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- attempts.register_direct_connection(CLIENT_2, ADDRESS_1).unwrap();
-
- // assert: both attempts are pending
- assert_eq!(attempts.active_attempts().len(), 2);
- });
- }
-
- #[test]
- fn test_two_direct_connection_cancel_one() {
- block_on_locally(async {
- // arrange: two pending direct connections
- let mut attempts = ConnectionAttempts::new();
- attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- attempts.register_direct_connection(CLIENT_2, ADDRESS_1).unwrap();
-
- // act: cancel one
- attempts.cancel_attempt(CLIENT_1, ADDRESS_1, ConnectionMode::Direct).unwrap();
-
- // assert: one attempt is still pending
- assert_eq!(attempts.active_attempts().len(), 1);
- assert_eq!(attempts.active_attempts()[0].client, CLIENT_2);
- });
- }
-
- #[test]
- fn test_drop_pending_connection_after_cancel_and_restart() {
- // arrange
- let mut attempts = ConnectionAttempts::new();
-
- // act: start one pending direct connection, cancel it, restart it, and then drop the first future
- let pending_1 = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- attempts.cancel_attempt(CLIENT_1, ADDRESS_1, ConnectionMode::Direct).unwrap();
- let _pending_2 = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- drop(pending_1);
-
- // assert: the restart is still pending
- assert_eq!(attempts.active_attempts().len(), 1);
- }
-
- #[test]
- fn test_background_connection() {
- block_on_locally(async {
- // arrange
- let mut attempts = ConnectionAttempts::new();
-
- // act: start a pending background connection
- attempts.register_background_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // assert: this attempt is pending
- assert_eq!(attempts.active_attempts().len(), 1);
- assert_eq!(attempts.active_attempts()[0].client, CLIENT_1);
- assert_eq!(attempts.active_attempts()[0].mode, ConnectionMode::Background);
- assert_eq!(attempts.active_attempts()[0].remote_address, ADDRESS_1);
- });
- }
-
- #[test]
- fn test_reject_duplicate_direct_connection() {
- block_on_locally(async {
- // arrange
- let mut attempts = ConnectionAttempts::new();
-
- // act: start two background connections with the same parameters
- let _fut = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- let ret = attempts.register_direct_connection(CLIENT_1, ADDRESS_1);
-
- // assert: this attempt is pending
- assert!(matches!(ret, Err(CreateConnectionFailure::ConnectionAlreadyPending)));
- });
- }
-
- #[test]
- fn test_reject_duplicate_background_connection() {
- block_on_locally(async {
- // arrange
- let mut attempts = ConnectionAttempts::new();
-
- // act: start two background connections with the same parameters
- attempts.register_background_connection(CLIENT_1, ADDRESS_1).unwrap();
- let ret = attempts.register_background_connection(CLIENT_1, ADDRESS_1);
-
- // assert: this attempt is pending
- assert_eq!(ret, Err(CreateConnectionFailure::ConnectionAlreadyPending));
- });
- }
-
- #[test]
- fn test_resolved_direct_connection() {
- block_on_locally(async {
- // arrange: one pending direct connection
- let mut attempts = ConnectionAttempts::new();
- let pending_conn = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // act: resolve with an incoming connection
- attempts.process_connection(ADDRESS_1, Ok(CONNECTION_1));
-
- // assert: the attempt is resolved and is no longer active
- assert_eq!(pending_conn.await.unwrap(), CONNECTION_1);
- assert!(attempts.active_attempts().is_empty());
- });
- }
-
- #[test]
- fn test_failed_direct_connection() {
- block_on_locally(async {
- // arrange: one pending direct connection
- let mut attempts = ConnectionAttempts::new();
- let pending_conn = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // act: resolve with an incoming connection
- attempts.process_connection(ADDRESS_1, Err(ErrorCode(1)));
-
- // assert: the attempt is resolved and is no longer active
- assert_eq!(pending_conn.await, Err(ConnectionFailure::Error(ErrorCode(1))));
- assert!(attempts.active_attempts().is_empty());
- });
- }
-
- #[test]
- fn test_resolved_background_connection() {
- block_on_locally(async {
- // arrange: one pending direct connection
- let mut attempts = ConnectionAttempts::new();
- attempts.register_background_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // act: resolve with an incoming connection
- attempts.process_connection(ADDRESS_1, Ok(CONNECTION_1));
-
- // assert: the attempt is still active
- assert_eq!(attempts.active_attempts().len(), 1);
- });
- }
-
- #[test]
- fn test_incoming_connection_while_another_is_pending() {
- block_on_locally(async {
- // arrange: one pending direct connection
- let mut attempts = ConnectionAttempts::new();
- let pending_conn = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // act: an incoming connection arrives to a different address
- attempts.process_connection(ADDRESS_2, Ok(CONNECTION_2));
-
- // assert: the attempt is still pending
- assert!(try_await(pending_conn).await.is_err());
- assert_eq!(attempts.active_attempts().len(), 1);
- });
- }
-
- #[test]
- fn test_incoming_connection_resolves_some_but_not_all() {
- block_on_locally(async {
- // arrange: one pending direct connection and one background connection to each of two addresses
- let mut attempts = ConnectionAttempts::new();
- let pending_conn_1 = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- let pending_conn_2 = attempts.register_direct_connection(CLIENT_1, ADDRESS_2).unwrap();
- attempts.register_background_connection(CLIENT_1, ADDRESS_1).unwrap();
- attempts.register_background_connection(CLIENT_1, ADDRESS_2).unwrap();
-
- // act: an incoming connection arrives to the first address
- attempts.process_connection(ADDRESS_1, Ok(CONNECTION_1));
-
- // assert: one direct attempt is completed, one is still pending
- assert_eq!(pending_conn_1.await, Ok(CONNECTION_1));
- assert!(try_await(pending_conn_2).await.is_err());
- // three attempts remain (the unresolved direct, and both background attempts)
- assert_eq!(attempts.active_attempts().len(), 3);
- });
- }
-
- #[test]
- fn test_remove_background_connection() {
- block_on_locally(async {
- // arrange: one pending background connection
- let mut attempts = ConnectionAttempts::new();
- attempts.register_background_connection(CLIENT_1, ADDRESS_1).unwrap();
-
- // act: remove it
- attempts.cancel_attempt(CLIENT_1, ADDRESS_1, ConnectionMode::Background).unwrap();
-
- // assert: no pending attempts
- assert!(attempts.active_attempts().is_empty());
- });
- }
-
- #[test]
- fn test_cancel_nonexistent_connection() {
- block_on_locally(async {
- // arrange
- let mut attempts = ConnectionAttempts::new();
-
- // act: cancel a nonexistent direct connection
- let resp = attempts.cancel_attempt(CLIENT_1, ADDRESS_1, ConnectionMode::Direct);
-
- // assert: got an error
- assert_eq!(resp, Err(CancelConnectFailure::ConnectionNotPending));
- });
- }
-
- #[test]
- fn test_remove_unconditionally() {
- block_on_locally(async {
- // arrange: one pending direct connection, and one background connection, to each address
- let mut attempts = ConnectionAttempts::new();
- let pending_conn_1 = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- let pending_conn_2 = attempts.register_direct_connection(CLIENT_1, ADDRESS_2).unwrap();
- attempts.register_background_connection(CLIENT_1, ADDRESS_1).unwrap();
- attempts.register_background_connection(CLIENT_1, ADDRESS_2).unwrap();
-
- // act: cancel all connections to the first address
- attempts.remove_unconditionally(ADDRESS_1);
-
- // assert: one direct attempt is completed, one is still pending
- assert_eq!(pending_conn_1.await, Err(ConnectionFailure::Cancelled));
- assert!(try_await(pending_conn_2).await.is_err());
- // assert: two attempts remain, both to the other address
- assert_eq!(attempts.active_attempts().len(), 2);
- assert_eq!(attempts.active_attempts()[0].remote_address, ADDRESS_2);
- assert_eq!(attempts.active_attempts()[1].remote_address, ADDRESS_2);
- });
- }
-
- #[test]
- fn test_remove_client() {
- block_on_locally(async {
- // arrange: one pending direct connection, and one background connection, from each address
- let mut attempts = ConnectionAttempts::new();
- let pending_conn_1 = attempts.register_direct_connection(CLIENT_1, ADDRESS_1).unwrap();
- let pending_conn_2 = attempts.register_direct_connection(CLIENT_2, ADDRESS_1).unwrap();
- attempts.register_background_connection(CLIENT_1, ADDRESS_1).unwrap();
- attempts.register_background_connection(CLIENT_2, ADDRESS_1).unwrap();
-
- // act: remove the first client
- attempts.remove_client(CLIENT_1);
-
- // assert: one direct attempt is completed, one is still pending
- assert_eq!(pending_conn_1.await, Err(ConnectionFailure::Cancelled));
- assert!(try_await(pending_conn_2).await.is_err());
- // assert: two attempts remain, both from the second client
- assert_eq!(attempts.active_attempts().len(), 2);
- assert_eq!(attempts.active_attempts()[0].client, CLIENT_2);
- assert_eq!(attempts.active_attempts()[1].client, CLIENT_2);
- });
- }
-}
diff --git a/system/rust/src/connection/ffi.rs b/system/rust/src/connection/ffi.rs
deleted file mode 100644
index 82a98582de..0000000000
--- a/system/rust/src/connection/ffi.rs
+++ /dev/null
@@ -1,242 +0,0 @@
-//! FFI interfaces for the Connection module.
-
-use std::{fmt::Debug, pin::Pin};
-
-use cxx::UniquePtr;
-pub use inner::*;
-use log::warn;
-use tokio::{
- sync::mpsc::{unbounded_channel, UnboundedSender},
- task::spawn_local,
-};
-
-use crate::do_in_rust_thread;
-
-use super::{
- attempt_manager::ConnectionMode,
- le_manager::{ErrorCode, InactiveLeAclManager, LeAclManager, LeAclManagerConnectionCallbacks},
- ConnectionManagerClient, LeConnection,
-};
-
-// SAFETY: `LeAclManagerShim` can be passed between threads.
-unsafe impl Send for LeAclManagerShim {}
-
-#[cxx::bridge]
-#[allow(clippy::needless_lifetimes)]
-#[allow(clippy::needless_maybe_sized)]
-#[allow(clippy::too_many_arguments)]
-#[allow(missing_docs)]
-#[allow(unsafe_op_in_unsafe_fn)]
-mod inner {
- impl UniquePtr<LeAclManagerShim> {}
-
- #[namespace = "bluetooth::core"]
- extern "C++" {
- type AddressWithType = crate::core::address::AddressWithType;
- }
-
- #[namespace = "bluetooth::connection"]
- unsafe extern "C++" {
- include!("src/connection/ffi/connection_shim.h");
-
- /// This lets us send HCI commands, either directly,
- /// or via the address manager
- type LeAclManagerShim;
-
- /// Add address to direct/background connect list, if not already connected
- /// If connected, then adding to direct list is a no-op, but adding to the
- /// background list will still take place.
- #[cxx_name = "CreateLeConnection"]
- fn create_le_connection(&self, address: AddressWithType, is_direct: bool);
-
- /// Remove address from both direct + background connect lists
- #[cxx_name = "CancelLeConnect"]
- fn cancel_le_connect(&self, address: AddressWithType);
-
- /// Register Rust callbacks for connection events
- ///
- /// # Safety
- ///
- /// `callbacks` must be Send + Sync, since C++ moves it to a different thread and
- /// invokes it from several others (GD + legacy threads).
- #[allow(clippy::missing_safety_doc)]
- #[cxx_name = "RegisterRustCallbacks"]
- unsafe fn unchecked_register_rust_callbacks(
- self: Pin<&mut Self>,
- callbacks: Box<LeAclManagerCallbackShim>,
- );
- }
-
- #[namespace = "bluetooth::connection"]
- extern "Rust" {
- type LeAclManagerCallbackShim;
- #[cxx_name = "OnLeConnectSuccess"]
- fn on_le_connect_success(&self, address: AddressWithType);
- #[cxx_name = "OnLeConnectFail"]
- fn on_le_connect_fail(&self, address: AddressWithType, status: u8);
- #[cxx_name = "OnLeDisconnection"]
- fn on_disconnect(&self, address: AddressWithType);
- }
-
- #[namespace = "bluetooth::connection"]
- unsafe extern "C++" {
- include!("stack/arbiter/acl_arbiter.h");
-
- /// Register APIs exposed by Rust
- fn RegisterRustApis(
- start_direct_connection: fn(client_id: u8, address: AddressWithType),
- stop_direct_connection: fn(client_id: u8, address: AddressWithType),
- add_background_connection: fn(client_id: u8, address: AddressWithType),
- remove_background_connection: fn(client_id: u8, address: AddressWithType),
- remove_client: fn(client_id: u8),
- stop_all_connections_to_device: fn(address: AddressWithType),
- );
- }
-}
-
-impl LeAclManagerShim {
- fn register_rust_callbacks(
- self: Pin<&mut LeAclManagerShim>,
- callbacks: Box<LeAclManagerCallbackShim>,
- ) where
- Box<LeAclManagerCallbackShim>: Send + Sync,
- {
- // SAFETY: The requirements of this method are enforced
- // by our own trait bounds.
- unsafe {
- self.unchecked_register_rust_callbacks(callbacks);
- }
- }
-}
-
-/// Implementation of HciConnectProxy wrapping the corresponding C++ methods
-pub struct LeAclManagerImpl(pub UniquePtr<LeAclManagerShim>);
-
-pub struct LeAclManagerCallbackShim(
- UnboundedSender<Box<dyn FnOnce(&dyn LeAclManagerConnectionCallbacks) + Send>>,
-);
-
-impl LeAclManagerCallbackShim {
- fn on_le_connect_success(&self, address: AddressWithType) {
- let _ = self.0.send(Box::new(move |callback| {
- callback.on_le_connect(address, Ok(LeConnection { remote_address: address }))
- }));
- }
-
- fn on_le_connect_fail(&self, address: AddressWithType, status: u8) {
- let _ = self.0.send(Box::new(move |callback| {
- callback.on_le_connect(address, Err(ErrorCode(status)))
- }));
- }
-
- fn on_disconnect(&self, address: AddressWithType) {
- let _ = self.0.send(Box::new(move |callback| {
- callback.on_disconnect(address);
- }));
- }
-}
-
-impl InactiveLeAclManager for LeAclManagerImpl {
- type ActiveManager = Self;
-
- fn register_callbacks(
- mut self,
- callbacks: impl LeAclManagerConnectionCallbacks + 'static,
- ) -> Self::ActiveManager {
- let (tx, mut rx) = unbounded_channel();
-
- // only register callbacks if the feature is enabled
- if bluetooth_aconfig_flags_rust::unified_connection_manager() {
- self.0.pin_mut().register_rust_callbacks(Box::new(LeAclManagerCallbackShim(tx)));
- }
-
- spawn_local(async move {
- while let Some(f) = rx.recv().await {
- f(&callbacks)
- }
- });
- self
- }
-}
-
-impl LeAclManager for LeAclManagerImpl {
- fn add_to_direct_list(&self, address: AddressWithType) {
- self.0.create_le_connection(address, /* is_direct= */ true)
- }
-
- fn add_to_background_list(&self, address: AddressWithType) {
- self.0.create_le_connection(address, /* is_direct= */ false)
- }
-
- fn remove_from_all_lists(&self, address: AddressWithType) {
- self.0.cancel_le_connect(address)
- }
-}
-
-impl Debug for LeAclManagerImpl {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_tuple("LeAclManagerImpl").finish()
- }
-}
-
-/// Registers all connection-manager callbacks into C++ dependencies
-pub fn register_callbacks() {
- RegisterRustApis(
- |client, address| {
- let client = ConnectionManagerClient::GattClient(client);
- do_in_rust_thread(move |modules| {
- let result =
- modules.connection_manager.as_ref().start_direct_connection(client, address);
- if let Err(err) = result {
- warn!("Failed to start direct connection from {client:?} to {address:?} ({err:?})")
- }
- });
- },
- |client, address| {
- let client = ConnectionManagerClient::GattClient(client);
- do_in_rust_thread(move |modules| {
- let result = modules.connection_manager.cancel_connection(
- client,
- address,
- ConnectionMode::Direct,
- );
- if let Err(err) = result {
- warn!("Failed to cancel direct connection from {client:?} to {address:?} ({err:?})")
- }
- })
- },
- |client, address| {
- let client = ConnectionManagerClient::GattClient(client);
- do_in_rust_thread(move |modules| {
- let result = modules.connection_manager.add_background_connection(client, address);
- if let Err(err) = result {
- warn!("Failed to add background connection from {client:?} to {address:?} ({err:?})")
- }
- })
- },
- |client, address| {
- let client = ConnectionManagerClient::GattClient(client);
- do_in_rust_thread(move |modules| {
- let result = modules.connection_manager.cancel_connection(
- client,
- address,
- ConnectionMode::Background,
- );
- if let Err(err) = result {
- warn!("Failed to remove background connection from {client:?} to {address:?} ({err:?})")
- }
- })
- },
- |client| {
- let client = ConnectionManagerClient::GattClient(client);
- do_in_rust_thread(move |modules| {
- modules.connection_manager.remove_client(client);
- })
- },
- |address| {
- do_in_rust_thread(move |modules| {
- modules.connection_manager.cancel_unconditionally(address);
- })
- },
- )
-}
diff --git a/system/rust/src/connection/ffi/connection_shim.cc b/system/rust/src/connection/ffi/connection_shim.cc
deleted file mode 100644
index 1ff23b9629..0000000000
--- a/system/rust/src/connection/ffi/connection_shim.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2023, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "connection_shim.h"
-
-#include <bluetooth/log.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <iterator>
-#include <optional>
-
-#include "hci/acl_manager.h"
-#include "hci/address_with_type.h"
-#include "hci/hci_packets.h"
-#include "main/shim/entry.h"
-#ifndef TARGET_FLOSS
-#include "src/connection/ffi.rs.h"
-#endif
-#include "src/core/ffi/types.h"
-#include "stack/btm/btm_dev.h"
-
-namespace bluetooth {
-namespace connection {
-
-#ifdef TARGET_FLOSS
-struct LeAclManagerCallbackShim {
- void OnLeConnectSuccess(core::AddressWithType addr) const {
- log::fatal("system/rust not available in Floss");
- }
- void OnLeConnectFail(core::AddressWithType addr, uint8_t status) const {
- log::fatal("system/rust not available in Floss");
- }
- void OnLeDisconnection(core::AddressWithType addr) const {
- log::fatal("system/rust not available in Floss");
- }
-};
-
-using BoxedLeAclManagerCallbackShim = std::unique_ptr<LeAclManagerCallbackShim>;
-
-#else
-
-using BoxedLeAclManagerCallbackShim = ::rust::Box<LeAclManagerCallbackShim>;
-
-#endif
-
-namespace {
-hci::AddressWithType ToCppAddress(core::AddressWithType address) {
- auto hci_address = hci::Address();
- hci_address.FromOctets(address.address.data());
- return hci::AddressWithType(hci_address, (hci::AddressType)address.address_type);
-}
-
-core::AddressWithType ToRustAddress(hci::AddressWithType address) {
- return core::AddressWithType{address.GetAddress().address,
- (core::AddressType)address.GetAddressType()};
-}
-} // namespace
-
-struct LeAclManagerShim::impl : hci::acl_manager::LeAcceptlistCallbacks {
-public:
- impl() { acl_manager_ = shim::GetAclManager(); }
-
- ~impl() {
- if (callbacks_.has_value()) {
- callbacks_.reset();
- auto promise = std::promise<void>();
- auto future = promise.get_future();
- acl_manager_->UnregisterLeAcceptlistCallbacks(this, std::move(promise));
- future.wait();
- }
- }
-
- void CreateLeConnection(core::AddressWithType address, bool is_direct) {
- acl_manager_->CreateLeConnection(ToCppAddress(address), is_direct);
- }
-
- void CancelLeConnect(core::AddressWithType address) {
- acl_manager_->CancelLeConnect(ToCppAddress(address));
- }
-
-#ifndef TARGET_FLOSS
- void RegisterRustCallbacks(BoxedLeAclManagerCallbackShim callbacks) {
- callbacks_ = std::move(callbacks);
- acl_manager_->RegisterLeAcceptlistCallbacks(this);
- }
-#endif
-
- // hci::acl_manager::LeAcceptlistCallbacks
- virtual void OnLeConnectSuccess(hci::AddressWithType address) {
- callbacks_.value()->OnLeConnectSuccess(ToRustAddress(address));
- }
-
- // hci::acl_manager::LeAcceptlistCallbacks
- virtual void OnLeConnectFail(hci::AddressWithType address, hci::ErrorCode reason) {
- callbacks_.value()->OnLeConnectFail(ToRustAddress(address), static_cast<uint8_t>(reason));
- }
-
- // hci::acl_manager::LeAcceptlistCallbacks
- virtual void OnLeDisconnection(hci::AddressWithType address) {
- callbacks_.value()->OnLeDisconnection(ToRustAddress(address));
- }
-
- // hci::acl_manager::LeAcceptlistCallbacks
- virtual void OnResolvingListChange() {}
-
-private:
- std::optional<BoxedLeAclManagerCallbackShim> callbacks_;
- hci::AclManager* acl_manager_{};
-};
-
-LeAclManagerShim::LeAclManagerShim() { pimpl_ = std::make_unique<LeAclManagerShim::impl>(); }
-
-LeAclManagerShim::~LeAclManagerShim() = default;
-
-void LeAclManagerShim::CreateLeConnection(core::AddressWithType address, bool is_direct) const {
- pimpl_->CreateLeConnection(address, is_direct);
-}
-
-void LeAclManagerShim::CancelLeConnect(core::AddressWithType address) const {
- pimpl_->CancelLeConnect(address);
-}
-
-#ifndef TARGET_FLOSS
-void LeAclManagerShim::RegisterRustCallbacks(BoxedLeAclManagerCallbackShim callbacks) {
- pimpl_->RegisterRustCallbacks(std::move(callbacks));
-}
-#endif
-
-namespace {
-
-std::optional<RustConnectionManager> connection_manager;
-
-} // namespace
-
-RustConnectionManager& GetConnectionManager() { return connection_manager.value(); }
-
-void RegisterRustApis(
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)> start_direct_connection,
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)> stop_direct_connection,
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
- add_background_connection,
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
- remove_background_connection,
- ::rust::Fn<void(uint8_t client_id)> remove_client,
- ::rust::Fn<void(core::AddressWithType address)> stop_all_connections_to_device) {
- connection_manager = {
- start_direct_connection, stop_direct_connection, add_background_connection,
- remove_background_connection, remove_client, stop_all_connections_to_device};
-}
-
-core::AddressWithType ResolveRawAddress(RawAddress bd_addr) {
- tBLE_BD_ADDR address = BTM_Sec_GetAddressWithType(bd_addr);
- return core::ToRustAddress(address);
-}
-
-} // namespace connection
-} // namespace bluetooth
diff --git a/system/rust/src/connection/ffi/connection_shim.h b/system/rust/src/connection/ffi/connection_shim.h
deleted file mode 100644
index 5346c07db9..0000000000
--- a/system/rust/src/connection/ffi/connection_shim.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2023, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-
-#include "rust/cxx.h"
-#include "rust/src/core/ffi/types.h"
-#include "types/ble_address_with_type.h"
-
-namespace bluetooth {
-
-namespace connection {
-
-struct LeAclManagerCallbackShim;
-
-class LeAclManagerShim {
-public:
- LeAclManagerShim();
- ~LeAclManagerShim();
-
- void CreateLeConnection(core::AddressWithType address, bool is_direct) const;
-
- void CancelLeConnect(core::AddressWithType address) const;
-
-#ifndef TARGET_FLOSS
- void RegisterRustCallbacks(::rust::Box<LeAclManagerCallbackShim> callbacks);
-#endif
-
-private:
- struct impl;
- std::unique_ptr<impl> pimpl_;
-};
-
-void RegisterRustApis(
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)> start_direct_connection,
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)> stop_direct_connection,
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
- add_background_connection,
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
- remove_background_connection,
- ::rust::Fn<void(uint8_t client_id)> remove_client,
- ::rust::Fn<void(core::AddressWithType address)> stop_all_connections_to_device);
-
-struct RustConnectionManager {
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)> start_direct_connection;
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)> stop_direct_connection;
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)> add_background_connection;
- ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)> remove_background_connection;
- ::rust::Fn<void(uint8_t client_id)> remove_client;
- ::rust::Fn<void(core::AddressWithType address)> stop_all_connections_to_device;
-};
-
-RustConnectionManager& GetConnectionManager();
-
-core::AddressWithType ResolveRawAddress(RawAddress bd_addr);
-
-} // namespace connection
-} // namespace bluetooth
diff --git a/system/rust/src/connection/le_manager.rs b/system/rust/src/connection/le_manager.rs
deleted file mode 100644
index fa55118d08..0000000000
--- a/system/rust/src/connection/le_manager.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-//! This trait represents the lower-level operations
-//! made available to the connection manager. In particular,
-//! we can add devices to either the "direct" or "background"
-//! connect list, which are in turn mapped to an appropriate choice
-//! of scan parameters / the filter accept list.
-//!
-//! Note that the ACL manager is unaware of address resolution,
-//! so this must be handled by the connection manager. Conversely, the connection
-//! manager does not need to consider the HCI state machine, and can send requests
-//! at any time.
-//!
-//! In addition to the supplied API, when a connection completes to a peer device,
-//! it is removed from the "direct" connect list (based on exact address match).
-
-use std::fmt::Debug;
-
-use crate::core::address::AddressWithType;
-
-use super::LeConnection;
-
-/// An HCI Error Code from the controller
-#[derive(Copy, Clone, Eq, PartialEq, Debug)]
-pub struct ErrorCode(pub u8);
-
-impl ErrorCode {
- /// Operation completed successfully
- pub const SUCCESS: Self = ErrorCode(0);
-}
-
-/// The LeAclManager before callbacks are registered
-pub trait InactiveLeAclManager {
- /// The type implementing LeAclManager once callbacks are registered
- type ActiveManager: LeAclManager + 'static;
-
- /// Register callbacks for connection events, and produuce an ActiveManager
- fn register_callbacks(
- self,
- callbacks: impl LeAclManagerConnectionCallbacks + 'static,
- ) -> Self::ActiveManager;
-}
-
-/// The operations provided by GD AclManager to the connection manager
-pub trait LeAclManager: Debug {
- /// Adds an address to the direct connect list, if not already connected.
- /// WARNING: the connection timeout is set the FIRST time the address is added, and is
- /// NOT RESET! TODO(aryarahul): remove connection timeout from le_impl since it belongs here instead
- /// Precondition: Must NOT be currently connected to this adddress (if connected due to race, is a no-op)
- fn add_to_direct_list(&self, address: AddressWithType); // CreateLeConnection(is_direct=true)
- /// Adds an address to the background connect list
- fn add_to_background_list(&self, address: AddressWithType); // CreateLeConnection(is_direct=false)
- /// Removes address from both the direct + background connect lists
- /// Due to races, it is possible to call this, and THEN get a connection complete with us as central
- fn remove_from_all_lists(&self, address: AddressWithType); // CancelLeConnect
-}
-
-/// The callbacks invoked by the LeAclManager in response to events from the controller
-pub trait LeAclManagerConnectionCallbacks {
- /// Invoked when an LE connection to a given address completes
- fn on_le_connect(&self, address: AddressWithType, result: Result<LeConnection, ErrorCode>);
- /// Invoked when a peer device disconnects from us. The address must match the address
- /// supplied on the initial connection.
- fn on_disconnect(&self, address: AddressWithType);
-}
diff --git a/system/rust/src/connection/mocks.rs b/system/rust/src/connection/mocks.rs
deleted file mode 100644
index b50e621a89..0000000000
--- a/system/rust/src/connection/mocks.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#[cfg(test)]
-pub mod mock_le_manager;
diff --git a/system/rust/src/connection/mocks/mock_le_manager.rs b/system/rust/src/connection/mocks/mock_le_manager.rs
deleted file mode 100644
index 879acfac28..0000000000
--- a/system/rust/src/connection/mocks/mock_le_manager.rs
+++ /dev/null
@@ -1,174 +0,0 @@
-//! This module mocks the behavior of le_impl in GD (excluding timers).
-//! It tracks both the internal state of le_impl, as well as the connect list in the controller.
-//! It also enforces all (implicit) invariants of le_impl as documented in le_manager.rs, and
-//! asserts on violation.
-
-use std::{cell::RefCell, collections::HashSet, fmt::Debug, rc::Rc};
-
-use crate::{
- connection::{
- attempt_manager::ConnectionMode,
- le_manager::{
- ErrorCode, InactiveLeAclManager, LeAclManager, LeAclManagerConnectionCallbacks,
- },
- LeConnection,
- },
- core::address::AddressWithType,
-};
-
-#[derive(Clone)]
-pub struct MockLeAclManager {
- active: Rc<RefCell<Option<Rc<MockActiveLeAclManager>>>>,
- callbacks: Rc<RefCell<Option<Box<dyn LeAclManagerConnectionCallbacks>>>>,
-}
-
-impl MockLeAclManager {
- pub fn new() -> Self {
- Self { active: Rc::new(RefCell::new(None)), callbacks: Rc::new(RefCell::new(None)) }
- }
-
- fn inner(&self) -> Rc<MockActiveLeAclManager> {
- self.active.borrow().as_ref().unwrap().clone()
- }
-
- pub fn current_acceptlist(&self) -> HashSet<AddressWithType> {
- self.inner().current_acceptlist()
- }
-
- pub fn current_connection_mode(&self) -> Option<ConnectionMode> {
- self.inner().current_connection_mode()
- }
-
- pub fn on_le_connect(&self, address: AddressWithType, status: ErrorCode) {
- let inner = self.inner();
- inner.on_le_connect(address, status);
- drop(inner);
-
- if status == ErrorCode::SUCCESS {
- self.callbacks
- .borrow()
- .as_deref()
- .unwrap()
- .on_le_connect(address, Ok(LeConnection { remote_address: address }));
- } else {
- self.callbacks.borrow().as_deref().unwrap().on_le_connect(address, Err(status));
- }
- }
-
- pub fn on_le_disconnect(&self, address: AddressWithType) {
- let inner = self.inner();
- inner.on_le_disconnect(address);
- drop(inner);
-
- self.callbacks.borrow().as_deref().unwrap().on_disconnect(address);
- }
-}
-
-impl InactiveLeAclManager for MockLeAclManager {
- type ActiveManager = Rc<MockActiveLeAclManager>;
-
- fn register_callbacks(
- self,
- callbacks: impl LeAclManagerConnectionCallbacks + 'static,
- ) -> Self::ActiveManager {
- let out = MockActiveLeAclManager::new();
- *self.active.borrow_mut() = Some(out.clone());
- *self.callbacks.borrow_mut() = Some(Box::new(callbacks));
- out
- }
-}
-
-#[derive(Debug)]
-pub struct MockActiveLeAclManager {
- state: RefCell<MockLeManagerInternalState>,
-}
-
-#[derive(Clone, Debug)]
-struct MockLeManagerInternalState {
- direct_connect_list: HashSet<AddressWithType>,
- background_connect_list: HashSet<AddressWithType>,
- currently_connected: HashSet<AddressWithType>,
-}
-
-impl MockActiveLeAclManager {
- pub fn new() -> Rc<Self> {
- Rc::new(MockActiveLeAclManager {
- state: RefCell::new(MockLeManagerInternalState {
- direct_connect_list: HashSet::new(),
- background_connect_list: HashSet::new(),
- currently_connected: HashSet::new(),
- }),
- })
- }
-
- pub fn current_acceptlist(&self) -> HashSet<AddressWithType> {
- let state = self.state.borrow();
- &(&state.direct_connect_list | &state.background_connect_list)
- - (&state.currently_connected)
- }
-
- pub fn current_connection_mode(&self) -> Option<ConnectionMode> {
- let state = self.state.borrow();
-
- if !state.direct_connect_list.is_empty() {
- Some(ConnectionMode::Direct)
- } else if state
- .background_connect_list
- .difference(&state.currently_connected)
- .next()
- .is_some()
- {
- Some(ConnectionMode::Background)
- } else {
- None
- }
- }
-
- pub fn on_le_connect(&self, address: AddressWithType, status: ErrorCode) {
- let mut state = self.state.borrow_mut();
- state.direct_connect_list.remove(&address);
- if status == ErrorCode::SUCCESS {
- let ok = state.currently_connected.insert(address);
- assert!(ok, "Already connected");
- }
- }
-
- pub fn on_le_disconnect(&self, address: AddressWithType) {
- let mut state = self.state.borrow_mut();
- let ok = state.currently_connected.remove(&address);
- assert!(ok, "Not connected");
- }
-}
-
-impl LeAclManager for Rc<MockActiveLeAclManager> {
- fn add_to_direct_list(&self, address: AddressWithType) {
- let mut state = self.state.borrow_mut();
- assert!(
- !state.currently_connected.contains(&address),
- "Must NOT be currently connected to this address"
- );
- let ok = state.direct_connect_list.insert(address);
- assert!(ok, "Already in direct connect list");
- }
-
- fn add_to_background_list(&self, address: AddressWithType) {
- let mut state = self.state.borrow_mut();
- assert!(
- !state.currently_connected.contains(&address),
- "Must NOT be currently connected to this address"
- );
- let ok = state.background_connect_list.insert(address);
- assert!(ok, "Already in background connect list");
- }
-
- fn remove_from_all_lists(&self, address: AddressWithType) {
- let mut state = self.state.borrow_mut();
- assert!(
- !state.currently_connected.contains(&address),
- "Must NOT be currently connected to this address"
- );
- let ok1 = state.direct_connect_list.remove(&address);
- let ok2 = state.background_connect_list.remove(&address);
- assert!(ok1 || ok2, "Present in neither direct nor background connect list");
- }
-}
diff --git a/system/rust/src/core/ffi.rs b/system/rust/src/core/ffi.rs
index e69002def9..c81235d7f1 100644
--- a/system/rust/src/core/ffi.rs
+++ b/system/rust/src/core/ffi.rs
@@ -75,17 +75,10 @@ mod inner {
type GattServerCallbacks = crate::gatt::GattServerCallbacks;
}
- #[namespace = "bluetooth::connection"]
- unsafe extern "C++" {
- include!("src/connection/ffi/connection_shim.h");
- type LeAclManagerShim = crate::connection::LeAclManagerShim;
- }
-
#[namespace = "bluetooth::rust_shim"]
extern "Rust" {
fn start(
gatt_server_callbacks: UniquePtr<GattServerCallbacks>,
- le_acl_manager: UniquePtr<LeAclManagerShim>,
on_started: Pin<&'static mut Future>,
);
diff --git a/system/rust/src/core/ffi/module.cc b/system/rust/src/core/ffi/module.cc
index f43e19a1f8..5e79d143fa 100644
--- a/system/rust/src/core/ffi/module.cc
+++ b/system/rust/src/core/ffi/module.cc
@@ -22,7 +22,6 @@
#include "btcore/include/module.h"
#include "os/log.h"
#ifndef TARGET_FLOSS
-#include "src/connection/ffi/connection_shim.h"
#include "src/core/ffi.rs.h"
#include "src/gatt/ffi.rs.h"
#endif
@@ -65,8 +64,7 @@ future_t* Start() {
return fut;
}
bluetooth::rust_shim::start(
- std::make_unique<bluetooth::gatt::GattServerCallbacks>(*callbacks->server),
- std::make_unique<bluetooth::connection::LeAclManagerShim>(), *fut);
+ std::make_unique<bluetooth::gatt::GattServerCallbacks>(*callbacks->server), *fut);
return fut;
}
diff --git a/system/rust/src/core/mod.rs b/system/rust/src/core/mod.rs
index 2f48f19619..3d25dae585 100644
--- a/system/rust/src/core/mod.rs
+++ b/system/rust/src/core/mod.rs
@@ -11,7 +11,6 @@ use std::{pin::Pin, rc::Rc, thread};
use cxx::UniquePtr;
use crate::{
- connection::{LeAclManagerImpl, LeAclManagerShim},
gatt::ffi::{AttTransportImpl, GattCallbacksImpl},
GlobalModuleRegistry, MainThreadTxMessage, GLOBAL_MODULE_REGISTRY,
};
@@ -20,14 +19,12 @@ use self::ffi::{future_ready, Future, GattServerCallbacks};
fn start(
gatt_server_callbacks: UniquePtr<GattServerCallbacks>,
- le_acl_manager: UniquePtr<LeAclManagerShim>,
on_started: Pin<&'static mut Future>,
) {
thread::spawn(move || {
GlobalModuleRegistry::start(
Rc::new(GattCallbacksImpl(gatt_server_callbacks)),
Rc::new(AttTransportImpl()),
- LeAclManagerImpl(le_acl_manager),
|| {
future_ready(on_started);
},
diff --git a/system/rust/src/lib.rs b/system/rust/src/lib.rs
index b8154a1cd9..adfb665de3 100644
--- a/system/rust/src/lib.rs
+++ b/system/rust/src/lib.rs
@@ -15,18 +15,15 @@
//! The core event loop for Rust modules. Here Rust modules are started in
//! dependency order.
-use connection::le_manager::InactiveLeAclManager;
use gatt::{channel::AttTransport, GattCallbacks};
use log::{info, warn};
use tokio::task::LocalSet;
-use self::core::shared_box::SharedBox;
use std::{rc::Rc, sync::Mutex};
use tokio::runtime::Builder;
use tokio::sync::mpsc;
-pub mod connection;
pub mod core;
pub mod gatt;
pub mod packets;
@@ -47,8 +44,6 @@ pub struct ModuleViews<'a> {
pub gatt_incoming_callbacks: Rc<gatt::callbacks::CallbackTransactionManager>,
/// Proxies calls into GATT server
pub gatt_module: &'a mut gatt::server::GattModule,
- /// Proxies calls into connection manager
- pub connection_manager: SharedBox<connection::ConnectionManager>,
}
static GLOBAL_MODULE_REGISTRY: Mutex<Option<GlobalModuleRegistry>> = Mutex::new(None);
@@ -61,7 +56,6 @@ impl GlobalModuleRegistry {
pub fn start(
gatt_callbacks: Rc<dyn GattCallbacks>,
att_transport: Rc<dyn AttTransport>,
- le_acl_manager: impl InactiveLeAclManager,
on_started: impl FnOnce(),
) {
info!("starting Rust modules");
@@ -79,7 +73,6 @@ impl GlobalModuleRegistry {
// First, setup FFI and C++ modules
let arbiter = gatt::arbiter::initialize_arbiter();
- connection::register_callbacks();
// Now enter the runtime
local.block_on(&rt, async move {
@@ -88,15 +81,12 @@ impl GlobalModuleRegistry {
Rc::new(gatt::callbacks::CallbackTransactionManager::new(gatt_callbacks.clone()));
let gatt_module = &mut gatt::server::GattModule::new(att_transport.clone(), arbiter);
- let connection_manager = connection::ConnectionManager::new(le_acl_manager);
-
// All modules that are visible from incoming JNI / top-level interfaces should
// be exposed here
let mut modules = ModuleViews {
gatt_outgoing_callbacks: gatt_callbacks,
gatt_incoming_callbacks,
gatt_module,
- connection_manager,
};
// notify upper layer that we are ready to receive messages
diff --git a/system/stack/acl/ble_acl.cc b/system/stack/acl/ble_acl.cc
index c7ad2adbbd..1f5d5b580c 100644
--- a/system/stack/acl/ble_acl.cc
+++ b/system/stack/acl/ble_acl.cc
@@ -52,9 +52,7 @@ static bool acl_ble_common_connection(const tBLE_BD_ADDR& address_with_type, uin
}
// Inform any applications that a connection has completed.
- if (!com::android::bluetooth::flags::unified_connection_manager()) {
- connection_manager::on_connection_complete(address_with_type.bda);
- }
+ connection_manager::on_connection_complete(address_with_type.bda);
// Allocate or update the security device record for this device
btm_ble_connected(address_with_type.bda, handle, HCI_ENCRYPT_MODE_DISABLED, role,
@@ -111,9 +109,7 @@ void acl_ble_enhanced_connection_complete_from_shim(
uint16_t conn_interval, uint16_t conn_latency, uint16_t conn_timeout,
const RawAddress& local_rpa, const RawAddress& peer_rpa, tBLE_ADDR_TYPE peer_addr_type,
bool can_read_discoverable_characteristics) {
- if (!com::android::bluetooth::flags::unified_connection_manager()) {
- connection_manager::on_connection_complete(address_with_type.bda);
- }
+ connection_manager::on_connection_complete(address_with_type.bda);
tBLE_BD_ADDR resolved_address_with_type;
const bool is_in_security_db =
@@ -139,9 +135,7 @@ void acl_ble_connection_fail(const tBLE_BD_ADDR& address_with_type, uint16_t /*
btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
tBLE_BD_ADDR resolved_address_with_type;
maybe_resolve_received_address(address_with_type, &resolved_address_with_type);
- if (!com::android::bluetooth::flags::unified_connection_manager()) {
- connection_manager::on_connection_timed_out_from_shim(resolved_address_with_type.bda);
- }
+ connection_manager::on_connection_timed_out_from_shim(resolved_address_with_type.bda);
log::warn("LE connection fail peer:{} bd_addr:{} hci_status:{}", address_with_type,
resolved_address_with_type.bda, hci_status_code_text(status));
} else {
diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc
index d88f447160..fc4a4dcd6c 100644
--- a/system/stack/acl/btm_acl.cc
+++ b/system/stack/acl/btm_acl.cc
@@ -54,8 +54,6 @@
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
#include "osi/include/stack_power_telemetry.h"
-#include "rust/src/connection/ffi/connection_shim.h"
-#include "rust/src/core/ffi/types.h"
#include "stack/acl/acl.h"
#include "stack/acl/peer_packet_types.h"
#include "stack/btm/btm_ble_int.h"
@@ -2464,7 +2462,7 @@ void acl_write_automatic_flush_timeout(const RawAddress& bd_addr, uint16_t flush
btsnd_hcic_write_auto_flush_tout(p_acl->hci_handle, flush_timeout_in_ticks);
}
-bool acl_create_le_connection_with_id(uint8_t id, const RawAddress& bd_addr,
+bool acl_create_le_connection_with_id(uint8_t /* id */, const RawAddress& bd_addr,
tBLE_ADDR_TYPE addr_type) {
tBLE_BD_ADDR address_with_type{
.type = addr_type,
@@ -2484,13 +2482,8 @@ bool acl_create_le_connection_with_id(uint8_t id, const RawAddress& bd_addr,
return false;
}
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- bluetooth::connection::GetConnectionManager().start_direct_connection(
- id, bluetooth::core::ToRustAddress(address_with_type));
- } else {
- bluetooth::shim::ACL_AcceptLeConnectionFrom(address_with_type,
- /* is_direct */ true);
- }
+ bluetooth::shim::ACL_AcceptLeConnectionFrom(address_with_type,
+ /* is_direct */ true);
return true;
}
diff --git a/system/stack/btm/btm_dev.cc b/system/stack/btm/btm_dev.cc
index af7869423f..cdc7e27f91 100644
--- a/system/stack/btm/btm_dev.cc
+++ b/system/stack/btm/btm_dev.cc
@@ -39,7 +39,6 @@
#include "main/shim/acl_api.h"
#include "main/shim/dumpsys.h"
#include "osi/include/allocator.h"
-#include "rust/src/connection/ffi/connection_shim.h"
#include "stack/btm/btm_sec.h"
#include "stack/include/acl_api.h"
#include "stack/include/bt_octets.h"
@@ -182,12 +181,7 @@ bool BTM_SecDeleteDevice(const RawAddress& bd_addr) {
RawAddress bda = p_dev_rec->bd_addr;
log::info("Remove device {} from filter accept list before delete record", bd_addr);
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- bluetooth::connection::GetConnectionManager().stop_all_connections_to_device(
- bluetooth::connection::ResolveRawAddress(bda));
- } else {
- bluetooth::shim::ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(bda));
- }
+ bluetooth::shim::ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(bda));
const auto device_type = p_dev_rec->device_type;
const auto bond_type = p_dev_rec->sec_rec.bond_type;
diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc
index a5a863708f..cf723d1e1e 100644
--- a/system/stack/gatt/gatt_api.cc
+++ b/system/stack/gatt/gatt_api.cc
@@ -35,7 +35,6 @@
#include "internal_include/stack_config.h"
#include "os/system_properties.h"
#include "osi/include/allocator.h"
-#include "rust/src/connection/ffi/connection_shim.h"
#include "stack/arbiter/acl_arbiter.h"
#include "stack/btm/btm_dev.h"
#include "stack/gatt/connection_manager.h"
@@ -1378,11 +1377,7 @@ void GATT_Deregister(tGATT_IF gatt_if) {
}
}
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- bluetooth::connection::GetConnectionManager().remove_client(gatt_if);
- } else {
- connection_manager::on_app_deregistered(gatt_if);
- }
+ connection_manager::on_app_deregistered(gatt_if);
if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
gatt_cb.cl_rcb_map.erase(gatt_if);
@@ -1506,20 +1501,10 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, tBLE_ADDR_TYPE ad
ret = false;
} else {
log::debug("Adding to background connect to device:{}", bd_addr);
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- if (connection_type == BTM_BLE_BKG_CONNECT_ALLOW_LIST) {
- bluetooth::connection::GetConnectionManager().add_background_connection(
- gatt_if, bluetooth::connection::ResolveRawAddress(bd_addr));
- ret = true; // TODO(aryarahul): error handling
- } else {
- log::fatal("unimplemented, TODO(aryarahul)");
- }
+ if (connection_type == BTM_BLE_BKG_CONNECT_ALLOW_LIST) {
+ ret = connection_manager::background_connect_add(gatt_if, bd_addr);
} else {
- if (connection_type == BTM_BLE_BKG_CONNECT_ALLOW_LIST) {
- ret = connection_manager::background_connect_add(gatt_if, bd_addr);
- } else {
- ret = connection_manager::background_connect_targeted_announcement_add(gatt_if, bd_addr);
- }
+ ret = connection_manager::background_connect_targeted_announcement_add(gatt_if, bd_addr);
}
}
}
@@ -1602,14 +1587,9 @@ bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr, bool is_dir
}
}
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- bluetooth::connection::GetConnectionManager().stop_all_connections_to_device(
- bluetooth::connection::ResolveRawAddress(bd_addr));
- } else {
- if (!connection_manager::remove_unconditional(bd_addr)) {
- log::error("no app associated with the bg device for unconditional removal");
- return false;
- }
+ if (!connection_manager::remove_unconditional(bd_addr)) {
+ log::error("no app associated with the bg device for unconditional removal");
+ return false;
}
return true;
diff --git a/system/stack/gatt/gatt_main.cc b/system/stack/gatt/gatt_main.cc
index 299b847c5a..7c8a256610 100644
--- a/system/stack/gatt/gatt_main.cc
+++ b/system/stack/gatt/gatt_main.cc
@@ -35,7 +35,6 @@
#include "main/shim/acl_api.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
-#include "rust/src/connection/ffi/connection_shim.h"
#include "stack/arbiter/acl_arbiter.h"
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_sec.h"
@@ -261,20 +260,14 @@ void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
/* This shall be call only when device is not connected */
log::debug("{}, transport {}", bd_addr, transport);
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- // TODO(aryarahul): this might not be necessary now that the connection
- // manager handles GATT client closure correctly in GATT_Deregister
- bluetooth::connection::GetConnectionManager().stop_all_connections_to_device(
- bluetooth::connection::ResolveRawAddress(bd_addr));
- } else {
- if (!connection_manager::direct_connect_remove(CONN_MGR_ID_L2CAP, bd_addr)) {
- bluetooth::shim::ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(bd_addr));
- log::info(
- "GATT connection manager has no record but removed filter "
- "acceptlist gatt_if:{} peer:{}",
- static_cast<uint8_t>(CONN_MGR_ID_L2CAP), bd_addr);
- }
+ if (!connection_manager::direct_connect_remove(CONN_MGR_ID_L2CAP, bd_addr)) {
+ bluetooth::shim::ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(bd_addr));
+ log::info(
+ "GATT connection manager has no record but removed filter "
+ "acceptlist gatt_if:{} peer:{}",
+ static_cast<uint8_t>(CONN_MGR_ID_L2CAP), bd_addr);
}
+
gatt_cleanup_upon_disc(bd_addr, GATT_CONN_TERMINATE_LOCAL_HOST, transport);
}
@@ -1010,14 +1003,7 @@ static void gatt_send_conn_cback(tGATT_TCB* p_tcb) {
tGATT_REG* p_reg;
tCONN_ID conn_id;
- std::set<tGATT_IF> apps = {};
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- // TODO(aryarahul): this should be done via callbacks passed into the
- // connection manager
- apps = {};
- } else {
- apps = connection_manager::get_apps_connecting_to(p_tcb->peer_bda);
- }
+ std::set<tGATT_IF> apps = connection_manager::get_apps_connecting_to(p_tcb->peer_bda);
/* notifying all applications for the connection up event */
@@ -1070,9 +1056,7 @@ static void gatt_send_conn_cback(tGATT_TCB* p_tcb) {
}
/* Remove the direct connection */
- if (!com::android::bluetooth::flags::unified_connection_manager()) {
- connection_manager::on_connection_complete(p_tcb->peer_bda);
- }
+ connection_manager::on_connection_complete(p_tcb->peer_bda);
if (p_tcb->att_lcid == L2CAP_ATT_CID) {
if (!p_tcb->app_hold_link.empty()) {
diff --git a/system/stack/gatt/gatt_utils.cc b/system/stack/gatt/gatt_utils.cc
index ec449c0ecd..57dbb6e71a 100644
--- a/system/stack/gatt/gatt_utils.cc
+++ b/system/stack/gatt/gatt_utils.cc
@@ -36,7 +36,6 @@
#include "main/shim/dumpsys.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
-#include "rust/src/connection/ffi/connection_shim.h"
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_sec.h"
#include "stack/eatt/eatt.h"
@@ -1661,26 +1660,21 @@ bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) {
gatt_disconnect(p_tcb);
}
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- bluetooth::connection::GetConnectionManager().stop_direct_connection(
- gatt_if, bluetooth::connection::ResolveRawAddress(bda));
- } else {
- if (!connection_manager::direct_connect_remove(gatt_if, bda)) {
- if (!connection_manager::is_background_connection(bda)) {
- if (!com::android::bluetooth::flags::gatt_fix_multiple_direct_connect() ||
- p_tcb->app_hold_link.empty()) {
- bluetooth::shim::ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(bda));
- }
- log::info(
- "Gatt connection manager has no background record but removed "
- "filter acceptlist gatt_if:{} peer:{}",
- gatt_if, bda);
- } else {
- log::info(
- "Gatt connection manager maintains a background record preserving "
- "filter acceptlist gatt_if:{} peer:{}",
- gatt_if, bda);
+ if (!connection_manager::direct_connect_remove(gatt_if, bda)) {
+ if (!connection_manager::is_background_connection(bda)) {
+ if (!com::android::bluetooth::flags::gatt_fix_multiple_direct_connect() ||
+ p_tcb->app_hold_link.empty()) {
+ bluetooth::shim::ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(bda));
}
+ log::info(
+ "Gatt connection manager has no background record but removed "
+ "filter acceptlist gatt_if:{} peer:{}",
+ gatt_if, bda);
+ } else {
+ log::info(
+ "Gatt connection manager maintains a background record preserving "
+ "filter acceptlist gatt_if:{} peer:{}",
+ gatt_if, bda);
}
}
@@ -1979,14 +1973,7 @@ bool gatt_auto_connect_dev_remove(tGATT_IF gatt_if, const RawAddress& bd_addr) {
if (p_tcb) {
gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false);
}
- if (com::android::bluetooth::flags::unified_connection_manager()) {
- bluetooth::connection::GetConnectionManager().remove_background_connection(
- gatt_if, bluetooth::connection::ResolveRawAddress(bd_addr));
- // TODO(aryarahul): handle failure case
- return true;
- } else {
- return connection_manager::background_connect_remove(gatt_if, bd_addr);
- }
+ return connection_manager::background_connect_remove(gatt_if, bd_addr);
}
tCONN_ID gatt_create_conn_id(tTCB_IDX tcb_idx, tGATT_IF gatt_if) {
diff --git a/system/test/mock/mock_rust_ffi_connection_shim.cc b/system/test/mock/mock_rust_ffi_connection_shim.cc
deleted file mode 100644
index aeb62182ba..0000000000
--- a/system/test/mock/mock_rust_ffi_connection_shim.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "rust/src/connection/ffi/connection_shim.h"
-#include "test/common/mock_functions.h"
-
-namespace bluetooth {
-
-namespace connection {
-
-RustConnectionManager& GetConnectionManager() {
- static RustConnectionManager manager = {};
- inc_func_call_count(__func__);
- return manager;
-}
-
-core::AddressWithType ResolveRawAddress(RawAddress /* bd_addr */) {
- inc_func_call_count(__func__);
- return {};
-}
-
-} // namespace connection
-} // namespace bluetooth