Loading system/gd/rust/linux/client/src/callbacks.rs +7 −3 Original line number Diff line number Diff line Loading @@ -125,12 +125,16 @@ impl IBluetoothCallback for BtCallback { print_info!("Found device: {:?}", remote_device); } fn on_device_cleared(&self, remote_device: BluetoothDevice) { match self.context.lock().unwrap().found_devices.remove(&remote_device.address) { Some(_) => print_info!("Removed device: {:?}", remote_device), None => (), }; } fn on_discovering_changed(&self, discovering: bool) { self.context.lock().unwrap().discovering_state = discovering; if discovering { self.context.lock().unwrap().found_devices.clear(); } print_info!("Discovering: {}", discovering); } Loading system/gd/rust/linux/client/src/dbus_iface.rs +3 −0 Original line number Diff line number Diff line Loading @@ -183,6 +183,9 @@ impl IBluetoothCallback for IBluetoothCallbackDBus { #[dbus_method("OnDeviceFound")] fn on_device_found(&self, remote_device: BluetoothDevice) {} #[dbus_method("OnDeviceCleared")] fn on_device_cleared(&self, remote_device: BluetoothDevice) {} #[dbus_method("OnDiscoveringChanged")] fn on_discovering_changed(&self, discovering: bool) {} Loading system/gd/rust/linux/service/src/iface_bluetooth.rs +4 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,10 @@ impl IBluetoothCallback for BluetoothCallbackDBus { fn on_device_found(&self, remote_device: BluetoothDevice) { dbus_generated!() } #[dbus_method("OnDeviceCleared")] fn on_device_cleared(&self, remote_device: BluetoothDevice) { dbus_generated!() } #[dbus_method("OnDiscoveringChanged")] fn on_discovering_changed(&self, discovering: bool) { dbus_generated!() Loading system/gd/rust/linux/stack/src/bluetooth.rs +157 −72 Original line number Diff line number Diff line Loading @@ -18,8 +18,11 @@ use num_traits::cast::ToPrimitive; use std::collections::HashMap; use std::sync::Arc; use std::sync::Mutex; use std::time::Duration; use std::time::Instant; use tokio::sync::mpsc::Sender; use tokio::task::JoinHandle; use tokio::time; use crate::bluetooth_media::{BluetoothMedia, IBluetoothMedia, MediaActions}; use crate::uuid::{Profile, UuidHelper}; Loading @@ -28,6 +31,11 @@ use crate::{BluetoothCallbackType, Message, RPCProxy}; const DEFAULT_DISCOVERY_TIMEOUT_MS: u64 = 12800; const MIN_ADV_INSTANCES_FOR_MULTI_ADV: u8 = 5; /// Devices that were last seen longer than this duration are considered stale /// if they haven't already bonded or connected. Once this duration expires, the /// clear event should be sent to clients. const FOUND_DEVICE_FRESHNESS: Duration = Duration::from_secs(30); /// Defines the adapter API. pub trait IBluetooth { /// Adds a callback from a client who wishes to observe adapter events. Loading Loading @@ -196,6 +204,7 @@ struct BluetoothDeviceContext { pub bond_state: BtBondState, pub acl_state: BtAclState, pub info: BluetoothDevice, pub last_seen: Instant, pub properties: HashMap<BtPropertyType, BluetoothProperty>, } Loading @@ -204,10 +213,16 @@ impl BluetoothDeviceContext { bond_state: BtBondState, acl_state: BtAclState, info: BluetoothDevice, last_seen: Instant, properties: Vec<BluetoothProperty>, ) -> BluetoothDeviceContext { let mut device = BluetoothDeviceContext { bond_state, acl_state, info, properties: HashMap::new() }; let mut device = BluetoothDeviceContext { bond_state, acl_state, info, last_seen, properties: HashMap::new(), }; device.update_properties(properties); device } Loading @@ -227,6 +242,11 @@ impl BluetoothDeviceContext { self.properties.insert(prop.get_type(), prop); } } /// Mark this device as seen. pub(crate) fn seen(&mut self) { self.last_seen = Instant::now(); } } /// The interface for adapter callbacks registered through `IBluetooth::register_callback`. Loading @@ -243,6 +263,9 @@ pub trait IBluetoothCallback: RPCProxy { /// When a device is found via discovery. fn on_device_found(&self, remote_device: BluetoothDevice); /// When a device is cleared from discovered devices cache. fn on_device_cleared(&self, remote_device: BluetoothDevice); /// When the discovery state is changed. fn on_discovering_changed(&self, discovering: bool); Loading Loading @@ -277,16 +300,17 @@ pub struct Bluetooth { connection_callbacks: HashMap<u32, Box<dyn IBluetoothConnectionCallback + Send>>, discovering_started: Instant, hh: Option<HidHost>, is_connectable: bool, is_discovering: bool, local_address: Option<RawAddress>, properties: HashMap<BtPropertyType, BluetoothProperty>, profiles_ready: bool, found_devices: HashMap<String, BluetoothDeviceContext>, freshness_check: Option<JoinHandle<()>>, sdp: Option<Sdp>, state: BtState, tx: Sender<Message>, uuid_helper: UuidHelper, is_connectable: bool, } impl Bluetooth { Loading @@ -304,16 +328,17 @@ impl Bluetooth { bluetooth_media, discovering_started: Instant::now(), intf, is_connectable: false, is_discovering: false, local_address: None, properties: HashMap::new(), profiles_ready: false, found_devices: HashMap::new(), freshness_check: None, sdp: None, state: BtState::Off, tx, uuid_helper: UuidHelper::new(), is_connectable: false, } } Loading Loading @@ -401,19 +426,16 @@ impl Bluetooth { }; } fn get_remote_device_if_found( &self, device: &BluetoothDevice, ) -> Option<&BluetoothDeviceContext> { self.bonded_devices.get(&device.address).or_else(|| self.found_devices.get(&device.address)) fn get_remote_device_if_found(&self, address: &str) -> Option<&BluetoothDeviceContext> { self.bonded_devices.get(address).or_else(|| self.found_devices.get(address)) } fn get_remote_device_if_found_mut( &mut self, device: &BluetoothDevice, address: &str, ) -> Option<&mut BluetoothDeviceContext> { match self.bonded_devices.get_mut(&device.address) { None => self.found_devices.get_mut(&device.address), match self.bonded_devices.get_mut(address) { None => self.found_devices.get_mut(address), some => some, } } Loading @@ -423,7 +445,7 @@ impl Bluetooth { device: &BluetoothDevice, property_type: &BtPropertyType, ) -> Option<BluetoothProperty> { self.get_remote_device_if_found(&device) self.get_remote_device_if_found(&device.address) .and_then(|d| d.properties.get(property_type).and_then(|p| Some(p.clone()))) } Loading @@ -433,7 +455,7 @@ impl Bluetooth { property_type: BtPropertyType, property: BluetoothProperty, ) -> Result<(), ()> { let mut remote_device = match self.get_remote_device_if_found_mut(&device) { let remote_device = match self.get_remote_device_if_found_mut(&device.address) { Some(d) => d, None => { return Err(()); Loading @@ -451,6 +473,48 @@ impl Bluetooth { self.intf.lock().unwrap().set_remote_device_property(addr, property); Ok(()) } /// Check whether found devices are still fresh. If they're outside the /// freshness window, send a notification to clear the device from clients. pub(crate) fn trigger_freshness_check(&mut self) { // Drop previous joinhandle self.freshness_check = None; // A found device is considered fresh if: // * It was last seen less than |FOUND_DEVICE_FRESHNESS| ago. // * It is currently connected. fn is_fresh(d: &BluetoothDeviceContext, now: &Instant) -> bool { let fresh_at = d.last_seen + FOUND_DEVICE_FRESHNESS; now < &fresh_at || d.acl_state == BtAclState::Connected } let now = Instant::now(); let stale_devices: Vec<BluetoothDevice> = self .found_devices .iter() .filter(|(_, d)| !is_fresh(d, &now)) .map(|(_, d)| d.info.clone()) .collect(); // Retain only devices that are fresh. self.found_devices.retain(|_, d| is_fresh(d, &now)); for d in stale_devices { self.for_all_callbacks(|callback| { callback.on_device_cleared(d.clone()); }); } // If we have any fresh devices remaining, re-queue a freshness check. if self.found_devices.len() > 0 { let txl = self.tx.clone(); self.freshness_check = Some(tokio::spawn(async move { time::sleep(FOUND_DEVICE_FRESHNESS).await; let _ = txl.send(Message::DeviceFreshnessCheck).await; })); } } } #[btif_callbacks_dispatcher(Bluetooth, dispatch_base_callbacks, BaseCallbacks)] Loading Loading @@ -593,6 +657,7 @@ impl BtifBluetoothCallbacks for Bluetooth { BtBondState::Bonded, BtAclState::Disconnected, BluetoothDevice::new(address.clone(), "".to_string()), Instant::now(), vec![], )); } Loading Loading @@ -621,11 +686,13 @@ impl BtifBluetoothCallbacks for Bluetooth { if let Some(existing) = self.found_devices.get_mut(&address) { existing.update_properties(properties); existing.seen(); } else { let device_with_props = BluetoothDeviceContext::new( BtBondState::NotBonded, BtAclState::Disconnected, device, Instant::now(), properties, ); self.found_devices.insert(address.clone(), device_with_props); Loading @@ -639,9 +706,11 @@ impl BtifBluetoothCallbacks for Bluetooth { } fn discovery_state(&mut self, state: BtDiscoveryState) { // Clear found devices when discovery session starts if !self.is_discovering && &state == &BtDiscoveryState::Started { self.found_devices.clear(); let is_discovering = &state == &BtDiscoveryState::Started; // No-op if we're updating the state to the same value again. if &is_discovering == &self.is_discovering { return; } // Cache discovering state Loading @@ -653,6 +722,13 @@ impl BtifBluetoothCallbacks for Bluetooth { self.for_all_callbacks(|callback| { callback.on_discovering_changed(state == BtDiscoveryState::Started); }); // Stopped discovering and no freshness check is active. Immediately do // freshness check which will schedule a recurring future until all // entries are cleared. if !is_discovering && self.freshness_check.is_none() { self.trigger_freshness_check(); } } fn ssp_request( Loading Loading @@ -706,6 +782,7 @@ impl BtifBluetoothCallbacks for Bluetooth { bond_state.clone(), BtAclState::Disconnected, BluetoothDevice::new(address.clone(), "".to_string()), Instant::now(), vec![], ), }; Loading Loading @@ -736,27 +813,31 @@ impl BtifBluetoothCallbacks for Bluetooth { properties: Vec<BluetoothProperty>, ) { let address = addr.to_string(); // Device should be in either found devices or bonded devices // If it isn't in either, create it and put it found devices. let device = if self.bonded_devices.contains_key(&address) { self.bonded_devices.get_mut(&address) } else if self.found_devices.contains_key(&address) { self.found_devices.get_mut(&address) } else { let device = match self.get_remote_device_if_found_mut(&address) { None => { self.found_devices.insert( address.clone(), BluetoothDeviceContext::new( BtBondState::NotBonded, BtAclState::Disconnected, BluetoothDevice::new(address.clone(), String::from("")), Instant::now(), vec![], ), ); self.found_devices.get_mut(&address) } some => some, }; device.unwrap().update_properties(properties); match device { Some(d) => { d.update_properties(properties); d.seen(); } None => (), }; } fn acl_state( Loading @@ -773,30 +854,31 @@ impl BtifBluetoothCallbacks for Bluetooth { } let address = addr.to_string(); let found = if self.bonded_devices.contains_key(&address) { self.bonded_devices.get_mut(&address) } else if self.found_devices.contains_key(&address) { self.found_devices.get_mut(&address) } else { let device = match self.get_remote_device_if_found_mut(&address) { None => { self.found_devices.insert( address.clone(), BluetoothDeviceContext::new( BtBondState::NotBonded, BtAclState::Disconnected, BluetoothDevice::new(address.clone(), String::from("")), Instant::now(), vec![], ), ); self.found_devices.get_mut(&address) } some => some, }; match device { Some(found) => { // Only notify if there's been a change in state let prev_state = &found.as_ref().unwrap().acl_state; let prev_state = &found.acl_state; if prev_state != &state { let device = found.as_ref().unwrap().info.clone(); found.unwrap().acl_state = state.clone(); let device = found.info.clone(); found.acl_state = state.clone(); match state { BtAclState::Connected => { Loading @@ -812,6 +894,9 @@ impl BtifBluetoothCallbacks for Bluetooth { }; } } None => (), }; } } // TODO: Add unit tests for this implementation Loading Loading @@ -1219,7 +1304,7 @@ impl IBluetooth for Bluetooth { } fn fetch_remote_uuids(&self, device: BluetoothDevice) -> bool { if self.get_remote_device_if_found(&device).is_none() { if self.get_remote_device_if_found(&device.address).is_none() { warn!("Won't fetch UUIDs on unknown device {}", device.address); return false; } Loading system/gd/rust/linux/stack/src/lib.rs +7 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ pub enum Message { // Client callback disconnections BluetoothCallbackDisconnected(u32, BluetoothCallbackType), // Update list of found devices and remove old instances. DeviceFreshnessCheck, // Suspend related SuspendCallbackRegistered(u32), SuspendCallbackDisconnected(u32), Loading Loading @@ -126,6 +129,10 @@ impl Stack { bluetooth.lock().unwrap().callback_disconnected(id, cb_type); } Message::DeviceFreshnessCheck => { bluetooth.lock().unwrap().trigger_freshness_check(); } Message::SuspendCallbackRegistered(id) => { suspend.lock().unwrap().callback_registered(id); } Loading Loading
system/gd/rust/linux/client/src/callbacks.rs +7 −3 Original line number Diff line number Diff line Loading @@ -125,12 +125,16 @@ impl IBluetoothCallback for BtCallback { print_info!("Found device: {:?}", remote_device); } fn on_device_cleared(&self, remote_device: BluetoothDevice) { match self.context.lock().unwrap().found_devices.remove(&remote_device.address) { Some(_) => print_info!("Removed device: {:?}", remote_device), None => (), }; } fn on_discovering_changed(&self, discovering: bool) { self.context.lock().unwrap().discovering_state = discovering; if discovering { self.context.lock().unwrap().found_devices.clear(); } print_info!("Discovering: {}", discovering); } Loading
system/gd/rust/linux/client/src/dbus_iface.rs +3 −0 Original line number Diff line number Diff line Loading @@ -183,6 +183,9 @@ impl IBluetoothCallback for IBluetoothCallbackDBus { #[dbus_method("OnDeviceFound")] fn on_device_found(&self, remote_device: BluetoothDevice) {} #[dbus_method("OnDeviceCleared")] fn on_device_cleared(&self, remote_device: BluetoothDevice) {} #[dbus_method("OnDiscoveringChanged")] fn on_discovering_changed(&self, discovering: bool) {} Loading
system/gd/rust/linux/service/src/iface_bluetooth.rs +4 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,10 @@ impl IBluetoothCallback for BluetoothCallbackDBus { fn on_device_found(&self, remote_device: BluetoothDevice) { dbus_generated!() } #[dbus_method("OnDeviceCleared")] fn on_device_cleared(&self, remote_device: BluetoothDevice) { dbus_generated!() } #[dbus_method("OnDiscoveringChanged")] fn on_discovering_changed(&self, discovering: bool) { dbus_generated!() Loading
system/gd/rust/linux/stack/src/bluetooth.rs +157 −72 Original line number Diff line number Diff line Loading @@ -18,8 +18,11 @@ use num_traits::cast::ToPrimitive; use std::collections::HashMap; use std::sync::Arc; use std::sync::Mutex; use std::time::Duration; use std::time::Instant; use tokio::sync::mpsc::Sender; use tokio::task::JoinHandle; use tokio::time; use crate::bluetooth_media::{BluetoothMedia, IBluetoothMedia, MediaActions}; use crate::uuid::{Profile, UuidHelper}; Loading @@ -28,6 +31,11 @@ use crate::{BluetoothCallbackType, Message, RPCProxy}; const DEFAULT_DISCOVERY_TIMEOUT_MS: u64 = 12800; const MIN_ADV_INSTANCES_FOR_MULTI_ADV: u8 = 5; /// Devices that were last seen longer than this duration are considered stale /// if they haven't already bonded or connected. Once this duration expires, the /// clear event should be sent to clients. const FOUND_DEVICE_FRESHNESS: Duration = Duration::from_secs(30); /// Defines the adapter API. pub trait IBluetooth { /// Adds a callback from a client who wishes to observe adapter events. Loading Loading @@ -196,6 +204,7 @@ struct BluetoothDeviceContext { pub bond_state: BtBondState, pub acl_state: BtAclState, pub info: BluetoothDevice, pub last_seen: Instant, pub properties: HashMap<BtPropertyType, BluetoothProperty>, } Loading @@ -204,10 +213,16 @@ impl BluetoothDeviceContext { bond_state: BtBondState, acl_state: BtAclState, info: BluetoothDevice, last_seen: Instant, properties: Vec<BluetoothProperty>, ) -> BluetoothDeviceContext { let mut device = BluetoothDeviceContext { bond_state, acl_state, info, properties: HashMap::new() }; let mut device = BluetoothDeviceContext { bond_state, acl_state, info, last_seen, properties: HashMap::new(), }; device.update_properties(properties); device } Loading @@ -227,6 +242,11 @@ impl BluetoothDeviceContext { self.properties.insert(prop.get_type(), prop); } } /// Mark this device as seen. pub(crate) fn seen(&mut self) { self.last_seen = Instant::now(); } } /// The interface for adapter callbacks registered through `IBluetooth::register_callback`. Loading @@ -243,6 +263,9 @@ pub trait IBluetoothCallback: RPCProxy { /// When a device is found via discovery. fn on_device_found(&self, remote_device: BluetoothDevice); /// When a device is cleared from discovered devices cache. fn on_device_cleared(&self, remote_device: BluetoothDevice); /// When the discovery state is changed. fn on_discovering_changed(&self, discovering: bool); Loading Loading @@ -277,16 +300,17 @@ pub struct Bluetooth { connection_callbacks: HashMap<u32, Box<dyn IBluetoothConnectionCallback + Send>>, discovering_started: Instant, hh: Option<HidHost>, is_connectable: bool, is_discovering: bool, local_address: Option<RawAddress>, properties: HashMap<BtPropertyType, BluetoothProperty>, profiles_ready: bool, found_devices: HashMap<String, BluetoothDeviceContext>, freshness_check: Option<JoinHandle<()>>, sdp: Option<Sdp>, state: BtState, tx: Sender<Message>, uuid_helper: UuidHelper, is_connectable: bool, } impl Bluetooth { Loading @@ -304,16 +328,17 @@ impl Bluetooth { bluetooth_media, discovering_started: Instant::now(), intf, is_connectable: false, is_discovering: false, local_address: None, properties: HashMap::new(), profiles_ready: false, found_devices: HashMap::new(), freshness_check: None, sdp: None, state: BtState::Off, tx, uuid_helper: UuidHelper::new(), is_connectable: false, } } Loading Loading @@ -401,19 +426,16 @@ impl Bluetooth { }; } fn get_remote_device_if_found( &self, device: &BluetoothDevice, ) -> Option<&BluetoothDeviceContext> { self.bonded_devices.get(&device.address).or_else(|| self.found_devices.get(&device.address)) fn get_remote_device_if_found(&self, address: &str) -> Option<&BluetoothDeviceContext> { self.bonded_devices.get(address).or_else(|| self.found_devices.get(address)) } fn get_remote_device_if_found_mut( &mut self, device: &BluetoothDevice, address: &str, ) -> Option<&mut BluetoothDeviceContext> { match self.bonded_devices.get_mut(&device.address) { None => self.found_devices.get_mut(&device.address), match self.bonded_devices.get_mut(address) { None => self.found_devices.get_mut(address), some => some, } } Loading @@ -423,7 +445,7 @@ impl Bluetooth { device: &BluetoothDevice, property_type: &BtPropertyType, ) -> Option<BluetoothProperty> { self.get_remote_device_if_found(&device) self.get_remote_device_if_found(&device.address) .and_then(|d| d.properties.get(property_type).and_then(|p| Some(p.clone()))) } Loading @@ -433,7 +455,7 @@ impl Bluetooth { property_type: BtPropertyType, property: BluetoothProperty, ) -> Result<(), ()> { let mut remote_device = match self.get_remote_device_if_found_mut(&device) { let remote_device = match self.get_remote_device_if_found_mut(&device.address) { Some(d) => d, None => { return Err(()); Loading @@ -451,6 +473,48 @@ impl Bluetooth { self.intf.lock().unwrap().set_remote_device_property(addr, property); Ok(()) } /// Check whether found devices are still fresh. If they're outside the /// freshness window, send a notification to clear the device from clients. pub(crate) fn trigger_freshness_check(&mut self) { // Drop previous joinhandle self.freshness_check = None; // A found device is considered fresh if: // * It was last seen less than |FOUND_DEVICE_FRESHNESS| ago. // * It is currently connected. fn is_fresh(d: &BluetoothDeviceContext, now: &Instant) -> bool { let fresh_at = d.last_seen + FOUND_DEVICE_FRESHNESS; now < &fresh_at || d.acl_state == BtAclState::Connected } let now = Instant::now(); let stale_devices: Vec<BluetoothDevice> = self .found_devices .iter() .filter(|(_, d)| !is_fresh(d, &now)) .map(|(_, d)| d.info.clone()) .collect(); // Retain only devices that are fresh. self.found_devices.retain(|_, d| is_fresh(d, &now)); for d in stale_devices { self.for_all_callbacks(|callback| { callback.on_device_cleared(d.clone()); }); } // If we have any fresh devices remaining, re-queue a freshness check. if self.found_devices.len() > 0 { let txl = self.tx.clone(); self.freshness_check = Some(tokio::spawn(async move { time::sleep(FOUND_DEVICE_FRESHNESS).await; let _ = txl.send(Message::DeviceFreshnessCheck).await; })); } } } #[btif_callbacks_dispatcher(Bluetooth, dispatch_base_callbacks, BaseCallbacks)] Loading Loading @@ -593,6 +657,7 @@ impl BtifBluetoothCallbacks for Bluetooth { BtBondState::Bonded, BtAclState::Disconnected, BluetoothDevice::new(address.clone(), "".to_string()), Instant::now(), vec![], )); } Loading Loading @@ -621,11 +686,13 @@ impl BtifBluetoothCallbacks for Bluetooth { if let Some(existing) = self.found_devices.get_mut(&address) { existing.update_properties(properties); existing.seen(); } else { let device_with_props = BluetoothDeviceContext::new( BtBondState::NotBonded, BtAclState::Disconnected, device, Instant::now(), properties, ); self.found_devices.insert(address.clone(), device_with_props); Loading @@ -639,9 +706,11 @@ impl BtifBluetoothCallbacks for Bluetooth { } fn discovery_state(&mut self, state: BtDiscoveryState) { // Clear found devices when discovery session starts if !self.is_discovering && &state == &BtDiscoveryState::Started { self.found_devices.clear(); let is_discovering = &state == &BtDiscoveryState::Started; // No-op if we're updating the state to the same value again. if &is_discovering == &self.is_discovering { return; } // Cache discovering state Loading @@ -653,6 +722,13 @@ impl BtifBluetoothCallbacks for Bluetooth { self.for_all_callbacks(|callback| { callback.on_discovering_changed(state == BtDiscoveryState::Started); }); // Stopped discovering and no freshness check is active. Immediately do // freshness check which will schedule a recurring future until all // entries are cleared. if !is_discovering && self.freshness_check.is_none() { self.trigger_freshness_check(); } } fn ssp_request( Loading Loading @@ -706,6 +782,7 @@ impl BtifBluetoothCallbacks for Bluetooth { bond_state.clone(), BtAclState::Disconnected, BluetoothDevice::new(address.clone(), "".to_string()), Instant::now(), vec![], ), }; Loading Loading @@ -736,27 +813,31 @@ impl BtifBluetoothCallbacks for Bluetooth { properties: Vec<BluetoothProperty>, ) { let address = addr.to_string(); // Device should be in either found devices or bonded devices // If it isn't in either, create it and put it found devices. let device = if self.bonded_devices.contains_key(&address) { self.bonded_devices.get_mut(&address) } else if self.found_devices.contains_key(&address) { self.found_devices.get_mut(&address) } else { let device = match self.get_remote_device_if_found_mut(&address) { None => { self.found_devices.insert( address.clone(), BluetoothDeviceContext::new( BtBondState::NotBonded, BtAclState::Disconnected, BluetoothDevice::new(address.clone(), String::from("")), Instant::now(), vec![], ), ); self.found_devices.get_mut(&address) } some => some, }; device.unwrap().update_properties(properties); match device { Some(d) => { d.update_properties(properties); d.seen(); } None => (), }; } fn acl_state( Loading @@ -773,30 +854,31 @@ impl BtifBluetoothCallbacks for Bluetooth { } let address = addr.to_string(); let found = if self.bonded_devices.contains_key(&address) { self.bonded_devices.get_mut(&address) } else if self.found_devices.contains_key(&address) { self.found_devices.get_mut(&address) } else { let device = match self.get_remote_device_if_found_mut(&address) { None => { self.found_devices.insert( address.clone(), BluetoothDeviceContext::new( BtBondState::NotBonded, BtAclState::Disconnected, BluetoothDevice::new(address.clone(), String::from("")), Instant::now(), vec![], ), ); self.found_devices.get_mut(&address) } some => some, }; match device { Some(found) => { // Only notify if there's been a change in state let prev_state = &found.as_ref().unwrap().acl_state; let prev_state = &found.acl_state; if prev_state != &state { let device = found.as_ref().unwrap().info.clone(); found.unwrap().acl_state = state.clone(); let device = found.info.clone(); found.acl_state = state.clone(); match state { BtAclState::Connected => { Loading @@ -812,6 +894,9 @@ impl BtifBluetoothCallbacks for Bluetooth { }; } } None => (), }; } } // TODO: Add unit tests for this implementation Loading Loading @@ -1219,7 +1304,7 @@ impl IBluetooth for Bluetooth { } fn fetch_remote_uuids(&self, device: BluetoothDevice) -> bool { if self.get_remote_device_if_found(&device).is_none() { if self.get_remote_device_if_found(&device.address).is_none() { warn!("Won't fetch UUIDs on unknown device {}", device.address); return false; } Loading
system/gd/rust/linux/stack/src/lib.rs +7 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ pub enum Message { // Client callback disconnections BluetoothCallbackDisconnected(u32, BluetoothCallbackType), // Update list of found devices and remove old instances. DeviceFreshnessCheck, // Suspend related SuspendCallbackRegistered(u32), SuspendCallbackDisconnected(u32), Loading Loading @@ -126,6 +129,10 @@ impl Stack { bluetooth.lock().unwrap().callback_disconnected(id, cb_type); } Message::DeviceFreshnessCheck => { bluetooth.lock().unwrap().trigger_freshness_check(); } Message::SuspendCallbackRegistered(id) => { suspend.lock().unwrap().callback_registered(id); } Loading