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