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