• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Anything related to the adapter API (IBluetooth).
2 
3 use bt_topshim::btif::{
4     BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState,
5     BtAddrType, BtBondState, BtConnectionDirection, BtConnectionState, BtDeviceType, BtDiscMode,
6     BtDiscoveryState, BtHciErrorCode, BtPinCode, BtPropertyType, BtScanMode, BtSspVariant, BtState,
7     BtStatus, BtThreadEvent, BtTransport, BtVendorProductInfo, DisplayAddress, DisplayUuid,
8     RawAddress, ToggleableProfile, Uuid, INVALID_RSSI,
9 };
10 use bt_topshim::profiles::gatt::GattStatus;
11 use bt_topshim::profiles::hfp::EscoCodingFormat;
12 use bt_topshim::profiles::hid_host::{
13     BthhConnectionState, BthhHidInfo, BthhProtocolMode, BthhReportType, BthhStatus, HHCallbacks,
14     HHCallbacksDispatcher, HidHost,
15 };
16 use bt_topshim::profiles::sdp::{BtSdpRecord, Sdp, SdpCallbacks, SdpCallbacksDispatcher};
17 use bt_topshim::profiles::ProfileConnectionState;
18 use bt_topshim::{controller, metrics, sysprop, topstack};
19 
20 use bt_utils::array_utils;
21 use bt_utils::cod::{is_cod_hid_combo, is_cod_hid_keyboard};
22 use bt_utils::uhid::UHid;
23 use btif_macros::{btif_callback, btif_callbacks_dispatcher, log_cb_args};
24 
25 use log::{debug, error, warn};
26 use num_derive::{FromPrimitive, ToPrimitive};
27 use num_traits::cast::ToPrimitive;
28 use num_traits::pow;
29 use std::collections::{HashMap, HashSet};
30 use std::convert::TryInto;
31 use std::fs::{File, OpenOptions};
32 use std::hash::Hash;
33 use std::io::Write;
34 use std::os::fd::AsRawFd;
35 use std::process;
36 use std::sync::{Arc, Condvar, Mutex};
37 use std::time::{Duration, Instant};
38 use tokio::sync::mpsc::Sender;
39 use tokio::task::JoinHandle;
40 use tokio::time;
41 
42 use crate::bluetooth_admin::BluetoothAdminPolicyHelper;
43 use crate::bluetooth_gatt::{
44     BluetoothGatt, GattActions, IBluetoothGatt, IScannerCallback, ScanResult,
45 };
46 use crate::bluetooth_media::{BluetoothMedia, MediaActions, LEA_UNKNOWN_GROUP_ID};
47 use crate::callbacks::Callbacks;
48 use crate::socket_manager::SocketActions;
49 use crate::uuid::{Profile, UuidHelper};
50 use crate::{make_message_dispatcher, APIMessage, BluetoothAPI, Message, RPCProxy, SuspendMode};
51 
52 pub(crate) const FLOSS_VER: u16 = 0x0001;
53 const DEFAULT_DISCOVERY_TIMEOUT_MS: u64 = 12800;
54 const MIN_ADV_INSTANCES_FOR_MULTI_ADV: u8 = 5;
55 
56 /// Devices that were last seen longer than this duration are considered stale
57 /// if they haven't already bonded or connected. Once this duration expires, the
58 /// clear event should be sent to clients.
59 const FOUND_DEVICE_FRESHNESS: Duration = Duration::from_secs(30);
60 
61 /// This is the value returned from Bluetooth Interface calls.
62 // TODO(241930383): Add enum to topshim
63 const BTM_SUCCESS: i32 = 0;
64 
65 const PID_DIR: &str = "/var/run/bluetooth";
66 
67 const DUMPSYS_LOG: &str = "/tmp/dumpsys.log";
68 
69 /// Represents various roles the adapter supports.
70 #[derive(Debug, FromPrimitive, ToPrimitive)]
71 #[repr(u32)]
72 pub enum BtAdapterRole {
73     Central = 0,
74     Peripheral,
75     CentralPeripheral,
76 }
77 /// Defines the adapter API.
78 pub trait IBluetooth {
79     /// Adds a callback from a client who wishes to observe adapter events.
register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) -> u3280     fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) -> u32;
81 
82     /// Removes registered callback.
unregister_callback(&mut self, callback_id: u32) -> bool83     fn unregister_callback(&mut self, callback_id: u32) -> bool;
84 
85     /// Adds a callback from a client who wishes to observe connection events.
register_connection_callback( &mut self, callback: Box<dyn IBluetoothConnectionCallback + Send>, ) -> u3286     fn register_connection_callback(
87         &mut self,
88         callback: Box<dyn IBluetoothConnectionCallback + Send>,
89     ) -> u32;
90 
91     /// Removes registered callback.
unregister_connection_callback(&mut self, callback_id: u32) -> bool92     fn unregister_connection_callback(&mut self, callback_id: u32) -> bool;
93 
94     /// Inits the bluetooth interface. Should always be called before enable.
init(&mut self, hci_index: i32) -> bool95     fn init(&mut self, hci_index: i32) -> bool;
96 
97     /// Enables the adapter.
98     ///
99     /// Returns true if the request is accepted.
enable(&mut self) -> bool100     fn enable(&mut self) -> bool;
101 
102     /// Disables the adapter.
103     ///
104     /// Returns true if the request is accepted.
disable(&mut self) -> bool105     fn disable(&mut self) -> bool;
106 
107     /// Cleans up the bluetooth interface. Should always be called after disable.
cleanup(&mut self)108     fn cleanup(&mut self);
109 
110     /// Returns the Bluetooth address of the local adapter.
get_address(&self) -> RawAddress111     fn get_address(&self) -> RawAddress;
112 
113     /// Gets supported UUIDs by the local adapter.
get_uuids(&self) -> Vec<Uuid>114     fn get_uuids(&self) -> Vec<Uuid>;
115 
116     /// Gets the local adapter name.
get_name(&self) -> String117     fn get_name(&self) -> String;
118 
119     /// Sets the local adapter name.
set_name(&self, name: String) -> bool120     fn set_name(&self, name: String) -> bool;
121 
122     /// Gets the bluetooth class.
get_bluetooth_class(&self) -> u32123     fn get_bluetooth_class(&self) -> u32;
124 
125     /// Sets the bluetooth class.
set_bluetooth_class(&self, cod: u32) -> bool126     fn set_bluetooth_class(&self, cod: u32) -> bool;
127 
128     /// Returns whether the adapter is discoverable.
get_discoverable(&self) -> bool129     fn get_discoverable(&self) -> bool;
130 
131     /// Returns the adapter discoverable timeout.
get_discoverable_timeout(&self) -> u32132     fn get_discoverable_timeout(&self) -> u32;
133 
134     /// Sets discoverability. If discoverable, limits the duration with given value.
set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool135     fn set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool;
136 
137     /// Returns whether multi-advertisement is supported.
138     /// A minimum number of 5 advertising instances is required for multi-advertisment support.
is_multi_advertisement_supported(&self) -> bool139     fn is_multi_advertisement_supported(&self) -> bool;
140 
141     /// Returns whether LE extended advertising is supported.
is_le_extended_advertising_supported(&self) -> bool142     fn is_le_extended_advertising_supported(&self) -> bool;
143 
144     /// Starts BREDR Inquiry.
start_discovery(&mut self) -> bool145     fn start_discovery(&mut self) -> bool;
146 
147     /// Cancels BREDR Inquiry.
cancel_discovery(&mut self) -> bool148     fn cancel_discovery(&mut self) -> bool;
149 
150     /// Checks if discovery is started.
is_discovering(&self) -> bool151     fn is_discovering(&self) -> bool;
152 
153     /// Checks when discovery ends in milliseconds from now.
get_discovery_end_millis(&self) -> u64154     fn get_discovery_end_millis(&self) -> u64;
155 
156     /// Initiates pairing to a remote device. Triggers connection if not already started.
create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> BtStatus157     fn create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> BtStatus;
158 
159     /// Cancels any pending bond attempt on given device.
cancel_bond_process(&mut self, device: BluetoothDevice) -> bool160     fn cancel_bond_process(&mut self, device: BluetoothDevice) -> bool;
161 
162     /// Removes pairing for given device.
remove_bond(&mut self, device: BluetoothDevice) -> bool163     fn remove_bond(&mut self, device: BluetoothDevice) -> bool;
164 
165     /// Returns a list of known bonded devices.
get_bonded_devices(&self) -> Vec<BluetoothDevice>166     fn get_bonded_devices(&self) -> Vec<BluetoothDevice>;
167 
168     /// Gets the bond state of a single device.
get_bond_state(&self, device: BluetoothDevice) -> BtBondState169     fn get_bond_state(&self, device: BluetoothDevice) -> BtBondState;
170 
171     /// Set pin on bonding device.
set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool172     fn set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool;
173 
174     /// Set passkey on bonding device.
set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool175     fn set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool;
176 
177     /// Confirm that a pairing should be completed on a bonding device.
set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool178     fn set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool;
179 
180     /// Gets the name of the remote device.
get_remote_name(&self, device: BluetoothDevice) -> String181     fn get_remote_name(&self, device: BluetoothDevice) -> String;
182 
183     /// Gets the type of the remote device.
get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType184     fn get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType;
185 
186     /// Gets the alias of the remote device.
get_remote_alias(&self, device: BluetoothDevice) -> String187     fn get_remote_alias(&self, device: BluetoothDevice) -> String;
188 
189     /// Sets the alias of the remote device.
set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String)190     fn set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String);
191 
192     /// Gets the class of the remote device.
get_remote_class(&self, device: BluetoothDevice) -> u32193     fn get_remote_class(&self, device: BluetoothDevice) -> u32;
194 
195     /// Gets the appearance of the remote device.
get_remote_appearance(&self, device: BluetoothDevice) -> u16196     fn get_remote_appearance(&self, device: BluetoothDevice) -> u16;
197 
198     /// Gets whether the remote device is connected.
get_remote_connected(&self, device: BluetoothDevice) -> bool199     fn get_remote_connected(&self, device: BluetoothDevice) -> bool;
200 
201     /// Gets whether the remote device can wake the system.
get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool202     fn get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool;
203 
204     /// Gets the vendor and product information of the remote device.
get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo205     fn get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo;
206 
207     /// Get the address type of the remote device.
get_remote_address_type(&self, device: BluetoothDevice) -> BtAddrType208     fn get_remote_address_type(&self, device: BluetoothDevice) -> BtAddrType;
209 
210     /// Get the RSSI of the remote device.
get_remote_rssi(&self, device: BluetoothDevice) -> i8211     fn get_remote_rssi(&self, device: BluetoothDevice) -> i8;
212 
213     /// Returns a list of connected devices.
get_connected_devices(&self) -> Vec<BluetoothDevice>214     fn get_connected_devices(&self) -> Vec<BluetoothDevice>;
215 
216     /// Gets the connection state of a single device.
get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState217     fn get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState;
218 
219     /// Gets the connection state of a specific profile.
get_profile_connection_state(&self, profile: Uuid) -> ProfileConnectionState220     fn get_profile_connection_state(&self, profile: Uuid) -> ProfileConnectionState;
221 
222     /// Returns the cached UUIDs of a remote device.
get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid>223     fn get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid>;
224 
225     /// Triggers SDP to get UUIDs of a remote device.
fetch_remote_uuids(&self, device: BluetoothDevice) -> bool226     fn fetch_remote_uuids(&self, device: BluetoothDevice) -> bool;
227 
228     /// Triggers SDP and searches for a specific UUID on a remote device.
sdp_search(&self, device: BluetoothDevice, uuid: Uuid) -> bool229     fn sdp_search(&self, device: BluetoothDevice, uuid: Uuid) -> bool;
230 
231     /// Creates a new SDP record.
create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool232     fn create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool;
233 
234     /// Removes the SDP record associated with the provided handle.
remove_sdp_record(&self, handle: i32) -> bool235     fn remove_sdp_record(&self, handle: i32) -> bool;
236 
237     /// Connect all profiles supported by device and enabled on adapter.
connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> BtStatus238     fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> BtStatus;
239 
240     /// Disconnect all profiles supported by device and enabled on adapter.
241     /// Note that it includes all custom profiles enabled by the users e.g. through SocketManager or
242     /// BluetoothGatt interfaces; The device shall be disconnected on baseband eventually.
disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool243     fn disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool;
244 
245     /// Returns whether WBS is supported.
is_wbs_supported(&self) -> bool246     fn is_wbs_supported(&self) -> bool;
247 
248     /// Returns whether SWB is supported.
is_swb_supported(&self) -> bool249     fn is_swb_supported(&self) -> bool;
250 
251     /// Returns a list of all the roles that are supported.
get_supported_roles(&self) -> Vec<BtAdapterRole>252     fn get_supported_roles(&self) -> Vec<BtAdapterRole>;
253 
254     /// Returns whether the coding format is supported.
is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool255     fn is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool;
256 
257     /// Returns whether LE Audio is supported.
is_le_audio_supported(&self) -> bool258     fn is_le_audio_supported(&self) -> bool;
259 
260     /// Returns whether the remote device is a dual mode audio sink device (supports both classic and
261     /// LE Audio sink roles).
is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool262     fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool;
263 
264     /// Gets diagnostic output.
get_dumpsys(&self) -> String265     fn get_dumpsys(&self) -> String;
266 }
267 
268 /// Adapter API for Bluetooth qualification and verification.
269 ///
270 /// This interface is provided for testing and debugging.
271 /// Clients should not use this interface for production.
272 pub trait IBluetoothQALegacy {
273     /// Returns whether the adapter is connectable.
get_connectable(&self) -> bool274     fn get_connectable(&self) -> bool;
275 
276     /// Sets connectability. Returns true on success, false otherwise.
set_connectable(&mut self, mode: bool) -> bool277     fn set_connectable(&mut self, mode: bool) -> bool;
278 
279     /// Returns the adapter's Bluetooth friendly name.
get_alias(&self) -> String280     fn get_alias(&self) -> String;
281 
282     /// Returns the adapter's Device ID information in modalias format
283     /// used by the kernel and udev.
get_modalias(&self) -> String284     fn get_modalias(&self) -> String;
285 
286     /// Gets HID report on the peer.
get_hid_report( &mut self, addr: RawAddress, report_type: BthhReportType, report_id: u8, ) -> BtStatus287     fn get_hid_report(
288         &mut self,
289         addr: RawAddress,
290         report_type: BthhReportType,
291         report_id: u8,
292     ) -> BtStatus;
293 
294     /// Sets HID report to the peer.
set_hid_report( &mut self, addr: RawAddress, report_type: BthhReportType, report: String, ) -> BtStatus295     fn set_hid_report(
296         &mut self,
297         addr: RawAddress,
298         report_type: BthhReportType,
299         report: String,
300     ) -> BtStatus;
301 
302     /// Snd HID data report to the peer.
send_hid_data(&mut self, addr: RawAddress, data: String) -> BtStatus303     fn send_hid_data(&mut self, addr: RawAddress, data: String) -> BtStatus;
304 }
305 
306 /// Action events from lib.rs
307 pub enum AdapterActions {
308     /// Check whether the current set of found devices are still fresh.
309     DeviceFreshnessCheck,
310 
311     /// Connect to all supported profiles on target device.
312     ConnectAllProfiles(BluetoothDevice),
313 
314     /// Connect to the specified profiles on target device.
315     ConnectProfiles(Vec<Uuid>, BluetoothDevice),
316 
317     /// Scanner for BLE discovery is registered with given status and scanner id.
318     BleDiscoveryScannerRegistered(Uuid, u8, GattStatus),
319 
320     /// Scanner for BLE discovery is reporting a result.
321     BleDiscoveryScannerResult(ScanResult),
322 
323     /// Reset the discoverable mode to BtDiscMode::NonDiscoverable.
324     ResetDiscoverable,
325 
326     /// Create bond to the device stored in |pending_create_bond|.
327     CreateBond,
328 }
329 
330 /// Serializable device used in various apis.
331 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
332 pub struct BluetoothDevice {
333     pub address: RawAddress,
334     pub name: String,
335 }
336 
337 impl BluetoothDevice {
new(address: RawAddress, name: String) -> Self338     pub(crate) fn new(address: RawAddress, name: String) -> Self {
339         Self { address, name }
340     }
341 
from_properties(in_properties: &Vec<BluetoothProperty>) -> Self342     pub(crate) fn from_properties(in_properties: &Vec<BluetoothProperty>) -> Self {
343         let mut address = RawAddress::default();
344         let mut name = String::from("");
345 
346         for prop in in_properties {
347             match &prop {
348                 BluetoothProperty::BdAddr(bdaddr) => {
349                     address = *bdaddr;
350                 }
351                 BluetoothProperty::BdName(bdname) => {
352                     name = bdname.clone();
353                 }
354                 _ => {}
355             }
356         }
357 
358         Self { address, name }
359     }
360 }
361 
362 /// Internal data structure that keeps a map of cached properties for a remote device.
363 struct BluetoothDeviceContext {
364     /// Transport type reported by ACL connection (if completed).
365     pub acl_reported_transport: BtTransport,
366 
367     pub bredr_acl_state: BtAclState,
368     pub ble_acl_state: BtAclState,
369     pub bond_state: BtBondState,
370     pub info: BluetoothDevice,
371     pub last_seen: Instant,
372     pub properties: HashMap<BtPropertyType, BluetoothProperty>,
373     pub is_initiated_hh_connection: bool,
374 
375     /// If user wants to connect to all profiles, when new profiles are discovered we will also try
376     /// to connect them.
377     pub connect_to_new_profiles: bool,
378 }
379 
380 impl BluetoothDeviceContext {
new( bond_state: BtBondState, bredr_acl_state: BtAclState, ble_acl_state: BtAclState, info: BluetoothDevice, last_seen: Instant, properties: Vec<BluetoothProperty>, ) -> BluetoothDeviceContext381     pub(crate) fn new(
382         bond_state: BtBondState,
383         bredr_acl_state: BtAclState,
384         ble_acl_state: BtAclState,
385         info: BluetoothDevice,
386         last_seen: Instant,
387         properties: Vec<BluetoothProperty>,
388     ) -> BluetoothDeviceContext {
389         let mut device = BluetoothDeviceContext {
390             acl_reported_transport: BtTransport::Auto,
391             bredr_acl_state,
392             ble_acl_state,
393             bond_state,
394             info,
395             last_seen,
396             properties: HashMap::new(),
397             is_initiated_hh_connection: false,
398             connect_to_new_profiles: false,
399         };
400         device.update_properties(&properties);
401         device
402     }
403 
update_properties(&mut self, in_properties: &Vec<BluetoothProperty>)404     pub(crate) fn update_properties(&mut self, in_properties: &Vec<BluetoothProperty>) {
405         for prop in in_properties {
406             // Handle merging of certain properties.
407             match &prop {
408                 BluetoothProperty::BdAddr(bdaddr) => {
409                     self.info.address = *bdaddr;
410                     self.properties.insert(BtPropertyType::BdAddr, prop.clone());
411                 }
412                 BluetoothProperty::BdName(bdname) => {
413                     if !bdname.is_empty() {
414                         self.info.name = bdname.clone();
415                         self.properties.insert(BtPropertyType::BdName, prop.clone());
416                     }
417                 }
418                 BluetoothProperty::Uuids(new_uuids) => {
419                     // Merge the new and the old (if exist) UUIDs.
420                     self.properties
421                         .entry(BtPropertyType::Uuids)
422                         .and_modify(|old_prop| {
423                             if let BluetoothProperty::Uuids(old_uuids) = old_prop {
424                                 for uuid in new_uuids {
425                                     if !old_uuids.contains(uuid) {
426                                         old_uuids.push(*uuid);
427                                     }
428                                 }
429                             }
430                         })
431                         .or_insert(prop.clone());
432                 }
433                 _ => {
434                     self.properties.insert(prop.get_type(), prop.clone());
435                 }
436             }
437         }
438     }
439 
440     /// Mark this device as seen.
seen(&mut self)441     pub(crate) fn seen(&mut self) {
442         self.last_seen = Instant::now();
443     }
444 
get_default_transport(&self) -> BtTransport445     fn get_default_transport(&self) -> BtTransport {
446         self.properties.get(&BtPropertyType::TypeOfDevice).map_or(BtTransport::Auto, |prop| {
447             match prop {
448                 BluetoothProperty::TypeOfDevice(t) => match *t {
449                     BtDeviceType::Bredr => BtTransport::Bredr,
450                     BtDeviceType::Ble => BtTransport::Le,
451                     _ => BtTransport::Auto,
452                 },
453                 _ => BtTransport::Auto,
454             }
455         })
456     }
457 
458     /// Check if it is connected in at least one transport.
is_connected(&self) -> bool459     fn is_connected(&self) -> bool {
460         self.bredr_acl_state == BtAclState::Connected || self.ble_acl_state == BtAclState::Connected
461     }
462 
463     /// Set ACL state given transport. Return true if state changed.
set_transport_state(&mut self, transport: &BtTransport, state: &BtAclState) -> bool464     fn set_transport_state(&mut self, transport: &BtTransport, state: &BtAclState) -> bool {
465         match (transport, self.get_default_transport()) {
466             (t, d)
467                 if *t == BtTransport::Bredr
468                     || (*t == BtTransport::Auto && d == BtTransport::Bredr) =>
469             {
470                 if self.bredr_acl_state == *state {
471                     return false;
472                 }
473                 self.bredr_acl_state = state.clone();
474             }
475             (t, d)
476                 if *t == BtTransport::Le || (*t == BtTransport::Auto && d == BtTransport::Le) =>
477             {
478                 if self.ble_acl_state == *state {
479                     return false;
480                 }
481                 self.ble_acl_state = state.clone();
482             }
483             // both link transport and the default transport are Auto.
484             _ => {
485                 warn!("Unable to decide the transport! Set current connection states bredr({:?}), ble({:?}) to {:?}", self.bredr_acl_state, self.ble_acl_state, *state);
486                 if self.bredr_acl_state == *state && self.ble_acl_state == *state {
487                     return false;
488                 }
489                 // There is no way for us to know which transport the link is referring to in this case.
490                 self.ble_acl_state = state.clone();
491                 self.bredr_acl_state = state.clone();
492                 return true;
493             }
494         };
495         true
496     }
497 }
498 
499 /// Structure to track all the signals for SIGTERM.
500 pub struct SigData {
501     pub enabled: Mutex<bool>,
502     pub enabled_notify: Condvar,
503 
504     pub thread_attached: Mutex<bool>,
505     pub thread_notify: Condvar,
506 
507     pub api_enabled: Mutex<bool>,
508     pub api_notify: Condvar,
509 }
510 
511 /// The interface for adapter callbacks registered through `IBluetooth::register_callback`.
512 pub trait IBluetoothCallback: RPCProxy {
513     /// When any adapter property changes.
on_adapter_property_changed(&mut self, prop: BtPropertyType)514     fn on_adapter_property_changed(&mut self, prop: BtPropertyType);
515 
516     /// When any device properties change.
on_device_properties_changed( &mut self, remote_device: BluetoothDevice, props: Vec<BtPropertyType>, )517     fn on_device_properties_changed(
518         &mut self,
519         remote_device: BluetoothDevice,
520         props: Vec<BtPropertyType>,
521     );
522 
523     /// When any of the adapter local address is changed.
on_address_changed(&mut self, addr: RawAddress)524     fn on_address_changed(&mut self, addr: RawAddress);
525 
526     /// When the adapter name is changed.
on_name_changed(&mut self, name: String)527     fn on_name_changed(&mut self, name: String);
528 
529     /// When the adapter's discoverable mode is changed.
on_discoverable_changed(&mut self, discoverable: bool)530     fn on_discoverable_changed(&mut self, discoverable: bool);
531 
532     /// When a device is found via discovery.
on_device_found(&mut self, remote_device: BluetoothDevice)533     fn on_device_found(&mut self, remote_device: BluetoothDevice);
534 
535     /// When a device is cleared from discovered devices cache.
on_device_cleared(&mut self, remote_device: BluetoothDevice)536     fn on_device_cleared(&mut self, remote_device: BluetoothDevice);
537 
538     /// When a device is missing keys.
on_device_key_missing(&mut self, remote_device: BluetoothDevice)539     fn on_device_key_missing(&mut self, remote_device: BluetoothDevice);
540 
541     /// When the discovery state is changed.
on_discovering_changed(&mut self, discovering: bool)542     fn on_discovering_changed(&mut self, discovering: bool);
543 
544     /// When there is a pairing/bonding process and requires agent to display the event to UI.
on_ssp_request( &mut self, remote_device: BluetoothDevice, cod: u32, variant: BtSspVariant, passkey: u32, )545     fn on_ssp_request(
546         &mut self,
547         remote_device: BluetoothDevice,
548         cod: u32,
549         variant: BtSspVariant,
550         passkey: u32,
551     );
552 
553     /// When there is a pin request to display the event to client.
on_pin_request(&mut self, remote_device: BluetoothDevice, cod: u32, min_16_digit: bool)554     fn on_pin_request(&mut self, remote_device: BluetoothDevice, cod: u32, min_16_digit: bool);
555 
556     /// When there is a auto-gen pin to display the event to client.
on_pin_display(&mut self, remote_device: BluetoothDevice, pincode: String)557     fn on_pin_display(&mut self, remote_device: BluetoothDevice, pincode: String);
558 
559     /// When a bonding attempt has completed.
on_bond_state_changed(&mut self, status: u32, device_address: RawAddress, state: u32)560     fn on_bond_state_changed(&mut self, status: u32, device_address: RawAddress, state: u32);
561 
562     /// When an SDP search has completed.
on_sdp_search_complete( &mut self, remote_device: BluetoothDevice, searched_uuid: Uuid, sdp_records: Vec<BtSdpRecord>, )563     fn on_sdp_search_complete(
564         &mut self,
565         remote_device: BluetoothDevice,
566         searched_uuid: Uuid,
567         sdp_records: Vec<BtSdpRecord>,
568     );
569 
570     /// When an SDP record has been successfully created.
on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32)571     fn on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32);
572 }
573 
574 pub trait IBluetoothConnectionCallback: RPCProxy {
575     /// Notification sent when a remote device completes HCI connection.
on_device_connected(&mut self, remote_device: BluetoothDevice)576     fn on_device_connected(&mut self, remote_device: BluetoothDevice);
577 
578     /// Notification sent when a remote device completes HCI disconnection.
on_device_disconnected(&mut self, remote_device: BluetoothDevice)579     fn on_device_disconnected(&mut self, remote_device: BluetoothDevice);
580 
581     /// Notification sent when a remote device fails to complete HCI connection.
on_device_connection_failed(&mut self, remote_device: BluetoothDevice, status: BtStatus)582     fn on_device_connection_failed(&mut self, remote_device: BluetoothDevice, status: BtStatus);
583 }
584 
585 /// Implementation of the adapter API.
586 pub struct Bluetooth {
587     intf: Arc<Mutex<BluetoothInterface>>,
588 
589     virt_index: i32,
590     hci_index: i32,
591     remote_devices: HashMap<RawAddress, BluetoothDeviceContext>,
592     ble_scanner_id: Option<u8>,
593     ble_scanner_uuid: Option<Uuid>,
594     bluetooth_gatt: Option<Arc<Mutex<Box<BluetoothGatt>>>>,
595     bluetooth_media: Option<Arc<Mutex<Box<BluetoothMedia>>>>,
596     callbacks: Callbacks<dyn IBluetoothCallback + Send>,
597     connection_callbacks: Callbacks<dyn IBluetoothConnectionCallback + Send>,
598     discovering_started: Instant,
599     hh: Option<HidHost>,
600     is_connectable: bool,
601     is_socket_listening: bool,
602     discoverable_mode: BtDiscMode,
603     discoverable_duration: u32,
604     // This refers to the suspend mode of the functionality related to Classic scan mode,
605     // i.e., page scan and inquiry scan; Also known as connectable and discoverable.
606     scan_suspend_mode: SuspendMode,
607     is_discovering: bool,
608     is_discovering_before_suspend: bool,
609     is_discovery_paused: bool,
610     discovery_suspend_mode: SuspendMode,
611     local_address: Option<RawAddress>,
612     pending_discovery: bool,
613     properties: HashMap<BtPropertyType, BluetoothProperty>,
614     profiles_ready: bool,
615     freshness_check: Option<JoinHandle<()>>,
616     sdp: Option<Sdp>,
617     state: BtState,
618     disabling: bool,
619     tx: Sender<Message>,
620     api_tx: Sender<APIMessage>,
621     // Internal API members
622     discoverable_timeout: Option<JoinHandle<()>>,
623     cancelling_devices: HashSet<RawAddress>,
624     pending_create_bond: Option<(BluetoothDevice, BtTransport)>,
625     active_pairing_address: Option<RawAddress>,
626     le_supported_states: u64,
627     le_local_supported_features: u64,
628 
629     /// Used to notify signal handler that we have turned off the stack.
630     sig_notifier: Arc<SigData>,
631 
632     /// Virtual uhid device created to keep bluetooth as a wakeup source.
633     uhid_wakeup_source: UHid,
634 }
635 
636 impl Bluetooth {
637     /// Constructs the IBluetooth implementation.
new( virt_index: i32, hci_index: i32, tx: Sender<Message>, api_tx: Sender<APIMessage>, sig_notifier: Arc<SigData>, intf: Arc<Mutex<BluetoothInterface>>, ) -> Bluetooth638     pub fn new(
639         virt_index: i32,
640         hci_index: i32,
641         tx: Sender<Message>,
642         api_tx: Sender<APIMessage>,
643         sig_notifier: Arc<SigData>,
644         intf: Arc<Mutex<BluetoothInterface>>,
645     ) -> Bluetooth {
646         Bluetooth {
647             virt_index,
648             hci_index,
649             remote_devices: HashMap::new(),
650             callbacks: Callbacks::new(tx.clone(), Message::AdapterCallbackDisconnected),
651             connection_callbacks: Callbacks::new(
652                 tx.clone(),
653                 Message::ConnectionCallbackDisconnected,
654             ),
655             hh: None,
656             ble_scanner_id: None,
657             ble_scanner_uuid: None,
658             bluetooth_gatt: None,
659             bluetooth_media: None,
660             discovering_started: Instant::now(),
661             intf,
662             is_connectable: false,
663             is_socket_listening: false,
664             discoverable_mode: BtDiscMode::NonDiscoverable,
665             discoverable_duration: 0,
666             scan_suspend_mode: SuspendMode::Normal,
667             is_discovering: false,
668             is_discovering_before_suspend: false,
669             is_discovery_paused: false,
670             discovery_suspend_mode: SuspendMode::Normal,
671             local_address: None,
672             pending_discovery: false,
673             properties: HashMap::new(),
674             profiles_ready: false,
675             freshness_check: None,
676             sdp: None,
677             state: BtState::Off,
678             disabling: false,
679             tx,
680             api_tx,
681             // Internal API members
682             discoverable_timeout: None,
683             cancelling_devices: HashSet::new(),
684             pending_create_bond: None,
685             active_pairing_address: None,
686             le_supported_states: 0u64,
687             le_local_supported_features: 0u64,
688             sig_notifier,
689             uhid_wakeup_source: UHid::new(),
690         }
691     }
692 
set_media(&mut self, bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>)693     pub(crate) fn set_media(&mut self, bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>) {
694         self.bluetooth_media = Some(bluetooth_media);
695     }
696 
set_gatt_and_init_scanner( &mut self, bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>, )697     pub(crate) fn set_gatt_and_init_scanner(
698         &mut self,
699         bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
700     ) {
701         self.bluetooth_gatt = Some(bluetooth_gatt.clone());
702 
703         // Initialize the BLE scanner for discovery.
704         let callback_id = bluetooth_gatt
705             .lock()
706             .unwrap()
707             .register_scanner_callback(Box::new(BleDiscoveryCallbacks::new(self.tx.clone())));
708         self.ble_scanner_uuid = Some(bluetooth_gatt.lock().unwrap().register_scanner(callback_id));
709     }
710 
update_connectable_mode(&mut self)711     fn update_connectable_mode(&mut self) {
712         // Don't bother if we are disabling. See b/361510982
713         if self.disabling {
714             return;
715         }
716         if self.get_scan_suspend_mode() != SuspendMode::Normal {
717             return;
718         }
719         // Set connectable if
720         // - there is bredr socket listening, or
721         // - there is a classic device bonded and not connected
722         self.set_connectable_internal(
723             self.is_socket_listening
724                 || self.remote_devices.values().any(|ctx| {
725                     ctx.bond_state == BtBondState::Bonded
726                         && ctx.bredr_acl_state == BtAclState::Disconnected
727                         && ctx
728                             .properties
729                             .get(&BtPropertyType::TypeOfDevice)
730                             .and_then(|prop| match prop {
731                                 BluetoothProperty::TypeOfDevice(transport) => {
732                                     Some(*transport != BtDeviceType::Ble)
733                                 }
734                                 _ => None,
735                             })
736                             .unwrap_or(false)
737                 }),
738         );
739     }
740 
set_socket_listening(&mut self, is_listening: bool)741     pub(crate) fn set_socket_listening(&mut self, is_listening: bool) {
742         if self.is_socket_listening == is_listening {
743             return;
744         }
745         self.is_socket_listening = is_listening;
746         self.update_connectable_mode();
747     }
748 
get_hci_index(&self) -> u16749     pub(crate) fn get_hci_index(&self) -> u16 {
750         self.hci_index as u16
751     }
752 
handle_admin_policy_changed( &mut self, admin_policy_helper: BluetoothAdminPolicyHelper, )753     pub(crate) fn handle_admin_policy_changed(
754         &mut self,
755         admin_policy_helper: BluetoothAdminPolicyHelper,
756     ) {
757         match (
758             admin_policy_helper.is_profile_allowed(&Profile::Hid),
759             self.hh.as_ref().unwrap().is_hidp_activated,
760         ) {
761             (true, false) => self.hh.as_mut().unwrap().activate_hidp(true),
762             (false, true) => self.hh.as_mut().unwrap().activate_hidp(false),
763             _ => {}
764         }
765 
766         match (
767             admin_policy_helper.is_profile_allowed(&Profile::Hogp),
768             self.hh.as_ref().unwrap().is_hogp_activated,
769         ) {
770             (true, false) => self.hh.as_mut().unwrap().activate_hogp(true),
771             (false, true) => self.hh.as_mut().unwrap().activate_hogp(false),
772             _ => {}
773         }
774 
775         if self.hh.as_mut().unwrap().configure_enabled_profiles() {
776             self.hh.as_mut().unwrap().disable();
777             let tx = self.tx.clone();
778 
779             tokio::spawn(async move {
780                 // Wait 100 milliseconds to prevent race condition caused by quick disable then
781                 // enable.
782                 // TODO: (b/272191117): don't enable until we're sure disable is done.
783                 tokio::time::sleep(Duration::from_millis(100)).await;
784                 let _ = tx.send(Message::HidHostEnable).await;
785             });
786         }
787     }
788 
enable_hidhost(&mut self)789     pub fn enable_hidhost(&mut self) {
790         self.hh.as_mut().unwrap().enable();
791     }
792 
init_profiles(&mut self)793     pub fn init_profiles(&mut self) {
794         self.sdp = Some(Sdp::new(&self.intf.lock().unwrap()));
795         self.sdp.as_mut().unwrap().initialize(SdpCallbacksDispatcher {
796             dispatch: make_message_dispatcher(self.tx.clone(), Message::Sdp),
797         });
798 
799         self.hh = Some(HidHost::new(&self.intf.lock().unwrap()));
800         self.hh.as_mut().unwrap().initialize(HHCallbacksDispatcher {
801             dispatch: make_message_dispatcher(self.tx.clone(), Message::HidHost),
802         });
803 
804         // Mark profiles as ready
805         self.profiles_ready = true;
806     }
807 
update_local_address(&mut self, addr: RawAddress)808     fn update_local_address(&mut self, addr: RawAddress) {
809         self.local_address = Some(addr);
810 
811         self.callbacks.for_all_callbacks(|callback| {
812             callback.on_address_changed(addr);
813         });
814     }
815 
adapter_callback_disconnected(&mut self, id: u32)816     pub(crate) fn adapter_callback_disconnected(&mut self, id: u32) {
817         self.callbacks.remove_callback(id);
818     }
819 
connection_callback_disconnected(&mut self, id: u32)820     pub(crate) fn connection_callback_disconnected(&mut self, id: u32) {
821         self.connection_callbacks.remove_callback(id);
822     }
823 
shutdown_adapter(&mut self, abort: bool) -> bool824     pub fn shutdown_adapter(&mut self, abort: bool) -> bool {
825         self.disabling = true;
826 
827         if !abort {
828             if !self.set_discoverable(BtDiscMode::NonDiscoverable, 0) {
829                 warn!("set_discoverable failed on disabling");
830             }
831             if !self.set_connectable_internal(false) {
832                 warn!("set_connectable_internal failed on disabling");
833             }
834         }
835 
836         self.intf.lock().unwrap().disable() == 0
837     }
838 
get_remote_device_property( &self, device: &BluetoothDevice, property_type: &BtPropertyType, ) -> Option<BluetoothProperty>839     fn get_remote_device_property(
840         &self,
841         device: &BluetoothDevice,
842         property_type: &BtPropertyType,
843     ) -> Option<BluetoothProperty> {
844         self.remote_devices
845             .get(&device.address)
846             .and_then(|d| d.properties.get(property_type))
847             .cloned()
848     }
849 
set_remote_device_property( &mut self, device: &BluetoothDevice, property_type: BtPropertyType, property: BluetoothProperty, ) -> Result<(), ()>850     fn set_remote_device_property(
851         &mut self,
852         device: &BluetoothDevice,
853         property_type: BtPropertyType,
854         property: BluetoothProperty,
855     ) -> Result<(), ()> {
856         let Some(remote_device) = self.remote_devices.get_mut(&device.address) else {
857             return Err(());
858         };
859 
860         // TODO: Determine why a callback isn't invoked to do this.
861         remote_device.properties.insert(property_type, property.clone());
862         self.intf.lock().unwrap().set_remote_device_property(&mut device.address.clone(), property);
863         Ok(())
864     }
865 
866     /// Returns whether the adapter is connectable.
get_connectable_internal(&self) -> bool867     pub(crate) fn get_connectable_internal(&self) -> bool {
868         self.discoverable_mode != BtDiscMode::NonDiscoverable || self.is_connectable
869     }
870 
871     /// Sets the adapter's connectable mode for classic connections.
set_connectable_internal(&mut self, mode: bool) -> bool872     pub(crate) fn set_connectable_internal(&mut self, mode: bool) -> bool {
873         if self.get_scan_suspend_mode() != SuspendMode::Normal {
874             // We will always trigger an update on resume so no need so store the mode change.
875             return false;
876         }
877         if self.is_connectable == mode {
878             return true;
879         }
880         if self.discoverable_mode != BtDiscMode::NonDiscoverable {
881             // Discoverable always implies connectable. Don't affect the discoverable mode for now
882             // and the connectable mode would be restored when discoverable becomes off.
883             self.is_connectable = mode;
884             return true;
885         }
886         self.intf.lock().unwrap().set_scan_mode(if mode {
887             BtScanMode::Connectable
888         } else {
889             BtScanMode::None_
890         });
891         self.is_connectable = mode;
892         true
893     }
894 
895     /// Returns adapter's discoverable mode.
get_discoverable_mode_internal(&self) -> BtDiscMode896     pub(crate) fn get_discoverable_mode_internal(&self) -> BtDiscMode {
897         self.discoverable_mode.clone()
898     }
899 
900     /// Set the suspend mode for scan mode (connectable/discoverable mode).
set_scan_suspend_mode(&mut self, suspend_mode: SuspendMode)901     pub(crate) fn set_scan_suspend_mode(&mut self, suspend_mode: SuspendMode) {
902         if suspend_mode != self.scan_suspend_mode {
903             self.scan_suspend_mode = suspend_mode;
904         }
905     }
906 
907     /// Gets current suspend mode for scan mode (connectable/discoverable mode).
get_scan_suspend_mode(&self) -> SuspendMode908     pub(crate) fn get_scan_suspend_mode(&self) -> SuspendMode {
909         self.scan_suspend_mode.clone()
910     }
911 
912     /// Enters the suspend mode for scan mode (connectable/discoverable mode).
scan_mode_enter_suspend(&mut self) -> BtStatus913     pub(crate) fn scan_mode_enter_suspend(&mut self) -> BtStatus {
914         if self.get_scan_suspend_mode() != SuspendMode::Normal {
915             return BtStatus::Busy;
916         }
917         self.set_scan_suspend_mode(SuspendMode::Suspending);
918 
919         self.intf.lock().unwrap().set_scan_mode(BtScanMode::None_);
920 
921         self.set_scan_suspend_mode(SuspendMode::Suspended);
922 
923         BtStatus::Success
924     }
925 
926     /// Exits the suspend mode for scan mode (connectable/discoverable mode).
scan_mode_exit_suspend(&mut self) -> BtStatus927     pub(crate) fn scan_mode_exit_suspend(&mut self) -> BtStatus {
928         if self.get_scan_suspend_mode() != SuspendMode::Suspended {
929             return BtStatus::Busy;
930         }
931         self.set_scan_suspend_mode(SuspendMode::Resuming);
932 
933         let mode = match self.discoverable_mode {
934             BtDiscMode::LimitedDiscoverable => BtScanMode::ConnectableLimitedDiscoverable,
935             BtDiscMode::GeneralDiscoverable => BtScanMode::ConnectableDiscoverable,
936             BtDiscMode::NonDiscoverable => match self.is_connectable {
937                 true => BtScanMode::Connectable,
938                 false => BtScanMode::None_,
939             },
940         };
941         self.intf.lock().unwrap().set_scan_mode(mode);
942 
943         self.set_scan_suspend_mode(SuspendMode::Normal);
944 
945         // Update is only available after SuspendMode::Normal
946         self.update_connectable_mode();
947 
948         BtStatus::Success
949     }
950 
951     /// Returns adapter's alias.
get_alias_internal(&self) -> String952     pub(crate) fn get_alias_internal(&self) -> String {
953         let name = self.get_name();
954         if !name.is_empty() {
955             return name;
956         }
957 
958         // If the adapter name is empty, generate one based on local BDADDR
959         // so that test programs can have a friendly name for the adapter.
960         match self.local_address {
961             None => "floss_0000".to_string(),
962             Some(addr) => format!("floss_{:02X}{:02X}", addr.address[4], addr.address[5]),
963         }
964     }
965 
966     // TODO(b/328675014): Add BtAddrType and BtTransport parameters
get_hid_report_internal( &mut self, mut addr: RawAddress, report_type: BthhReportType, report_id: u8, ) -> BtStatus967     pub(crate) fn get_hid_report_internal(
968         &mut self,
969         mut addr: RawAddress,
970         report_type: BthhReportType,
971         report_id: u8,
972     ) -> BtStatus {
973         self.hh.as_mut().unwrap().get_report(
974             &mut addr,
975             BtAddrType::Public,
976             BtTransport::Auto,
977             report_type,
978             report_id,
979             128,
980         )
981     }
982 
983     // TODO(b/328675014): Add BtAddrType and BtTransport parameters
set_hid_report_internal( &mut self, mut addr: RawAddress, report_type: BthhReportType, report: String, ) -> BtStatus984     pub(crate) fn set_hid_report_internal(
985         &mut self,
986         mut addr: RawAddress,
987         report_type: BthhReportType,
988         report: String,
989     ) -> BtStatus {
990         let mut rb = report.clone().into_bytes();
991         self.hh.as_mut().unwrap().set_report(
992             &mut addr,
993             BtAddrType::Public,
994             BtTransport::Auto,
995             report_type,
996             rb.as_mut_slice(),
997         )
998     }
999 
1000     // TODO(b/328675014): Add BtAddrType and BtTransport parameters
send_hid_data_internal( &mut self, mut addr: RawAddress, data: String, ) -> BtStatus1001     pub(crate) fn send_hid_data_internal(
1002         &mut self,
1003         mut addr: RawAddress,
1004         data: String,
1005     ) -> BtStatus {
1006         let mut rb = data.clone().into_bytes();
1007         self.hh.as_mut().unwrap().send_data(
1008             &mut addr,
1009             BtAddrType::Public,
1010             BtTransport::Auto,
1011             rb.as_mut_slice(),
1012         )
1013     }
1014 
1015     // TODO(b/328675014): Add BtAddrType and BtTransport parameters
send_hid_virtual_unplug_internal(&mut self, mut addr: RawAddress) -> BtStatus1016     pub(crate) fn send_hid_virtual_unplug_internal(&mut self, mut addr: RawAddress) -> BtStatus {
1017         self.hh.as_mut().unwrap().virtual_unplug(&mut addr, BtAddrType::Public, BtTransport::Auto)
1018     }
1019 
1020     /// Returns all bonded and connected devices.
get_bonded_and_connected_devices(&mut self) -> Vec<BluetoothDevice>1021     pub(crate) fn get_bonded_and_connected_devices(&mut self) -> Vec<BluetoothDevice> {
1022         self.remote_devices
1023             .values()
1024             .filter(|v| v.is_connected() && v.bond_state == BtBondState::Bonded)
1025             .map(|v| v.info.clone())
1026             .collect()
1027     }
1028 
1029     /// Returns all devices with UUIDs, while None means there's not yet an UUID property change.
get_all_devices_and_uuids(&self) -> Vec<(BluetoothDevice, Option<Vec<Uuid>>)>1030     pub(crate) fn get_all_devices_and_uuids(&self) -> Vec<(BluetoothDevice, Option<Vec<Uuid>>)> {
1031         self.remote_devices
1032             .values()
1033             .map(|d| {
1034                 let uuids = d.properties.get(&BtPropertyType::Uuids).and_then(|prop| match prop {
1035                     BluetoothProperty::Uuids(uuids) => Some(uuids.clone()),
1036                     _ => None,
1037                 });
1038                 (d.info.clone(), uuids)
1039             })
1040             .collect()
1041     }
1042 
1043     /// Gets the bond state of a single device with its address.
get_bond_state_by_addr(&self, addr: &RawAddress) -> BtBondState1044     pub fn get_bond_state_by_addr(&self, addr: &RawAddress) -> BtBondState {
1045         self.remote_devices.get(addr).map_or(BtBondState::NotBonded, |d| d.bond_state.clone())
1046     }
1047 
1048     /// Gets whether a single device is connected with its address.
get_acl_state_by_addr(&self, addr: &RawAddress) -> bool1049     fn get_acl_state_by_addr(&self, addr: &RawAddress) -> bool {
1050         self.remote_devices.get(addr).map_or(false, |d| d.is_connected())
1051     }
1052 
1053     /// Check whether remote devices are still fresh. If they're outside the
1054     /// freshness window, send a notification to clear the device from clients.
trigger_freshness_check(&mut self)1055     fn trigger_freshness_check(&mut self) {
1056         // A remote device is considered fresh if:
1057         // * It was last seen less than |FOUND_DEVICE_FRESHNESS| ago.
1058         // * It is bonded / bonding (i.e., not NotBonded)
1059         // * It is currently connected.
1060         fn is_fresh(d: &BluetoothDeviceContext, now: &Instant) -> bool {
1061             let fresh_at = d.last_seen + FOUND_DEVICE_FRESHNESS;
1062             now < &fresh_at || d.is_connected() || d.bond_state != BtBondState::NotBonded
1063         }
1064 
1065         let now = Instant::now();
1066         let stale_devices: Vec<BluetoothDevice> = self
1067             .remote_devices
1068             .values()
1069             .filter(|d| !is_fresh(d, &now))
1070             .map(|d| d.info.clone())
1071             .collect();
1072 
1073         // Retain only devices that are fresh.
1074         self.remote_devices.retain(|_, d| is_fresh(d, &now));
1075 
1076         for d in stale_devices {
1077             self.callbacks.for_all_callbacks(|callback| {
1078                 callback.on_device_cleared(d.clone());
1079             });
1080         }
1081     }
1082 
send_metrics_remote_device_info(device: &BluetoothDeviceContext)1083     fn send_metrics_remote_device_info(device: &BluetoothDeviceContext) {
1084         if device.bond_state != BtBondState::Bonded && !device.is_connected() {
1085             return;
1086         }
1087 
1088         let mut class_of_device = 0u32;
1089         let mut device_type = BtDeviceType::Unknown;
1090         let mut appearance = 0u16;
1091         let mut vpi =
1092             BtVendorProductInfo { vendor_id_src: 0, vendor_id: 0, product_id: 0, version: 0 };
1093 
1094         for prop in device.properties.values() {
1095             match prop {
1096                 BluetoothProperty::TypeOfDevice(p) => device_type = p.clone(),
1097                 BluetoothProperty::ClassOfDevice(p) => class_of_device = *p,
1098                 BluetoothProperty::Appearance(p) => appearance = *p,
1099                 BluetoothProperty::VendorProductInfo(p) => vpi = *p,
1100                 _ => (),
1101             }
1102         }
1103 
1104         metrics::device_info_report(
1105             device.info.address,
1106             device_type,
1107             class_of_device,
1108             appearance,
1109             vpi.vendor_id,
1110             vpi.vendor_id_src,
1111             vpi.product_id,
1112             vpi.version,
1113         );
1114     }
1115 
1116     /// Handle adapter actions.
handle_actions(&mut self, action: AdapterActions)1117     pub(crate) fn handle_actions(&mut self, action: AdapterActions) {
1118         match action {
1119             AdapterActions::DeviceFreshnessCheck => {
1120                 self.trigger_freshness_check();
1121             }
1122 
1123             AdapterActions::ConnectAllProfiles(device) => {
1124                 self.connect_all_enabled_profiles(device);
1125             }
1126 
1127             AdapterActions::ConnectProfiles(uuids, device) => {
1128                 self.connect_profiles_internal(&uuids, device);
1129             }
1130 
1131             AdapterActions::BleDiscoveryScannerRegistered(uuid, scanner_id, status) => {
1132                 if let Some(app_uuid) = self.ble_scanner_uuid {
1133                     if app_uuid == uuid {
1134                         if status == GattStatus::Success {
1135                             self.ble_scanner_id = Some(scanner_id);
1136                         } else {
1137                             log::error!("BLE discovery scanner failed to register: {:?}", status);
1138                         }
1139                     }
1140                 }
1141             }
1142 
1143             AdapterActions::BleDiscoveryScannerResult(result) => {
1144                 // Generate a vector of properties from ScanResult.
1145                 let properties = {
1146                     let mut props = vec![];
1147                     props.push(BluetoothProperty::BdName(result.name.clone()));
1148                     props.push(BluetoothProperty::BdAddr(result.address));
1149                     if !result.service_uuids.is_empty() {
1150                         props.push(BluetoothProperty::Uuids(result.service_uuids.clone()));
1151                     }
1152                     if !result.service_data.is_empty() {
1153                         props.push(BluetoothProperty::Uuids(
1154                             result
1155                                 .service_data
1156                                 .keys()
1157                                 .map(|v| Uuid::from_string(v).unwrap())
1158                                 .collect(),
1159                         ));
1160                     }
1161                     props.push(BluetoothProperty::RemoteRssi(result.rssi));
1162                     props.push(BluetoothProperty::RemoteAddrType((result.addr_type as u32).into()));
1163                     props
1164                 };
1165 
1166                 let device_info = BluetoothDevice::from_properties(&properties);
1167                 self.check_new_property_and_potentially_connect_profiles(
1168                     result.address,
1169                     &properties,
1170                 );
1171 
1172                 self.remote_devices
1173                     .entry(device_info.address)
1174                     .and_modify(|d| {
1175                         d.update_properties(&properties);
1176                         d.seen();
1177                     })
1178                     .or_insert(BluetoothDeviceContext::new(
1179                         BtBondState::NotBonded,
1180                         BtAclState::Disconnected,
1181                         BtAclState::Disconnected,
1182                         device_info,
1183                         Instant::now(),
1184                         properties,
1185                     ));
1186             }
1187 
1188             AdapterActions::ResetDiscoverable => {
1189                 self.set_discoverable(BtDiscMode::NonDiscoverable, 0);
1190             }
1191 
1192             AdapterActions::CreateBond => {
1193                 if let Some((device, transport)) = self.pending_create_bond.take() {
1194                     let status = self.create_bond(device, transport);
1195                     if status != BtStatus::Success {
1196                         error!("Failed CreateBond status={:?}", status);
1197                     }
1198                 }
1199             }
1200         }
1201     }
1202 
1203     /// Creates a file to notify btmanagerd the adapter is enabled.
create_pid_file(&self) -> std::io::Result<()>1204     fn create_pid_file(&self) -> std::io::Result<()> {
1205         let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.virt_index);
1206         let mut f = File::create(file_name)?;
1207         f.write_all(process::id().to_string().as_bytes())?;
1208         Ok(())
1209     }
1210 
1211     /// Removes the file to notify btmanagerd the adapter is disabled.
remove_pid_file(&self) -> std::io::Result<()>1212     fn remove_pid_file(&self) -> std::io::Result<()> {
1213         let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.virt_index);
1214         std::fs::remove_file(file_name)?;
1215         Ok(())
1216     }
1217 
1218     /// Set the suspend mode.
set_discovery_suspend_mode(&mut self, suspend_mode: SuspendMode)1219     pub fn set_discovery_suspend_mode(&mut self, suspend_mode: SuspendMode) {
1220         if suspend_mode != self.discovery_suspend_mode {
1221             self.discovery_suspend_mode = suspend_mode;
1222         }
1223     }
1224 
1225     /// Gets current suspend mode.
get_discovery_suspend_mode(&self) -> SuspendMode1226     pub fn get_discovery_suspend_mode(&self) -> SuspendMode {
1227         self.discovery_suspend_mode.clone()
1228     }
1229 
1230     /// Enters the suspend mode for discovery.
discovery_enter_suspend(&mut self) -> BtStatus1231     pub fn discovery_enter_suspend(&mut self) -> BtStatus {
1232         if self.get_discovery_suspend_mode() != SuspendMode::Normal {
1233             return BtStatus::Busy;
1234         }
1235         self.set_discovery_suspend_mode(SuspendMode::Suspending);
1236 
1237         if self.is_discovering {
1238             self.is_discovering_before_suspend = true;
1239             self.cancel_discovery();
1240         }
1241         self.set_discovery_suspend_mode(SuspendMode::Suspended);
1242 
1243         BtStatus::Success
1244     }
1245 
1246     /// Exits the suspend mode for discovery.
discovery_exit_suspend(&mut self) -> BtStatus1247     pub fn discovery_exit_suspend(&mut self) -> BtStatus {
1248         if self.get_discovery_suspend_mode() != SuspendMode::Suspended {
1249             return BtStatus::Busy;
1250         }
1251         self.set_discovery_suspend_mode(SuspendMode::Resuming);
1252 
1253         if self.is_discovering_before_suspend {
1254             self.is_discovering_before_suspend = false;
1255             self.start_discovery();
1256         }
1257         self.set_discovery_suspend_mode(SuspendMode::Normal);
1258 
1259         BtStatus::Success
1260     }
1261 
1262     /// Temporarily stop the discovery process and mark it as paused so that clients cannot restart
1263     /// it.
pause_discovery(&mut self)1264     fn pause_discovery(&mut self) {
1265         self.cancel_discovery();
1266         self.is_discovery_paused = true;
1267     }
1268 
1269     /// Remove the paused flag to allow clients to begin discovery, and if there is already a
1270     /// pending request, start discovery.
resume_discovery(&mut self)1271     fn resume_discovery(&mut self) {
1272         self.is_discovery_paused = false;
1273         if self.pending_discovery {
1274             self.pending_discovery = false;
1275             self.start_discovery();
1276         }
1277     }
1278 
1279     /// Return if there are wake-allowed device in bonded status.
get_wake_allowed_device_bonded(&self) -> bool1280     fn get_wake_allowed_device_bonded(&self) -> bool {
1281         self.get_bonded_devices().into_iter().any(|d| self.get_remote_wake_allowed(d))
1282     }
1283 
1284     /// Powerd recognizes bluetooth activities as valid wakeup sources if powerd keeps bluetooth in
1285     /// the monitored path. This only happens if there is at least one valid wake-allowed BT device
1286     /// connected during the suspending process. If there is no BT devices connected at any time
1287     /// during the suspending process, the wakeup count will be lost, and system goes to dark
1288     /// resume instead of full resume.
1289     /// Bluetooth stack disconnects all physical bluetooth HID devices for suspend, so a virtual
1290     /// uhid device is necessary to keep bluetooth as a valid wakeup source.
create_uhid_for_suspend_wakesource(&mut self)1291     fn create_uhid_for_suspend_wakesource(&mut self) {
1292         if !self.uhid_wakeup_source.is_empty() {
1293             return;
1294         }
1295         match self.uhid_wakeup_source.create(
1296             "VIRTUAL_SUSPEND_UHID".to_string(),
1297             self.get_address(),
1298             RawAddress::empty(),
1299         ) {
1300             Err(e) => error!("Fail to create uhid {}", e),
1301             Ok(_) => (),
1302         }
1303     }
1304 
1305     /// Clear the UHID device.
clear_uhid(&mut self)1306     fn clear_uhid(&mut self) {
1307         self.uhid_wakeup_source.clear();
1308     }
1309 
1310     /// Checks whether pairing is busy.
is_pairing_busy(&self) -> bool1311     pub fn is_pairing_busy(&self) -> bool {
1312         self.intf.lock().unwrap().pairing_is_busy()
1313             || self.active_pairing_address.is_some()
1314             || self.pending_create_bond.is_some()
1315     }
1316 
1317     /// Checks whether a Hid/Hog connection is being established or active.
is_initiated_hh_connection(&self, device_address: &RawAddress) -> bool1318     pub fn is_initiated_hh_connection(&self, device_address: &RawAddress) -> bool {
1319         self.remote_devices
1320             .get(&device_address)
1321             .map_or(false, |context| context.is_initiated_hh_connection)
1322     }
1323 
1324     /// Checks whether the list of device properties contains some UUID we should connect now
1325     /// This function also connects those UUIDs.
check_new_property_and_potentially_connect_profiles( &self, addr: RawAddress, properties: &Vec<BluetoothProperty>, )1326     fn check_new_property_and_potentially_connect_profiles(
1327         &self,
1328         addr: RawAddress,
1329         properties: &Vec<BluetoothProperty>,
1330     ) {
1331         // Return early if no need to connect new profiles
1332         if !self.remote_devices.get(&addr).map_or(false, |d| d.connect_to_new_profiles) {
1333             return;
1334         }
1335 
1336         // Get the reported UUIDs, if any. Otherwise return early.
1337         let mut new_uuids: Vec<Uuid> = vec![];
1338         for prop in properties.iter() {
1339             if let BluetoothProperty::Uuids(value) = prop {
1340                 new_uuids.extend(value);
1341             }
1342         }
1343         if new_uuids.is_empty() {
1344             return;
1345         }
1346 
1347         // Only connect if the UUID is not seen before and it's supported
1348         let device = BluetoothDevice::new(addr, "".to_string());
1349         let current_uuids = self.get_remote_uuids(device.clone());
1350         new_uuids.retain(|uuid| !current_uuids.contains(uuid));
1351 
1352         let profile_known_and_supported = new_uuids.iter().any(|uuid| {
1353             if let Some(profile) = UuidHelper::is_known_profile(uuid) {
1354                 return UuidHelper::is_profile_supported(&profile);
1355             }
1356             return false;
1357         });
1358         if !profile_known_and_supported {
1359             return;
1360         }
1361 
1362         log::info!("[{}]: Connecting to newly discovered profiles", DisplayAddress(&addr));
1363         let tx = self.tx.clone();
1364         tokio::spawn(async move {
1365             let _ = tx
1366                 .send(Message::AdapterActions(AdapterActions::ConnectProfiles(new_uuids, device)))
1367                 .await;
1368         });
1369     }
1370 
1371     /// Connect these profiles of a peripheral device
connect_profiles_internal(&mut self, uuids: &Vec<Uuid>, device: BluetoothDevice)1372     fn connect_profiles_internal(&mut self, uuids: &Vec<Uuid>, device: BluetoothDevice) {
1373         let addr = device.address;
1374         if !self.get_acl_state_by_addr(&addr) {
1375             // log ACL connection attempt if it's not already connected.
1376             metrics::acl_connect_attempt(addr, BtAclState::Connected);
1377             // Pause discovery before connecting, or the ACL connection request may conflict with
1378             // the ongoing inquiry.
1379             self.pause_discovery();
1380         }
1381 
1382         let mut has_supported_profile = false;
1383         let mut has_le_media_profile = false;
1384         let mut has_classic_media_profile = false;
1385 
1386         for uuid in uuids.iter() {
1387             match UuidHelper::is_known_profile(uuid) {
1388                 Some(p) => {
1389                     if UuidHelper::is_profile_supported(&p) {
1390                         match p {
1391                             Profile::Hid | Profile::Hogp => {
1392                                 has_supported_profile = true;
1393                                 // TODO(b/328675014): Use BtAddrType
1394                                 // and BtTransport from
1395                                 // BluetoothDevice instead of default
1396                                 let status = self.hh.as_ref().unwrap().connect(
1397                                     &mut addr.clone(),
1398                                     BtAddrType::Public,
1399                                     BtTransport::Auto,
1400                                 );
1401                                 metrics::profile_connection_state_changed(
1402                                     addr,
1403                                     p as u32,
1404                                     BtStatus::Success,
1405                                     BthhConnectionState::Connecting as u32,
1406                                 );
1407 
1408                                 if status != BtStatus::Success {
1409                                     metrics::profile_connection_state_changed(
1410                                         addr,
1411                                         p as u32,
1412                                         status,
1413                                         BthhConnectionState::Disconnected as u32,
1414                                     );
1415                                 }
1416                             }
1417 
1418                             // TODO(b/317682584): implement policy to connect to LEA, VC, and CSIS
1419                             Profile::LeAudio | Profile::VolumeControl | Profile::CoordinatedSet
1420                                 if !has_le_media_profile =>
1421                             {
1422                                 has_le_media_profile = true;
1423                                 let txl = self.tx.clone();
1424                                 topstack::get_runtime().spawn(async move {
1425                                     let _ = txl
1426                                         .send(Message::Media(
1427                                             MediaActions::ConnectLeaGroupByMemberAddress(addr),
1428                                         ))
1429                                         .await;
1430                                 });
1431                             }
1432 
1433                             Profile::A2dpSink | Profile::A2dpSource | Profile::Hfp
1434                                 if !has_classic_media_profile =>
1435                             {
1436                                 has_supported_profile = true;
1437                                 has_classic_media_profile = true;
1438                                 let txl = self.tx.clone();
1439                                 topstack::get_runtime().spawn(async move {
1440                                     let _ =
1441                                         txl.send(Message::Media(MediaActions::Connect(addr))).await;
1442                                 });
1443                             }
1444 
1445                             // We don't connect most profiles
1446                             _ => (),
1447                         }
1448                     }
1449                 }
1450                 _ => {}
1451             }
1452         }
1453 
1454         // If the device does not have a profile that we are interested in connecting to, resume
1455         // discovery now. Other cases will be handled in the ACL connection state or bond state
1456         // callbacks.
1457         if !has_supported_profile {
1458             self.resume_discovery();
1459         }
1460     }
1461 
fire_device_connection_or_bonded_state_changed(&self, addr: RawAddress)1462     fn fire_device_connection_or_bonded_state_changed(&self, addr: RawAddress) {
1463         if let Some(device) = self.remote_devices.get(&addr) {
1464             let tx = self.tx.clone();
1465             let bredr_acl_state = device.bredr_acl_state.clone();
1466             let ble_acl_state = device.ble_acl_state.clone();
1467             let bond_state = device.bond_state.clone();
1468             let transport = match self.get_remote_type(device.info.clone()) {
1469                 BtDeviceType::Bredr => BtTransport::Bredr,
1470                 BtDeviceType::Ble => BtTransport::Le,
1471                 _ => device.acl_reported_transport.clone(),
1472             };
1473             tokio::spawn(async move {
1474                 let _ = tx
1475                     .send(Message::OnDeviceConnectionOrBondStateChanged(
1476                         addr,
1477                         bredr_acl_state,
1478                         ble_acl_state,
1479                         bond_state,
1480                         transport,
1481                     ))
1482                     .await;
1483             });
1484         }
1485     }
1486 }
1487 
1488 #[btif_callbacks_dispatcher(dispatch_base_callbacks, BaseCallbacks)]
1489 #[allow(unused_variables)]
1490 pub(crate) trait BtifBluetoothCallbacks {
1491     #[btif_callback(AdapterState)]
adapter_state_changed(&mut self, state: BtState)1492     fn adapter_state_changed(&mut self, state: BtState) {}
1493 
1494     #[btif_callback(AdapterProperties)]
adapter_properties_changed( &mut self, status: BtStatus, num_properties: i32, properties: Vec<BluetoothProperty>, )1495     fn adapter_properties_changed(
1496         &mut self,
1497         status: BtStatus,
1498         num_properties: i32,
1499         properties: Vec<BluetoothProperty>,
1500     ) {
1501     }
1502 
1503     #[btif_callback(DeviceFound)]
device_found(&mut self, n: i32, properties: Vec<BluetoothProperty>)1504     fn device_found(&mut self, n: i32, properties: Vec<BluetoothProperty>) {}
1505 
1506     #[btif_callback(DiscoveryState)]
discovery_state(&mut self, state: BtDiscoveryState)1507     fn discovery_state(&mut self, state: BtDiscoveryState) {}
1508 
1509     #[btif_callback(SspRequest)]
ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32)1510     fn ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32) {}
1511 
1512     #[btif_callback(BondState)]
bond_state( &mut self, status: BtStatus, addr: RawAddress, bond_state: BtBondState, fail_reason: i32, )1513     fn bond_state(
1514         &mut self,
1515         status: BtStatus,
1516         addr: RawAddress,
1517         bond_state: BtBondState,
1518         fail_reason: i32,
1519     ) {
1520     }
1521 
1522     #[btif_callback(RemoteDeviceProperties)]
remote_device_properties_changed( &mut self, status: BtStatus, addr: RawAddress, num_properties: i32, properties: Vec<BluetoothProperty>, )1523     fn remote_device_properties_changed(
1524         &mut self,
1525         status: BtStatus,
1526         addr: RawAddress,
1527         num_properties: i32,
1528         properties: Vec<BluetoothProperty>,
1529     ) {
1530     }
1531 
1532     #[btif_callback(AclState)]
acl_state( &mut self, status: BtStatus, addr: RawAddress, state: BtAclState, link_type: BtTransport, hci_reason: BtHciErrorCode, conn_direction: BtConnectionDirection, acl_handle: u16, )1533     fn acl_state(
1534         &mut self,
1535         status: BtStatus,
1536         addr: RawAddress,
1537         state: BtAclState,
1538         link_type: BtTransport,
1539         hci_reason: BtHciErrorCode,
1540         conn_direction: BtConnectionDirection,
1541         acl_handle: u16,
1542     ) {
1543     }
1544 
1545     #[btif_callback(LeRandCallback)]
le_rand_cb(&mut self, random: u64)1546     fn le_rand_cb(&mut self, random: u64) {}
1547 
1548     #[btif_callback(PinRequest)]
pin_request( &mut self, remote_addr: RawAddress, remote_name: String, cod: u32, min_16_digit: bool, )1549     fn pin_request(
1550         &mut self,
1551         remote_addr: RawAddress,
1552         remote_name: String,
1553         cod: u32,
1554         min_16_digit: bool,
1555     ) {
1556     }
1557 
1558     #[btif_callback(ThreadEvent)]
thread_event(&mut self, event: BtThreadEvent)1559     fn thread_event(&mut self, event: BtThreadEvent) {}
1560 
1561     #[btif_callback(KeyMissing)]
key_missing(&mut self, addr: RawAddress)1562     fn key_missing(&mut self, addr: RawAddress) {}
1563 }
1564 
1565 #[btif_callbacks_dispatcher(dispatch_hid_host_callbacks, HHCallbacks)]
1566 pub(crate) trait BtifHHCallbacks {
1567     #[btif_callback(ConnectionState)]
connection_state( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, state: BthhConnectionState, )1568     fn connection_state(
1569         &mut self,
1570         address: RawAddress,
1571         address_type: BtAddrType,
1572         transport: BtTransport,
1573         state: BthhConnectionState,
1574     );
1575 
1576     #[btif_callback(HidInfo)]
hid_info( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, info: BthhHidInfo, )1577     fn hid_info(
1578         &mut self,
1579         address: RawAddress,
1580         address_type: BtAddrType,
1581         transport: BtTransport,
1582         info: BthhHidInfo,
1583     );
1584 
1585     #[btif_callback(ProtocolMode)]
protocol_mode( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, mode: BthhProtocolMode, )1586     fn protocol_mode(
1587         &mut self,
1588         address: RawAddress,
1589         address_type: BtAddrType,
1590         transport: BtTransport,
1591         status: BthhStatus,
1592         mode: BthhProtocolMode,
1593     );
1594 
1595     #[btif_callback(IdleTime)]
idle_time( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, idle_rate: i32, )1596     fn idle_time(
1597         &mut self,
1598         address: RawAddress,
1599         address_type: BtAddrType,
1600         transport: BtTransport,
1601         status: BthhStatus,
1602         idle_rate: i32,
1603     );
1604 
1605     #[btif_callback(GetReport)]
get_report( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, data: Vec<u8>, size: i32, )1606     fn get_report(
1607         &mut self,
1608         address: RawAddress,
1609         address_type: BtAddrType,
1610         transport: BtTransport,
1611         status: BthhStatus,
1612         data: Vec<u8>,
1613         size: i32,
1614     );
1615 
1616     #[btif_callback(Handshake)]
handshake( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, )1617     fn handshake(
1618         &mut self,
1619         address: RawAddress,
1620         address_type: BtAddrType,
1621         transport: BtTransport,
1622         status: BthhStatus,
1623     );
1624 }
1625 
1626 #[btif_callbacks_dispatcher(dispatch_sdp_callbacks, SdpCallbacks)]
1627 pub(crate) trait BtifSdpCallbacks {
1628     #[btif_callback(SdpSearch)]
sdp_search( &mut self, status: BtStatus, address: RawAddress, uuid: Uuid, count: i32, records: Vec<BtSdpRecord>, )1629     fn sdp_search(
1630         &mut self,
1631         status: BtStatus,
1632         address: RawAddress,
1633         uuid: Uuid,
1634         count: i32,
1635         records: Vec<BtSdpRecord>,
1636     );
1637 }
1638 
get_bt_dispatcher(tx: Sender<Message>) -> BaseCallbacksDispatcher1639 pub fn get_bt_dispatcher(tx: Sender<Message>) -> BaseCallbacksDispatcher {
1640     BaseCallbacksDispatcher { dispatch: make_message_dispatcher(tx, Message::Base) }
1641 }
1642 
1643 impl BtifBluetoothCallbacks for Bluetooth {
1644     #[log_cb_args]
adapter_state_changed(&mut self, state: BtState)1645     fn adapter_state_changed(&mut self, state: BtState) {
1646         let prev_state = self.state.clone();
1647         self.state = state;
1648         metrics::adapter_state_changed(self.state.clone());
1649 
1650         // If it's the same state as before, no further action
1651         if self.state == prev_state {
1652             return;
1653         }
1654 
1655         match self.state {
1656             BtState::Off => {
1657                 self.properties.clear();
1658                 match self.remove_pid_file() {
1659                     Err(err) => warn!("remove_pid_file() error: {}", err),
1660                     _ => (),
1661                 }
1662 
1663                 self.clear_uhid();
1664 
1665                 // Let the signal notifier know we are turned off.
1666                 *self.sig_notifier.enabled.lock().unwrap() = false;
1667                 self.sig_notifier.enabled_notify.notify_all();
1668             }
1669 
1670             BtState::On => {
1671                 // Initialize core profiles
1672                 self.init_profiles();
1673 
1674                 // Trigger properties update
1675                 self.intf.lock().unwrap().get_adapter_properties();
1676 
1677                 // Also need to manually request some properties
1678                 self.intf.lock().unwrap().get_adapter_property(BtPropertyType::ClassOfDevice);
1679                 let mut controller = controller::Controller::new();
1680                 self.le_supported_states = controller.get_ble_supported_states();
1681                 self.le_local_supported_features = controller.get_ble_local_supported_features();
1682 
1683                 // Update connectable mode so that disconnected bonded classic device can reconnect
1684                 self.update_connectable_mode();
1685 
1686                 // Spawn a freshness check job in the background.
1687                 if let Some(h) = self.freshness_check.take() {
1688                     h.abort()
1689                 }
1690                 let txl = self.tx.clone();
1691                 self.freshness_check = Some(tokio::spawn(async move {
1692                     loop {
1693                         time::sleep(FOUND_DEVICE_FRESHNESS).await;
1694                         let _ = txl
1695                             .send(Message::AdapterActions(AdapterActions::DeviceFreshnessCheck))
1696                             .await;
1697                     }
1698                 }));
1699 
1700                 if self.get_wake_allowed_device_bonded() {
1701                     self.create_uhid_for_suspend_wakesource();
1702                 }
1703                 // Notify the signal notifier that we are turned on.
1704                 *self.sig_notifier.enabled.lock().unwrap() = true;
1705                 self.sig_notifier.enabled_notify.notify_all();
1706 
1707                 // Signal that the stack is up and running.
1708                 match self.create_pid_file() {
1709                     Err(err) => warn!("create_pid_file() error: {}", err),
1710                     _ => (),
1711                 }
1712 
1713                 // Inform the rest of the stack we're ready.
1714                 let txl = self.tx.clone();
1715                 let api_txl = self.api_tx.clone();
1716                 tokio::spawn(async move {
1717                     let _ = txl.send(Message::AdapterReady).await;
1718                 });
1719                 tokio::spawn(async move {
1720                     let _ = api_txl.send(APIMessage::IsReady(BluetoothAPI::Adapter)).await;
1721                 });
1722                 // Log LL privacy states.
1723                 // LL privacy is set according to feature flag when initializing chrome. When the
1724                 // sysprop override file is updated, the adapter is powered off/on to read the new
1725                 // settings. As a result, log the LL privacy state at adapter on.
1726                 // Multiple users may have different LL privacy settings, and the user setting is
1727                 // applied at user login.
1728                 let llp_state =
1729                     u32::from(sysprop::get_bool(sysprop::PropertyBool::LePrivacyEnabled));
1730                 let rpa_state = u32::from(sysprop::get_bool(
1731                     sysprop::PropertyBool::LePrivacyOwnAddressTypeEnabled,
1732                 ));
1733                 metrics::ll_privacy_state(llp_state, rpa_state);
1734             }
1735         }
1736     }
1737 
1738     #[allow(unused_variables)]
1739     #[log_cb_args]
adapter_properties_changed( &mut self, status: BtStatus, num_properties: i32, properties: Vec<BluetoothProperty>, )1740     fn adapter_properties_changed(
1741         &mut self,
1742         status: BtStatus,
1743         num_properties: i32,
1744         properties: Vec<BluetoothProperty>,
1745     ) {
1746         if status != BtStatus::Success {
1747             return;
1748         }
1749 
1750         // Update local property cache
1751         for prop in properties {
1752             self.properties.insert(prop.get_type(), prop.clone());
1753 
1754             match &prop {
1755                 BluetoothProperty::BdAddr(bdaddr) => {
1756                     self.update_local_address(*bdaddr);
1757                 }
1758                 BluetoothProperty::AdapterBondedDevices(bondlist) => {
1759                     for addr in bondlist.iter() {
1760                         self.remote_devices
1761                             .entry(*addr)
1762                             .and_modify(|d| d.bond_state = BtBondState::Bonded)
1763                             .or_insert(BluetoothDeviceContext::new(
1764                                 BtBondState::Bonded,
1765                                 BtAclState::Disconnected,
1766                                 BtAclState::Disconnected,
1767                                 BluetoothDevice::new(*addr, "".to_string()),
1768                                 Instant::now(),
1769                                 vec![],
1770                             ));
1771                     }
1772 
1773                     // Update the connectable mode since bonded device list might be updated.
1774                     self.update_connectable_mode();
1775                 }
1776                 BluetoothProperty::BdName(bdname) => {
1777                     self.callbacks.for_all_callbacks(|callback| {
1778                         callback.on_name_changed(bdname.clone());
1779                     });
1780                 }
1781                 _ => {}
1782             }
1783 
1784             self.callbacks.for_all_callbacks(|callback| {
1785                 callback.on_adapter_property_changed(prop.get_type());
1786             });
1787         }
1788     }
1789 
1790     #[log_cb_args]
device_found(&mut self, _n: i32, properties: Vec<BluetoothProperty>)1791     fn device_found(&mut self, _n: i32, properties: Vec<BluetoothProperty>) {
1792         let device_info = BluetoothDevice::from_properties(&properties);
1793         self.check_new_property_and_potentially_connect_profiles(device_info.address, &properties);
1794 
1795         let device_info = self
1796             .remote_devices
1797             .entry(device_info.address)
1798             .and_modify(|d| {
1799                 d.update_properties(&properties);
1800                 d.seen();
1801             })
1802             .or_insert(BluetoothDeviceContext::new(
1803                 BtBondState::NotBonded,
1804                 BtAclState::Disconnected,
1805                 BtAclState::Disconnected,
1806                 device_info,
1807                 Instant::now(),
1808                 properties,
1809             ))
1810             .info
1811             .clone();
1812 
1813         self.callbacks.for_all_callbacks(|callback| {
1814             callback.on_device_found(device_info.clone());
1815         });
1816     }
1817 
1818     #[log_cb_args]
discovery_state(&mut self, state: BtDiscoveryState)1819     fn discovery_state(&mut self, state: BtDiscoveryState) {
1820         let is_discovering = &state == &BtDiscoveryState::Started;
1821 
1822         // No-op if we're updating the state to the same value again.
1823         if &is_discovering == &self.is_discovering {
1824             return;
1825         }
1826 
1827         // Cache discovering state
1828         self.is_discovering = &state == &BtDiscoveryState::Started;
1829         if self.is_discovering {
1830             self.discovering_started = Instant::now();
1831         }
1832 
1833         // Prevent sending out discovering changes or freshness checks when
1834         // suspending. Clients don't need to be notified of discovery pausing
1835         // during suspend. They will probably try to restore it and fail.
1836         let discovery_suspend_mode = self.get_discovery_suspend_mode();
1837         if discovery_suspend_mode != SuspendMode::Normal
1838             && discovery_suspend_mode != SuspendMode::Resuming
1839         {
1840             return;
1841         }
1842 
1843         self.callbacks.for_all_callbacks(|callback| {
1844             callback.on_discovering_changed(state == BtDiscoveryState::Started);
1845         });
1846 
1847         // Start or stop BLE scanning based on discovering state
1848         if let (Some(gatt), Some(scanner_id)) = (self.bluetooth_gatt.as_ref(), self.ble_scanner_id)
1849         {
1850             if is_discovering {
1851                 gatt.lock().unwrap().start_active_scan(scanner_id);
1852             } else {
1853                 gatt.lock().unwrap().stop_active_scan(scanner_id);
1854             }
1855         }
1856 
1857         if !self.is_discovering && self.pending_create_bond.is_some() {
1858             debug!("Invoking delayed CreateBond");
1859             let tx = self.tx.clone();
1860             tokio::spawn(async move {
1861                 let _ = tx.send(Message::AdapterActions(AdapterActions::CreateBond)).await;
1862             });
1863         }
1864     }
1865 
1866     #[log_cb_args]
ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32)1867     fn ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32) {
1868         // Accept the Just-Works pairing that we initiated, reject otherwise.
1869         if variant == BtSspVariant::Consent {
1870             let initiated_by_us = Some(remote_addr) == self.active_pairing_address;
1871             self.set_pairing_confirmation(
1872                 BluetoothDevice::new(remote_addr, "".to_string()),
1873                 initiated_by_us,
1874             );
1875             return;
1876         }
1877 
1878         // Currently this supports many agent because we accept many callbacks.
1879         // TODO(b/274706838): We need a way to select the default agent.
1880         self.callbacks.for_all_callbacks(|callback| {
1881             // TODO(b/336960912): libbluetooth changed their API so that we no longer
1882             // get the Device name and CoD, which were included in our DBus API.
1883             // Now we simply put random values since we aren't ready to change our DBus API
1884             // and it works because our Clients are not using these anyway.
1885             callback.on_ssp_request(
1886                 BluetoothDevice::new(remote_addr, "".to_string()),
1887                 0,
1888                 variant.clone(),
1889                 passkey,
1890             );
1891         });
1892     }
1893 
1894     #[log_cb_args]
pin_request( &mut self, remote_addr: RawAddress, remote_name: String, cod: u32, min_16_digit: bool, )1895     fn pin_request(
1896         &mut self,
1897         remote_addr: RawAddress,
1898         remote_name: String,
1899         cod: u32,
1900         min_16_digit: bool,
1901     ) {
1902         let device = BluetoothDevice::new(remote_addr, remote_name.clone());
1903 
1904         let digits = match min_16_digit {
1905             true => 16,
1906             false => 6,
1907         };
1908 
1909         if is_cod_hid_keyboard(cod) || is_cod_hid_combo(cod) {
1910             debug!("auto gen pin for device {} (cod={:#x})", DisplayAddress(&remote_addr), cod);
1911             // generate a random pin code to display.
1912             let pin = rand::random::<u64>() % pow(10, digits);
1913             let display_pin = format!("{:06}", pin);
1914 
1915             // Currently this supports many agent because we accept many callbacks.
1916             // TODO(b/274706838): We need a way to select the default agent.
1917             self.callbacks.for_all_callbacks(|callback| {
1918                 callback.on_pin_display(device.clone(), display_pin.clone());
1919             });
1920 
1921             let pin_vec = display_pin.chars().map(|d| d.try_into().unwrap()).collect::<Vec<u8>>();
1922 
1923             self.set_pin(device, true, pin_vec);
1924         } else {
1925             debug!(
1926                 "sending pin request for device {} (cod={:#x}) to clients",
1927                 DisplayAddress(&remote_addr),
1928                 cod
1929             );
1930             // Currently this supports many agent because we accept many callbacks.
1931             // TODO(b/274706838): We need a way to select the default agent.
1932             self.callbacks.for_all_callbacks(|callback| {
1933                 callback.on_pin_request(device.clone(), cod, min_16_digit);
1934             });
1935         }
1936     }
1937 
1938     #[log_cb_args]
bond_state( &mut self, status: BtStatus, addr: RawAddress, bond_state: BtBondState, fail_reason: i32, )1939     fn bond_state(
1940         &mut self,
1941         status: BtStatus,
1942         addr: RawAddress,
1943         bond_state: BtBondState,
1944         fail_reason: i32,
1945     ) {
1946         // Get the device type before the device is potentially deleted.
1947         let device_type = self.get_remote_type(BluetoothDevice::new(addr, "".to_string()));
1948 
1949         // Clear the pairing lock if this call corresponds to the
1950         // active pairing device.
1951         if bond_state != BtBondState::Bonding && self.active_pairing_address == Some(addr) {
1952             self.active_pairing_address = None;
1953         }
1954 
1955         if self.get_bond_state_by_addr(&addr) == bond_state {
1956             debug!("[{}]: Unchanged bond_state", DisplayAddress(&addr));
1957         } else {
1958             let entry =
1959                 self.remote_devices.entry(addr).and_modify(|d| d.bond_state = bond_state.clone());
1960             match bond_state {
1961                 BtBondState::NotBonded => {
1962                     if !self.get_wake_allowed_device_bonded() {
1963                         self.clear_uhid();
1964                     }
1965                     // Update the connectable mode since bonded list is changed.
1966                     self.update_connectable_mode();
1967                 }
1968                 BtBondState::Bonded => {
1969                     let device = entry.or_insert(BluetoothDeviceContext::new(
1970                         BtBondState::Bonded,
1971                         BtAclState::Disconnected,
1972                         BtAclState::Disconnected,
1973                         BluetoothDevice::new(addr, "".to_string()),
1974                         Instant::now(),
1975                         vec![],
1976                     ));
1977                     let device_info = device.info.clone();
1978                     // Since this is a newly bonded device, we also need to trigger SDP on it.
1979                     self.fetch_remote_uuids(device_info);
1980                     if self.get_wake_allowed_device_bonded() {
1981                         self.create_uhid_for_suspend_wakesource();
1982                     }
1983                     // Update the connectable mode since bonded list is changed.
1984                     self.update_connectable_mode();
1985                 }
1986                 BtBondState::Bonding => {}
1987             }
1988         }
1989 
1990         // Modification to |self.remote_devices| has done, ok to fire the change event.
1991         self.fire_device_connection_or_bonded_state_changed(addr);
1992 
1993         // Resume discovery once the bonding process is complete. Discovery was paused before the
1994         // bond request to avoid ACL connection from interfering with active inquiry.
1995         if bond_state == BtBondState::NotBonded || bond_state == BtBondState::Bonded {
1996             self.resume_discovery();
1997         }
1998 
1999         // Send bond state changed notifications
2000         self.callbacks.for_all_callbacks(|callback| {
2001             callback.on_bond_state_changed(
2002                 status.to_u32().unwrap(),
2003                 addr,
2004                 bond_state.to_u32().unwrap(),
2005             );
2006         });
2007 
2008         // Don't emit the metrics event if we were cancelling the bond.
2009         // It is ok to not send the pairing complete event as the server should ignore the dangling
2010         // pairing attempt event.
2011         // This behavior aligns with BlueZ.
2012         if !self.cancelling_devices.remove(&addr) {
2013             metrics::bond_state_changed(addr, device_type, status, bond_state, fail_reason);
2014         }
2015     }
2016 
2017     #[log_cb_args]
remote_device_properties_changed( &mut self, _status: BtStatus, addr: RawAddress, _num_properties: i32, properties: Vec<BluetoothProperty>, )2018     fn remote_device_properties_changed(
2019         &mut self,
2020         _status: BtStatus,
2021         addr: RawAddress,
2022         _num_properties: i32,
2023         properties: Vec<BluetoothProperty>,
2024     ) {
2025         self.check_new_property_and_potentially_connect_profiles(addr, &properties);
2026         let device = self.remote_devices.entry(addr).or_insert(BluetoothDeviceContext::new(
2027             BtBondState::NotBonded,
2028             BtAclState::Disconnected,
2029             BtAclState::Disconnected,
2030             BluetoothDevice::new(addr, String::from("")),
2031             Instant::now(),
2032             vec![],
2033         ));
2034 
2035         device.update_properties(&properties);
2036         device.seen();
2037 
2038         Bluetooth::send_metrics_remote_device_info(device);
2039 
2040         let info = device.info.clone();
2041 
2042         self.callbacks.for_all_callbacks(|callback| {
2043             callback.on_device_properties_changed(
2044                 info.clone(),
2045                 properties.clone().into_iter().map(|x| x.get_type()).collect(),
2046             );
2047         });
2048 
2049         // Only care about device type property changed on bonded device.
2050         // If the property change happens during bonding, it will be updated after bonding complete anyway.
2051         if self.get_bond_state_by_addr(&addr) == BtBondState::Bonded
2052             && properties.iter().any(|prop| match prop {
2053                 BluetoothProperty::TypeOfDevice(_) => true,
2054                 _ => false,
2055             })
2056         {
2057             // Update the connectable mode since the device type is changed.
2058             self.update_connectable_mode();
2059         }
2060     }
2061 
2062     #[log_cb_args]
acl_state( &mut self, status: BtStatus, addr: RawAddress, state: BtAclState, link_type: BtTransport, hci_reason: BtHciErrorCode, conn_direction: BtConnectionDirection, _acl_handle: u16, )2063     fn acl_state(
2064         &mut self,
2065         status: BtStatus,
2066         addr: RawAddress,
2067         state: BtAclState,
2068         link_type: BtTransport,
2069         hci_reason: BtHciErrorCode,
2070         conn_direction: BtConnectionDirection,
2071         _acl_handle: u16,
2072     ) {
2073         // If discovery was previously paused at connect_all_enabled_profiles to avoid an outgoing
2074         // ACL connection colliding with an ongoing inquiry, resume it.
2075         self.resume_discovery();
2076 
2077         if status != BtStatus::Success {
2078             warn!(
2079                 "Connection to [{}] failed. Status: {:?}, Reason: {:?}",
2080                 DisplayAddress(&addr),
2081                 status,
2082                 hci_reason
2083             );
2084             metrics::acl_connection_state_changed(
2085                 addr,
2086                 link_type,
2087                 status,
2088                 BtAclState::Disconnected,
2089                 conn_direction,
2090                 hci_reason,
2091             );
2092             self.connection_callbacks.for_all_callbacks(|callback| {
2093                 callback.on_device_connection_failed(
2094                     BluetoothDevice::new(addr, String::from("")),
2095                     status,
2096                 );
2097             });
2098             return;
2099         }
2100 
2101         let device = self.remote_devices.entry(addr).or_insert(BluetoothDeviceContext::new(
2102             BtBondState::NotBonded,
2103             BtAclState::Disconnected,
2104             BtAclState::Disconnected,
2105             BluetoothDevice::new(addr, String::from("")),
2106             Instant::now(),
2107             vec![],
2108         ));
2109 
2110         // Only notify if there's been a change in state
2111         if !device.set_transport_state(&link_type, &state) {
2112             return;
2113         }
2114 
2115         let info = device.info.clone();
2116         device.acl_reported_transport = link_type;
2117 
2118         metrics::acl_connection_state_changed(
2119             addr,
2120             link_type,
2121             BtStatus::Success,
2122             state.clone(),
2123             conn_direction,
2124             hci_reason,
2125         );
2126 
2127         match state {
2128             BtAclState::Connected => {
2129                 Bluetooth::send_metrics_remote_device_info(device);
2130                 self.connection_callbacks.for_all_callbacks(|callback| {
2131                     callback.on_device_connected(info.clone());
2132                 });
2133             }
2134             BtAclState::Disconnected => {
2135                 if !device.is_connected() {
2136                     self.connection_callbacks.for_all_callbacks(|callback| {
2137                         callback.on_device_disconnected(info.clone());
2138                     });
2139                     device.connect_to_new_profiles = false;
2140                 }
2141             }
2142         };
2143 
2144         // Modification to |self.remote_devices| has done, ok to fire the change event.
2145         self.fire_device_connection_or_bonded_state_changed(addr);
2146 
2147         // If we are bonding, skip the update here as we will update it after bonding complete anyway.
2148         // This is necessary for RTK controllers, which will break RNR after |Write Scan Enable|
2149         // command. Although this is a bug of RTK controllers, but as we could avoid unwanted page
2150         // scan, it makes sense to extend it to all BT controllers here.
2151         if Some(addr) != self.active_pairing_address {
2152             // Update the connectable since the connected state could be changed.
2153             self.update_connectable_mode();
2154         }
2155     }
2156 
2157     #[log_cb_args]
thread_event(&mut self, event: BtThreadEvent)2158     fn thread_event(&mut self, event: BtThreadEvent) {
2159         match event {
2160             BtThreadEvent::Associate => {
2161                 // Let the signal notifier know stack is initialized.
2162                 *self.sig_notifier.thread_attached.lock().unwrap() = true;
2163                 self.sig_notifier.thread_notify.notify_all();
2164             }
2165             BtThreadEvent::Disassociate => {
2166                 // Let the signal notifier know stack is done.
2167                 *self.sig_notifier.thread_attached.lock().unwrap() = false;
2168                 self.sig_notifier.thread_notify.notify_all();
2169             }
2170         }
2171     }
2172 
key_missing(&mut self, addr: RawAddress)2173     fn key_missing(&mut self, addr: RawAddress) {
2174         if let Some(d) = self.remote_devices.get(&addr) {
2175             self.callbacks.for_all_callbacks(|callback| {
2176                 callback.on_device_key_missing(d.info.clone());
2177             });
2178         }
2179     }
2180 }
2181 
2182 struct BleDiscoveryCallbacks {
2183     tx: Sender<Message>,
2184 }
2185 
2186 impl BleDiscoveryCallbacks {
new(tx: Sender<Message>) -> Self2187     fn new(tx: Sender<Message>) -> Self {
2188         Self { tx }
2189     }
2190 }
2191 
2192 // Handle BLE scanner results.
2193 impl IScannerCallback for BleDiscoveryCallbacks {
2194     #[log_cb_args]
on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus)2195     fn on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus) {
2196         let tx = self.tx.clone();
2197         tokio::spawn(async move {
2198             let _ = tx
2199                 .send(Message::AdapterActions(AdapterActions::BleDiscoveryScannerRegistered(
2200                     uuid, scanner_id, status,
2201                 )))
2202                 .await;
2203         });
2204     }
2205 
2206     #[log_cb_args]
on_scan_result(&mut self, scan_result: ScanResult)2207     fn on_scan_result(&mut self, scan_result: ScanResult) {
2208         let tx = self.tx.clone();
2209         tokio::spawn(async move {
2210             let _ = tx
2211                 .send(Message::AdapterActions(AdapterActions::BleDiscoveryScannerResult(
2212                     scan_result,
2213                 )))
2214                 .await;
2215         });
2216     }
2217 
on_advertisement_found(&mut self, _scanner_id: u8, _scan_result: ScanResult)2218     fn on_advertisement_found(&mut self, _scanner_id: u8, _scan_result: ScanResult) {}
on_advertisement_lost(&mut self, _scanner_id: u8, _scan_result: ScanResult)2219     fn on_advertisement_lost(&mut self, _scanner_id: u8, _scan_result: ScanResult) {}
2220     #[log_cb_args]
on_suspend_mode_change(&mut self, _suspend_mode: SuspendMode)2221     fn on_suspend_mode_change(&mut self, _suspend_mode: SuspendMode) {}
2222 }
2223 
2224 impl RPCProxy for BleDiscoveryCallbacks {
get_object_id(&self) -> String2225     fn get_object_id(&self) -> String {
2226         "BLE Discovery Callback".to_string()
2227     }
2228 }
2229 
2230 // TODO: Add unit tests for this implementation
2231 impl IBluetooth for Bluetooth {
register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) -> u322232     fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) -> u32 {
2233         self.callbacks.add_callback(callback)
2234     }
2235 
unregister_callback(&mut self, callback_id: u32) -> bool2236     fn unregister_callback(&mut self, callback_id: u32) -> bool {
2237         self.callbacks.remove_callback(callback_id)
2238     }
2239 
register_connection_callback( &mut self, callback: Box<dyn IBluetoothConnectionCallback + Send>, ) -> u322240     fn register_connection_callback(
2241         &mut self,
2242         callback: Box<dyn IBluetoothConnectionCallback + Send>,
2243     ) -> u32 {
2244         self.connection_callbacks.add_callback(callback)
2245     }
2246 
unregister_connection_callback(&mut self, callback_id: u32) -> bool2247     fn unregister_connection_callback(&mut self, callback_id: u32) -> bool {
2248         self.connection_callbacks.remove_callback(callback_id)
2249     }
2250 
init(&mut self, hci_index: i32) -> bool2251     fn init(&mut self, hci_index: i32) -> bool {
2252         self.intf.lock().unwrap().initialize(get_bt_dispatcher(self.tx.clone()), hci_index)
2253     }
2254 
enable(&mut self) -> bool2255     fn enable(&mut self) -> bool {
2256         self.disabling = false;
2257         self.intf.lock().unwrap().enable() == 0
2258     }
2259 
disable(&mut self) -> bool2260     fn disable(&mut self) -> bool {
2261         self.shutdown_adapter(false)
2262     }
2263 
cleanup(&mut self)2264     fn cleanup(&mut self) {
2265         self.intf.lock().unwrap().cleanup();
2266     }
2267 
get_address(&self) -> RawAddress2268     fn get_address(&self) -> RawAddress {
2269         self.local_address.unwrap_or_default()
2270     }
2271 
get_uuids(&self) -> Vec<Uuid>2272     fn get_uuids(&self) -> Vec<Uuid> {
2273         match self.properties.get(&BtPropertyType::Uuids) {
2274             Some(prop) => match prop {
2275                 BluetoothProperty::Uuids(uuids) => uuids.clone(),
2276                 _ => vec![],
2277             },
2278             _ => vec![],
2279         }
2280     }
2281 
get_name(&self) -> String2282     fn get_name(&self) -> String {
2283         match self.properties.get(&BtPropertyType::BdName) {
2284             Some(prop) => match prop {
2285                 BluetoothProperty::BdName(name) => name.clone(),
2286                 _ => String::new(),
2287             },
2288             _ => String::new(),
2289         }
2290     }
2291 
set_name(&self, name: String) -> bool2292     fn set_name(&self, name: String) -> bool {
2293         if self.get_name() == name {
2294             return true;
2295         }
2296         self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::BdName(name)) == 0
2297     }
2298 
get_bluetooth_class(&self) -> u322299     fn get_bluetooth_class(&self) -> u32 {
2300         match self.properties.get(&BtPropertyType::ClassOfDevice) {
2301             Some(prop) => match prop {
2302                 BluetoothProperty::ClassOfDevice(cod) => *cod,
2303                 _ => 0,
2304             },
2305             _ => 0,
2306         }
2307     }
2308 
set_bluetooth_class(&self, cod: u32) -> bool2309     fn set_bluetooth_class(&self, cod: u32) -> bool {
2310         self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::ClassOfDevice(cod)) == 0
2311     }
2312 
get_discoverable(&self) -> bool2313     fn get_discoverable(&self) -> bool {
2314         self.get_discoverable_mode_internal() != BtDiscMode::NonDiscoverable
2315     }
2316 
get_discoverable_timeout(&self) -> u322317     fn get_discoverable_timeout(&self) -> u32 {
2318         self.discoverable_duration
2319     }
2320 
set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool2321     fn set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool {
2322         let intf = self.intf.lock().unwrap();
2323 
2324         // Checks if the duration is valid.
2325         if mode == BtDiscMode::LimitedDiscoverable && (duration > 60 || duration == 0) {
2326             warn!("Invalid duration for setting the device into limited discoverable mode. The valid duration is 1~60 seconds.");
2327             return false;
2328         }
2329 
2330         // Don't really set the mode when suspend. The mode would be instead restored on resume.
2331         // However, we still need to set the discoverable timeout so it would properly reset
2332         // |self.discoverable_mode| after resume.
2333         if self.get_scan_suspend_mode() == SuspendMode::Normal {
2334             let scan_mode = match mode {
2335                 BtDiscMode::LimitedDiscoverable => BtScanMode::ConnectableLimitedDiscoverable,
2336                 BtDiscMode::GeneralDiscoverable => BtScanMode::ConnectableDiscoverable,
2337                 BtDiscMode::NonDiscoverable => match self.is_connectable {
2338                     true => BtScanMode::Connectable,
2339                     false => BtScanMode::None_,
2340                 },
2341             };
2342             intf.set_scan_mode(scan_mode);
2343         }
2344 
2345         self.callbacks.for_all_callbacks(|callback| {
2346             callback.on_discoverable_changed(mode == BtDiscMode::GeneralDiscoverable);
2347         });
2348         self.discoverable_mode = mode.clone();
2349         self.discoverable_duration = duration;
2350 
2351         // The old timer should be overwritten regardless of what the new mode is.
2352         if let Some(handle) = self.discoverable_timeout.take() {
2353             handle.abort();
2354         }
2355 
2356         if mode != BtDiscMode::NonDiscoverable && duration != 0 {
2357             let txl = self.tx.clone();
2358             self.discoverable_timeout = Some(tokio::spawn(async move {
2359                 time::sleep(Duration::from_secs(duration.into())).await;
2360                 let _ = txl.send(Message::AdapterActions(AdapterActions::ResetDiscoverable)).await;
2361             }));
2362         }
2363 
2364         true
2365     }
2366 
is_multi_advertisement_supported(&self) -> bool2367     fn is_multi_advertisement_supported(&self) -> bool {
2368         match self.properties.get(&BtPropertyType::LocalLeFeatures) {
2369             Some(prop) => match prop {
2370                 BluetoothProperty::LocalLeFeatures(llf) => {
2371                     llf.max_adv_instance >= MIN_ADV_INSTANCES_FOR_MULTI_ADV
2372                 }
2373                 _ => false,
2374             },
2375             _ => false,
2376         }
2377     }
2378 
is_le_extended_advertising_supported(&self) -> bool2379     fn is_le_extended_advertising_supported(&self) -> bool {
2380         match self.properties.get(&BtPropertyType::LocalLeFeatures) {
2381             Some(prop) => match prop {
2382                 BluetoothProperty::LocalLeFeatures(llf) => llf.le_extended_advertising_supported,
2383                 _ => false,
2384             },
2385             _ => false,
2386         }
2387     }
2388 
start_discovery(&mut self) -> bool2389     fn start_discovery(&mut self) -> bool {
2390         // Short-circuit to avoid sending multiple start discovery calls.
2391         if self.is_discovering {
2392             return true;
2393         }
2394 
2395         // Short-circuit if paused and add the discovery intent to the queue.
2396         if self.is_discovery_paused {
2397             self.pending_discovery = true;
2398             debug!("Queue the discovery request during paused state");
2399             return true;
2400         }
2401 
2402         let discovery_suspend_mode = self.get_discovery_suspend_mode();
2403         if discovery_suspend_mode != SuspendMode::Normal
2404             && discovery_suspend_mode != SuspendMode::Resuming
2405         {
2406             log::warn!("start_discovery is not allowed when suspending or suspended.");
2407             return false;
2408         }
2409 
2410         self.intf.lock().unwrap().start_discovery() == 0
2411     }
2412 
cancel_discovery(&mut self) -> bool2413     fn cancel_discovery(&mut self) -> bool {
2414         // Client no longer want to discover, clear the request
2415         if self.is_discovery_paused {
2416             self.pending_discovery = false;
2417             debug!("Cancel the discovery request during paused state");
2418         }
2419 
2420         // Reject the cancel discovery request if the underlying stack is not in a discovering
2421         // state. For example, previous start discovery was enqueued for ongoing discovery.
2422         if !self.is_discovering {
2423             debug!("Reject cancel_discovery as it's not in discovering state.");
2424             return false;
2425         }
2426 
2427         let discovery_suspend_mode = self.get_discovery_suspend_mode();
2428         if discovery_suspend_mode != SuspendMode::Normal
2429             && discovery_suspend_mode != SuspendMode::Suspending
2430         {
2431             log::warn!("cancel_discovery is not allowed when resuming or suspended.");
2432             return false;
2433         }
2434 
2435         self.intf.lock().unwrap().cancel_discovery() == 0
2436     }
2437 
is_discovering(&self) -> bool2438     fn is_discovering(&self) -> bool {
2439         self.is_discovering
2440     }
2441 
get_discovery_end_millis(&self) -> u642442     fn get_discovery_end_millis(&self) -> u64 {
2443         if !self.is_discovering {
2444             return 0;
2445         }
2446 
2447         let elapsed_ms = self.discovering_started.elapsed().as_millis() as u64;
2448         if elapsed_ms >= DEFAULT_DISCOVERY_TIMEOUT_MS {
2449             0
2450         } else {
2451             DEFAULT_DISCOVERY_TIMEOUT_MS - elapsed_ms
2452         }
2453     }
2454 
create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> BtStatus2455     fn create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> BtStatus {
2456         let device_type = match transport {
2457             BtTransport::Bredr => BtDeviceType::Bredr,
2458             BtTransport::Le => BtDeviceType::Ble,
2459             _ => self.get_remote_type(device.clone()),
2460         };
2461         let address = device.address;
2462 
2463         if let Some(active_address) = self.active_pairing_address {
2464             warn!(
2465                 "Bonding requested for {} while already bonding {}, rejecting",
2466                 DisplayAddress(&address),
2467                 DisplayAddress(&active_address)
2468             );
2469             return BtStatus::Busy;
2470         }
2471 
2472         if self.pending_create_bond.is_some() {
2473             warn!("Delayed CreateBond is still pending");
2474             return BtStatus::Busy;
2475         }
2476 
2477         // There could be a race between bond complete and bond cancel, which makes
2478         // |cancelling_devices| in a wrong state. Remove the device just in case.
2479         if self.cancelling_devices.remove(&address) {
2480             warn!("Device {} is also cancelling the bond.", DisplayAddress(&address));
2481         }
2482 
2483         // BREDR connection won't work when Inquiry / Remote Name Request is in progress.
2484         // If is_discovering, delay the request until discovery state change.
2485         if self.is_discovering {
2486             debug!("Discovering. Delay the CreateBond request until discovery is done.");
2487             self.pause_discovery();
2488             self.pending_create_bond = Some((device, transport));
2489             return BtStatus::Success;
2490         }
2491 
2492         // We explicitly log the attempt to start the bonding separate from logging the bond state.
2493         // The start of the attempt is critical to help identify a bonding/pairing session.
2494         metrics::bond_create_attempt(address, device_type.clone());
2495 
2496         self.active_pairing_address = Some(address);
2497         let status = self.intf.lock().unwrap().create_bond(&address, transport);
2498 
2499         if status != 0 {
2500             metrics::bond_state_changed(
2501                 address,
2502                 device_type,
2503                 BtStatus::from(status as u32),
2504                 BtBondState::NotBonded,
2505                 0,
2506             );
2507             return BtStatus::from(status as u32);
2508         }
2509 
2510         // Creating bond automatically create ACL connection as well, therefore also log metrics
2511         // ACL connection attempt here.
2512         if !self.get_acl_state_by_addr(&address) {
2513             metrics::acl_connect_attempt(address, BtAclState::Connected);
2514         }
2515 
2516         BtStatus::Success
2517     }
2518 
cancel_bond_process(&mut self, device: BluetoothDevice) -> bool2519     fn cancel_bond_process(&mut self, device: BluetoothDevice) -> bool {
2520         if !self.cancelling_devices.insert(device.address) {
2521             warn!(
2522                 "Device {} has been added to cancelling_device.",
2523                 DisplayAddress(&device.address)
2524             );
2525         }
2526 
2527         self.intf.lock().unwrap().cancel_bond(&device.address) == 0
2528     }
2529 
remove_bond(&mut self, device: BluetoothDevice) -> bool2530     fn remove_bond(&mut self, device: BluetoothDevice) -> bool {
2531         let address = device.address;
2532 
2533         // There could be a race between bond complete and bond cancel, which makes
2534         // |cancelling_devices| in a wrong state. Remove the device just in case.
2535         if self.cancelling_devices.remove(&address) {
2536             warn!("Device {} is also cancelling the bond.", DisplayAddress(&address));
2537         }
2538 
2539         let status = self.intf.lock().unwrap().remove_bond(&address);
2540 
2541         if status != 0 {
2542             return false;
2543         }
2544 
2545         // Removing bond also disconnects the ACL if is connected. Therefore, also log ACL
2546         // disconnection attempt here.
2547         if self.get_acl_state_by_addr(&address) {
2548             metrics::acl_connect_attempt(address, BtAclState::Disconnected);
2549         }
2550 
2551         true
2552     }
2553 
get_bonded_devices(&self) -> Vec<BluetoothDevice>2554     fn get_bonded_devices(&self) -> Vec<BluetoothDevice> {
2555         self.remote_devices
2556             .values()
2557             .filter_map(|d| {
2558                 if d.bond_state == BtBondState::Bonded {
2559                     Some(d.info.clone())
2560                 } else {
2561                     None
2562                 }
2563             })
2564             .collect()
2565     }
2566 
get_bond_state(&self, device: BluetoothDevice) -> BtBondState2567     fn get_bond_state(&self, device: BluetoothDevice) -> BtBondState {
2568         self.get_bond_state_by_addr(&device.address)
2569     }
2570 
set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool2571     fn set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool {
2572         if self.get_bond_state_by_addr(&device.address) != BtBondState::Bonding {
2573             warn!("Can't set pin. Device {} isn't bonding.", DisplayAddress(&device.address));
2574             return false;
2575         }
2576 
2577         let mut btpin = BtPinCode { pin: array_utils::to_sized_array(&pin_code) };
2578 
2579         self.intf.lock().unwrap().pin_reply(
2580             &device.address,
2581             accept as u8,
2582             pin_code.len() as u8,
2583             &mut btpin,
2584         ) == 0
2585     }
2586 
set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool2587     fn set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool {
2588         if self.get_bond_state_by_addr(&device.address) != BtBondState::Bonding {
2589             warn!("Can't set passkey. Device {} isn't bonding.", DisplayAddress(&device.address));
2590             return false;
2591         }
2592 
2593         let mut tmp: [u8; 4] = [0; 4];
2594         tmp.copy_from_slice(passkey.as_slice());
2595         let passkey = u32::from_ne_bytes(tmp);
2596 
2597         self.intf.lock().unwrap().ssp_reply(
2598             &device.address,
2599             BtSspVariant::PasskeyEntry,
2600             accept as u8,
2601             passkey,
2602         ) == 0
2603     }
2604 
set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool2605     fn set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool {
2606         self.intf.lock().unwrap().ssp_reply(
2607             &device.address,
2608             BtSspVariant::PasskeyConfirmation,
2609             accept as u8,
2610             0,
2611         ) == 0
2612     }
2613 
get_remote_name(&self, device: BluetoothDevice) -> String2614     fn get_remote_name(&self, device: BluetoothDevice) -> String {
2615         match self.get_remote_device_property(&device, &BtPropertyType::BdName) {
2616             Some(BluetoothProperty::BdName(name)) => name.clone(),
2617             _ => "".to_string(),
2618         }
2619     }
2620 
get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType2621     fn get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType {
2622         match self.get_remote_device_property(&device, &BtPropertyType::TypeOfDevice) {
2623             Some(BluetoothProperty::TypeOfDevice(device_type)) => device_type,
2624             _ => BtDeviceType::Unknown,
2625         }
2626     }
2627 
get_remote_alias(&self, device: BluetoothDevice) -> String2628     fn get_remote_alias(&self, device: BluetoothDevice) -> String {
2629         match self.get_remote_device_property(&device, &BtPropertyType::RemoteFriendlyName) {
2630             Some(BluetoothProperty::RemoteFriendlyName(name)) => name.clone(),
2631             _ => "".to_string(),
2632         }
2633     }
2634 
set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String)2635     fn set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String) {
2636         let _ = self.set_remote_device_property(
2637             &device,
2638             BtPropertyType::RemoteFriendlyName,
2639             BluetoothProperty::RemoteFriendlyName(new_alias),
2640         );
2641     }
2642 
get_remote_class(&self, device: BluetoothDevice) -> u322643     fn get_remote_class(&self, device: BluetoothDevice) -> u32 {
2644         match self.get_remote_device_property(&device, &BtPropertyType::ClassOfDevice) {
2645             Some(BluetoothProperty::ClassOfDevice(class)) => class,
2646             _ => 0,
2647         }
2648     }
2649 
get_remote_appearance(&self, device: BluetoothDevice) -> u162650     fn get_remote_appearance(&self, device: BluetoothDevice) -> u16 {
2651         match self.get_remote_device_property(&device, &BtPropertyType::Appearance) {
2652             Some(BluetoothProperty::Appearance(appearance)) => appearance,
2653             _ => 0,
2654         }
2655     }
2656 
get_remote_connected(&self, device: BluetoothDevice) -> bool2657     fn get_remote_connected(&self, device: BluetoothDevice) -> bool {
2658         self.get_connection_state(device) != BtConnectionState::NotConnected
2659     }
2660 
get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool2661     fn get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool {
2662         // Wake is allowed if the device supports HIDP or HOGP only.
2663         match self.get_remote_device_property(&device, &BtPropertyType::Uuids) {
2664             Some(BluetoothProperty::Uuids(uuids)) => {
2665                 return uuids.iter().any(|&uuid| {
2666                     UuidHelper::is_known_profile(&uuid).map_or(false, |profile| {
2667                         profile == Profile::Hid || profile == Profile::Hogp
2668                     })
2669                 });
2670             }
2671             _ => false,
2672         }
2673     }
2674 
get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo2675     fn get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo {
2676         match self.get_remote_device_property(&device, &BtPropertyType::VendorProductInfo) {
2677             Some(BluetoothProperty::VendorProductInfo(p)) => p,
2678             _ => BtVendorProductInfo { vendor_id_src: 0, vendor_id: 0, product_id: 0, version: 0 },
2679         }
2680     }
2681 
get_remote_address_type(&self, device: BluetoothDevice) -> BtAddrType2682     fn get_remote_address_type(&self, device: BluetoothDevice) -> BtAddrType {
2683         match self.get_remote_device_property(&device, &BtPropertyType::RemoteAddrType) {
2684             Some(BluetoothProperty::RemoteAddrType(addr_type)) => addr_type,
2685             _ => BtAddrType::Unknown,
2686         }
2687     }
2688 
get_remote_rssi(&self, device: BluetoothDevice) -> i82689     fn get_remote_rssi(&self, device: BluetoothDevice) -> i8 {
2690         match self.get_remote_device_property(&device, &BtPropertyType::RemoteRssi) {
2691             Some(BluetoothProperty::RemoteRssi(rssi)) => rssi,
2692             _ => INVALID_RSSI,
2693         }
2694     }
2695 
get_connected_devices(&self) -> Vec<BluetoothDevice>2696     fn get_connected_devices(&self) -> Vec<BluetoothDevice> {
2697         self.remote_devices
2698             .values()
2699             .filter_map(|d| if d.is_connected() { Some(d.info.clone()) } else { None })
2700             .collect()
2701     }
2702 
get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState2703     fn get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState {
2704         // The underlying api adds whether this is ENCRYPTED_BREDR or ENCRYPTED_LE.
2705         // As long as it is non-zero, it is connected.
2706         self.intf.lock().unwrap().get_connection_state(&device.address)
2707     }
2708 
get_profile_connection_state(&self, profile: Uuid) -> ProfileConnectionState2709     fn get_profile_connection_state(&self, profile: Uuid) -> ProfileConnectionState {
2710         if let Some(known) = UuidHelper::is_known_profile(&profile) {
2711             match known {
2712                 Profile::A2dpSink | Profile::A2dpSource => self
2713                     .bluetooth_media
2714                     .as_ref()
2715                     .map_or(ProfileConnectionState::Disconnected, |media| {
2716                         media.lock().unwrap().get_a2dp_connection_state()
2717                     }),
2718                 Profile::Hfp | Profile::HfpAg => self
2719                     .bluetooth_media
2720                     .as_ref()
2721                     .map_or(ProfileConnectionState::Disconnected, |media| {
2722                         media.lock().unwrap().get_hfp_connection_state()
2723                     }),
2724                 // TODO: (b/223431229) Profile::Hid and Profile::Hogp
2725                 _ => ProfileConnectionState::Disconnected,
2726             }
2727         } else {
2728             ProfileConnectionState::Disconnected
2729         }
2730     }
2731 
get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid>2732     fn get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid> {
2733         match self.get_remote_device_property(&device, &BtPropertyType::Uuids) {
2734             Some(BluetoothProperty::Uuids(uuids)) => uuids,
2735             _ => vec![],
2736         }
2737     }
2738 
fetch_remote_uuids(&self, remote_device: BluetoothDevice) -> bool2739     fn fetch_remote_uuids(&self, remote_device: BluetoothDevice) -> bool {
2740         let Some(device) = self.remote_devices.get(&remote_device.address) else {
2741             warn!("Won't fetch UUIDs on unknown device");
2742             return false;
2743         };
2744 
2745         let transport = match self.get_remote_type(device.info.clone()) {
2746             BtDeviceType::Bredr => BtTransport::Bredr,
2747             BtDeviceType::Ble => BtTransport::Le,
2748             _ => device.acl_reported_transport,
2749         };
2750 
2751         self.intf.lock().unwrap().get_remote_services(&mut device.info.address.clone(), transport)
2752             == 0
2753     }
2754 
sdp_search(&self, mut device: BluetoothDevice, uuid: Uuid) -> bool2755     fn sdp_search(&self, mut device: BluetoothDevice, uuid: Uuid) -> bool {
2756         if let Some(sdp) = self.sdp.as_ref() {
2757             return sdp.sdp_search(&mut device.address, &uuid) == BtStatus::Success;
2758         }
2759         false
2760     }
2761 
create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool2762     fn create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool {
2763         let mut handle: i32 = -1;
2764         let mut sdp_record = sdp_record;
2765         match self.sdp.as_ref().unwrap().create_sdp_record(&mut sdp_record, &mut handle) {
2766             BtStatus::Success => {
2767                 let record_clone = sdp_record.clone();
2768                 self.callbacks.for_all_callbacks(|callback| {
2769                     callback.on_sdp_record_created(record_clone.clone(), handle);
2770                 });
2771                 true
2772             }
2773             _ => false,
2774         }
2775     }
2776 
remove_sdp_record(&self, handle: i32) -> bool2777     fn remove_sdp_record(&self, handle: i32) -> bool {
2778         self.sdp.as_ref().unwrap().remove_sdp_record(handle) == BtStatus::Success
2779     }
2780 
connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> BtStatus2781     fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> BtStatus {
2782         // Profile init must be complete before this api is callable
2783         if !self.profiles_ready {
2784             return BtStatus::NotReady;
2785         }
2786 
2787         // Check all remote uuids to see if they match enabled profiles and connect them.
2788         let uuids = self.get_remote_uuids(device.clone());
2789         self.connect_profiles_internal(&uuids, device.clone());
2790 
2791         // Also connect to profiles discovered in the future.
2792         if let Some(d) = self.remote_devices.get_mut(&device.address) {
2793             d.connect_to_new_profiles = true;
2794         }
2795 
2796         BtStatus::Success
2797     }
2798 
disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool2799     fn disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool {
2800         if !self.profiles_ready {
2801             return false;
2802         }
2803         let addr = device.address;
2804 
2805         // log ACL disconnection attempt if it's not already disconnected.
2806         if self.get_acl_state_by_addr(&addr) {
2807             metrics::acl_connect_attempt(addr, BtAclState::Disconnected);
2808         }
2809 
2810         let uuids = self.get_remote_uuids(device.clone());
2811         let mut has_classic_media_profile = false;
2812         let mut has_le_media_profile = false;
2813         for uuid in uuids.iter() {
2814             match UuidHelper::is_known_profile(uuid) {
2815                 Some(p) => {
2816                     if UuidHelper::is_profile_supported(&p) {
2817                         match p {
2818                             Profile::Hid | Profile::Hogp => {
2819                                 // TODO(b/328675014): Use BtAddrType
2820                                 // and BtTransport from
2821                                 // BluetoothDevice instead of default
2822 
2823                                 // TODO(b/329837967): Determine
2824                                 // correct reconnection behavior based
2825                                 // on device instead of the default
2826                                 self.hh.as_ref().unwrap().disconnect(
2827                                     &mut addr.clone(),
2828                                     BtAddrType::Public,
2829                                     BtTransport::Auto,
2830                                     /*reconnect_allowed=*/ true,
2831                                 );
2832                             }
2833 
2834                             // TODO(b/317682584): implement policy to disconnect from LEA, VC, and CSIS
2835                             Profile::LeAudio | Profile::VolumeControl | Profile::CoordinatedSet
2836                                 if !has_le_media_profile =>
2837                             {
2838                                 has_le_media_profile = true;
2839                                 let txl = self.tx.clone();
2840                                 topstack::get_runtime().spawn(async move {
2841                                     let _ = txl
2842                                         .send(Message::Media(
2843                                             MediaActions::DisconnectLeaGroupByMemberAddress(addr),
2844                                         ))
2845                                         .await;
2846                                 });
2847                             }
2848 
2849                             Profile::A2dpSink
2850                             | Profile::A2dpSource
2851                             | Profile::Hfp
2852                             | Profile::AvrcpController
2853                                 if !has_classic_media_profile =>
2854                             {
2855                                 has_classic_media_profile = true;
2856                                 let txl = self.tx.clone();
2857                                 topstack::get_runtime().spawn(async move {
2858                                     let _ = txl
2859                                         .send(Message::Media(MediaActions::Disconnect(addr)))
2860                                         .await;
2861                                 });
2862                             }
2863 
2864                             // We don't connect most profiles
2865                             _ => (),
2866                         }
2867                     }
2868                 }
2869                 _ => {}
2870             }
2871         }
2872 
2873         // Disconnect all socket connections
2874         let txl = self.tx.clone();
2875         topstack::get_runtime().spawn(async move {
2876             let _ =
2877                 txl.send(Message::SocketManagerActions(SocketActions::DisconnectAll(addr))).await;
2878         });
2879 
2880         // Disconnect all GATT connections
2881         let txl = self.tx.clone();
2882         topstack::get_runtime().spawn(async move {
2883             let _ = txl.send(Message::GattActions(GattActions::Disconnect(device))).await;
2884         });
2885 
2886         if let Some(d) = self.remote_devices.get_mut(&addr) {
2887             d.connect_to_new_profiles = false;
2888         }
2889 
2890         true
2891     }
2892 
is_wbs_supported(&self) -> bool2893     fn is_wbs_supported(&self) -> bool {
2894         self.intf.lock().unwrap().get_wbs_supported()
2895     }
2896 
is_swb_supported(&self) -> bool2897     fn is_swb_supported(&self) -> bool {
2898         self.intf.lock().unwrap().get_swb_supported()
2899     }
2900 
get_supported_roles(&self) -> Vec<BtAdapterRole>2901     fn get_supported_roles(&self) -> Vec<BtAdapterRole> {
2902         let mut roles: Vec<BtAdapterRole> = vec![];
2903 
2904         // See Core 5.3, Vol 4, Part E, 7.8.27 for detailed state information
2905         if self.le_supported_states >> 35 & 1 == 1u64 {
2906             roles.push(BtAdapterRole::Central);
2907         }
2908         if self.le_supported_states >> 38 & 1 == 1u64 {
2909             roles.push(BtAdapterRole::Peripheral);
2910         }
2911         if self.le_supported_states >> 28 & 1 == 1u64 {
2912             roles.push(BtAdapterRole::CentralPeripheral);
2913         }
2914 
2915         roles
2916     }
2917 
is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool2918     fn is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool {
2919         self.intf.lock().unwrap().is_coding_format_supported(coding_format as u8)
2920     }
2921 
is_le_audio_supported(&self) -> bool2922     fn is_le_audio_supported(&self) -> bool {
2923         // We determine LE Audio support by checking CIS Central support
2924         // See Core 5.3, Vol 6, 4.6 FEATURE SUPPORT
2925         self.le_local_supported_features >> 28 & 1 == 1u64
2926     }
2927 
is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool2928     fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool {
2929         fn is_dual_mode(uuids: Vec<Uuid>) -> bool {
2930             fn get_unwrapped_uuid(profile: Profile) -> Uuid {
2931                 *UuidHelper::get_profile_uuid(&profile).unwrap_or(&Uuid::empty())
2932             }
2933 
2934             uuids.contains(&get_unwrapped_uuid(Profile::LeAudio))
2935                 && (uuids.contains(&get_unwrapped_uuid(Profile::A2dpSink))
2936                     || uuids.contains(&get_unwrapped_uuid(Profile::Hfp)))
2937         }
2938 
2939         let Some(media) = self.bluetooth_media.as_ref() else {
2940             return false;
2941         };
2942         let media = media.lock().unwrap();
2943         let group_id = media.get_group_id(device.address);
2944         if group_id == LEA_UNKNOWN_GROUP_ID {
2945             return is_dual_mode(self.get_remote_uuids(device));
2946         }
2947 
2948         // Check if any device in the CSIP group is a dual mode audio sink device
2949         media.get_group_devices(group_id).iter().any(|addr| {
2950             is_dual_mode(self.get_remote_uuids(BluetoothDevice::new(*addr, "".to_string())))
2951         })
2952     }
2953 
get_dumpsys(&self) -> String2954     fn get_dumpsys(&self) -> String {
2955         OpenOptions::new()
2956             .write(true)
2957             .create(true)
2958             .truncate(true)
2959             .open(DUMPSYS_LOG)
2960             .and_then(|file| {
2961                 let fd = file.as_raw_fd();
2962                 self.intf.lock().unwrap().dump(fd);
2963                 Ok(format!("dump to {}", DUMPSYS_LOG))
2964             })
2965             .unwrap_or_default()
2966     }
2967 }
2968 
2969 impl BtifSdpCallbacks for Bluetooth {
2970     #[log_cb_args]
sdp_search( &mut self, status: BtStatus, address: RawAddress, uuid: Uuid, _count: i32, records: Vec<BtSdpRecord>, )2971     fn sdp_search(
2972         &mut self,
2973         status: BtStatus,
2974         address: RawAddress,
2975         uuid: Uuid,
2976         _count: i32,
2977         records: Vec<BtSdpRecord>,
2978     ) {
2979         let device_info = match self.remote_devices.get(&address) {
2980             Some(d) => d.info.clone(),
2981             None => BluetoothDevice::new(address, "".to_string()),
2982         };
2983 
2984         // The SDP records we get back do not populate the UUID so we populate it ourselves before
2985         // sending them on.
2986         let mut records = records;
2987         records.iter_mut().for_each(|record| {
2988             match record {
2989                 BtSdpRecord::HeaderOverlay(header) => header.uuid = uuid,
2990                 BtSdpRecord::MapMas(record) => record.hdr.uuid = uuid,
2991                 BtSdpRecord::MapMns(record) => record.hdr.uuid = uuid,
2992                 BtSdpRecord::PbapPse(record) => record.hdr.uuid = uuid,
2993                 BtSdpRecord::PbapPce(record) => record.hdr.uuid = uuid,
2994                 BtSdpRecord::OppServer(record) => record.hdr.uuid = uuid,
2995                 BtSdpRecord::SapServer(record) => record.hdr.uuid = uuid,
2996                 BtSdpRecord::Dip(record) => record.hdr.uuid = uuid,
2997                 BtSdpRecord::Mps(record) => record.hdr.uuid = uuid,
2998             };
2999         });
3000         self.callbacks.for_all_callbacks(|callback| {
3001             callback.on_sdp_search_complete(device_info.clone(), uuid, records.clone());
3002         });
3003         debug!(
3004             "Sdp search result found: Status={:?} Address={} Uuid={}",
3005             status,
3006             DisplayAddress(&address),
3007             DisplayUuid(&uuid)
3008         );
3009     }
3010 }
3011 
3012 impl BtifHHCallbacks for Bluetooth {
3013     #[log_cb_args]
connection_state( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, state: BthhConnectionState, )3014     fn connection_state(
3015         &mut self,
3016         address: RawAddress,
3017         address_type: BtAddrType,
3018         transport: BtTransport,
3019         state: BthhConnectionState,
3020     ) {
3021         // HID or HOG is not differentiated by the hid host when callback this function. Assume HOG
3022         // if the device is LE only and HID if classic only. And assume HOG if UUID said so when
3023         // device type is dual or unknown.
3024         let device = BluetoothDevice::new(address, "".to_string());
3025         let profile = match self.get_remote_type(device.clone()) {
3026             BtDeviceType::Ble => Profile::Hogp,
3027             BtDeviceType::Bredr => Profile::Hid,
3028             _ => {
3029                 if self
3030                     .get_remote_uuids(device)
3031                     .contains(UuidHelper::get_profile_uuid(&Profile::Hogp).unwrap())
3032                 {
3033                     Profile::Hogp
3034                 } else {
3035                     Profile::Hid
3036                 }
3037             }
3038         };
3039 
3040         metrics::profile_connection_state_changed(
3041             address,
3042             profile as u32,
3043             BtStatus::Success,
3044             state as u32,
3045         );
3046 
3047         let tx = self.tx.clone();
3048         self.remote_devices.entry(address).and_modify(|context| {
3049             if context.is_initiated_hh_connection
3050                 && (state != BthhConnectionState::Connected
3051                     && state != BthhConnectionState::Connecting)
3052             {
3053                 tokio::spawn(async move {
3054                     let _ = tx.send(Message::ProfileDisconnected(address)).await;
3055                 });
3056             }
3057             context.is_initiated_hh_connection =
3058                 state == BthhConnectionState::Connected || state == BthhConnectionState::Connecting;
3059         });
3060 
3061         if BtBondState::Bonded != self.get_bond_state_by_addr(&address)
3062             && (state != BthhConnectionState::Disconnecting
3063                 && state != BthhConnectionState::Disconnected)
3064         {
3065             warn!(
3066                 "[{}]: Rejecting a unbonded device's attempt to connect to HID/HOG profiles",
3067                 DisplayAddress(&address)
3068             );
3069             // TODO(b/329837967): Determine correct reconnection
3070             // behavior based on device instead of the default
3071             let mut address = address;
3072             self.hh.as_ref().unwrap().disconnect(
3073                 &mut address,
3074                 address_type,
3075                 transport,
3076                 /*reconnect_allowed=*/ true,
3077             );
3078         }
3079     }
3080 
3081     #[log_cb_args]
hid_info( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, info: BthhHidInfo, )3082     fn hid_info(
3083         &mut self,
3084         address: RawAddress,
3085         address_type: BtAddrType,
3086         transport: BtTransport,
3087         info: BthhHidInfo,
3088     ) {
3089     }
3090 
3091     #[log_cb_args]
protocol_mode( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, mode: BthhProtocolMode, )3092     fn protocol_mode(
3093         &mut self,
3094         address: RawAddress,
3095         address_type: BtAddrType,
3096         transport: BtTransport,
3097         status: BthhStatus,
3098         mode: BthhProtocolMode,
3099     ) {
3100     }
3101 
3102     #[log_cb_args]
idle_time( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, idle_rate: i32, )3103     fn idle_time(
3104         &mut self,
3105         address: RawAddress,
3106         address_type: BtAddrType,
3107         transport: BtTransport,
3108         status: BthhStatus,
3109         idle_rate: i32,
3110     ) {
3111     }
3112 
3113     #[log_cb_args]
get_report( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, _data: Vec<u8>, size: i32, )3114     fn get_report(
3115         &mut self,
3116         address: RawAddress,
3117         address_type: BtAddrType,
3118         transport: BtTransport,
3119         status: BthhStatus,
3120         _data: Vec<u8>,
3121         size: i32,
3122     ) {
3123     }
3124 
3125     #[log_cb_args]
handshake( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, )3126     fn handshake(
3127         &mut self,
3128         address: RawAddress,
3129         address_type: BtAddrType,
3130         transport: BtTransport,
3131         status: BthhStatus,
3132     ) {
3133     }
3134 }
3135 
3136 // TODO(b/261143122): Remove these once we migrate to BluetoothQA entirely
3137 impl IBluetoothQALegacy for Bluetooth {
get_connectable(&self) -> bool3138     fn get_connectable(&self) -> bool {
3139         self.get_connectable_internal()
3140     }
3141 
set_connectable(&mut self, mode: bool) -> bool3142     fn set_connectable(&mut self, mode: bool) -> bool {
3143         self.set_connectable_internal(mode)
3144     }
3145 
get_alias(&self) -> String3146     fn get_alias(&self) -> String {
3147         self.get_alias_internal()
3148     }
3149 
get_modalias(&self) -> String3150     fn get_modalias(&self) -> String {
3151         format!("bluetooth:v00E0pC405d{:04x}", FLOSS_VER)
3152     }
3153 
get_hid_report( &mut self, addr: RawAddress, report_type: BthhReportType, report_id: u8, ) -> BtStatus3154     fn get_hid_report(
3155         &mut self,
3156         addr: RawAddress,
3157         report_type: BthhReportType,
3158         report_id: u8,
3159     ) -> BtStatus {
3160         self.get_hid_report_internal(addr, report_type, report_id)
3161     }
3162 
set_hid_report( &mut self, addr: RawAddress, report_type: BthhReportType, report: String, ) -> BtStatus3163     fn set_hid_report(
3164         &mut self,
3165         addr: RawAddress,
3166         report_type: BthhReportType,
3167         report: String,
3168     ) -> BtStatus {
3169         self.set_hid_report_internal(addr, report_type, report)
3170     }
3171 
send_hid_data(&mut self, addr: RawAddress, data: String) -> BtStatus3172     fn send_hid_data(&mut self, addr: RawAddress, data: String) -> BtStatus {
3173         self.send_hid_data_internal(addr, data)
3174     }
3175 }
3176