• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Anything related to the adapter API (IBluetooth).
2 
3 use bt_topshim::btif::{
4     BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState,
5     BtBondState, BtConnectionDirection, BtConnectionState, BtDeviceType, BtDiscMode,
6     BtDiscoveryState, BtHciErrorCode, BtPinCode, BtPropertyType, BtScanMode, BtSspVariant, BtState,
7     BtStatus, BtTransport, BtVendorProductInfo, DisplayAddress, RawAddress, ToggleableProfile,
8     Uuid, Uuid128Bit,
9 };
10 use bt_topshim::{
11     metrics,
12     profiles::gatt::GattStatus,
13     profiles::hid_host::{
14         BthhConnectionState, BthhHidInfo, BthhProtocolMode, BthhReportType, BthhStatus,
15         HHCallbacks, HHCallbacksDispatcher, HidHost,
16     },
17     profiles::sdp::{BtSdpRecord, Sdp, SdpCallbacks, SdpCallbacksDispatcher},
18     profiles::ProfileConnectionState,
19     topstack,
20 };
21 
22 use bt_utils::array_utils;
23 use bt_utils::cod::{is_cod_hid_combo, is_cod_hid_keyboard};
24 use btif_macros::{btif_callback, btif_callbacks_dispatcher};
25 
26 use log::{debug, warn};
27 use num_traits::cast::ToPrimitive;
28 use num_traits::pow;
29 use std::collections::HashMap;
30 use std::convert::TryInto;
31 use std::fs::File;
32 use std::hash::Hash;
33 use std::io::Write;
34 use std::process;
35 use std::sync::{Arc, Condvar, Mutex};
36 use std::time::Duration;
37 use std::time::Instant;
38 use tokio::sync::mpsc::Sender;
39 use tokio::task::JoinHandle;
40 use tokio::time;
41 
42 use crate::battery_service::BatteryServiceActions;
43 use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin};
44 use crate::bluetooth_gatt::{BluetoothGatt, IBluetoothGatt, IScannerCallback, ScanResult};
45 use crate::bluetooth_media::{BluetoothMedia, IBluetoothMedia, MediaActions};
46 use crate::callbacks::Callbacks;
47 use crate::uuid::{Profile, UuidHelper, HOGP};
48 use crate::{Message, RPCProxy, SuspendMode};
49 
50 const FLOSS_VER: u16 = 0x0001;
51 const DEFAULT_DISCOVERY_TIMEOUT_MS: u64 = 12800;
52 const MIN_ADV_INSTANCES_FOR_MULTI_ADV: u8 = 5;
53 
54 /// Devices that were last seen longer than this duration are considered stale
55 /// if they haven't already bonded or connected. Once this duration expires, the
56 /// clear event should be sent to clients.
57 const FOUND_DEVICE_FRESHNESS: Duration = Duration::from_secs(30);
58 
59 /// This is the value returned from Bluetooth Interface calls.
60 // TODO(241930383): Add enum to topshim
61 const BTM_SUCCESS: i32 = 0;
62 
63 const PID_DIR: &str = "/var/run/bluetooth";
64 
65 /// Defines the adapter API.
66 pub trait IBluetooth {
67     /// Adds a callback from a client who wishes to observe adapter events.
register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>)68     fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>);
69 
70     /// Adds a callback from a client who wishes to observe connection events.
register_connection_callback( &mut self, callback: Box<dyn IBluetoothConnectionCallback + Send>, ) -> u3271     fn register_connection_callback(
72         &mut self,
73         callback: Box<dyn IBluetoothConnectionCallback + Send>,
74     ) -> u32;
75 
76     /// Removes registered callback.
unregister_connection_callback(&mut self, callback_id: u32) -> bool77     fn unregister_connection_callback(&mut self, callback_id: u32) -> bool;
78 
79     /// Enables the adapter.
80     ///
81     /// Returns true if the request is accepted.
enable(&mut self) -> bool82     fn enable(&mut self) -> bool;
83 
84     /// Disables the adapter.
85     ///
86     /// Returns true if the request is accepted.
disable(&mut self) -> bool87     fn disable(&mut self) -> bool;
88 
89     /// Returns the Bluetooth address of the local adapter.
get_address(&self) -> String90     fn get_address(&self) -> String;
91 
92     /// Gets supported UUIDs by the local adapter.
get_uuids(&self) -> Vec<Uuid128Bit>93     fn get_uuids(&self) -> Vec<Uuid128Bit>;
94 
95     /// Gets the local adapter name.
get_name(&self) -> String96     fn get_name(&self) -> String;
97 
98     /// Sets the local adapter name.
set_name(&self, name: String) -> bool99     fn set_name(&self, name: String) -> bool;
100 
101     /// Gets the bluetooth class.
get_bluetooth_class(&self) -> u32102     fn get_bluetooth_class(&self) -> u32;
103 
104     /// Sets the bluetooth class.
set_bluetooth_class(&self, cod: u32) -> bool105     fn set_bluetooth_class(&self, cod: u32) -> bool;
106 
107     /// Returns whether the adapter is discoverable.
get_discoverable(&self) -> bool108     fn get_discoverable(&self) -> bool;
109 
110     /// Returns the adapter discoverable timeout.
get_discoverable_timeout(&self) -> u32111     fn get_discoverable_timeout(&self) -> u32;
112 
113     /// Sets discoverability. If discoverable, limits the duration with given value.
set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool114     fn set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool;
115 
116     /// Returns whether multi-advertisement is supported.
117     /// A minimum number of 5 advertising instances is required for multi-advertisment support.
is_multi_advertisement_supported(&self) -> bool118     fn is_multi_advertisement_supported(&self) -> bool;
119 
120     /// Returns whether LE extended advertising is supported.
is_le_extended_advertising_supported(&self) -> bool121     fn is_le_extended_advertising_supported(&self) -> bool;
122 
123     /// Starts BREDR Inquiry.
start_discovery(&mut self) -> bool124     fn start_discovery(&mut self) -> bool;
125 
126     /// Cancels BREDR Inquiry.
cancel_discovery(&mut self) -> bool127     fn cancel_discovery(&mut self) -> bool;
128 
129     /// Checks if discovery is started.
is_discovering(&self) -> bool130     fn is_discovering(&self) -> bool;
131 
132     /// Checks when discovery ends in milliseconds from now.
get_discovery_end_millis(&self) -> u64133     fn get_discovery_end_millis(&self) -> u64;
134 
135     /// Initiates pairing to a remote device. Triggers connection if not already started.
create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> bool136     fn create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> bool;
137 
138     /// Cancels any pending bond attempt on given device.
cancel_bond_process(&self, device: BluetoothDevice) -> bool139     fn cancel_bond_process(&self, device: BluetoothDevice) -> bool;
140 
141     /// Removes pairing for given device.
remove_bond(&self, device: BluetoothDevice) -> bool142     fn remove_bond(&self, device: BluetoothDevice) -> bool;
143 
144     /// Returns a list of known bonded devices.
get_bonded_devices(&self) -> Vec<BluetoothDevice>145     fn get_bonded_devices(&self) -> Vec<BluetoothDevice>;
146 
147     /// Gets the bond state of a single device.
get_bond_state(&self, device: BluetoothDevice) -> BtBondState148     fn get_bond_state(&self, device: BluetoothDevice) -> BtBondState;
149 
150     /// Set pin on bonding device.
set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool151     fn set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool;
152 
153     /// Set passkey on bonding device.
set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool154     fn set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool;
155 
156     /// Confirm that a pairing should be completed on a bonding device.
set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool157     fn set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool;
158 
159     /// Gets the name of the remote device.
get_remote_name(&self, device: BluetoothDevice) -> String160     fn get_remote_name(&self, device: BluetoothDevice) -> String;
161 
162     /// Gets the type of the remote device.
get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType163     fn get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType;
164 
165     /// Gets the alias of the remote device.
get_remote_alias(&self, device: BluetoothDevice) -> String166     fn get_remote_alias(&self, device: BluetoothDevice) -> String;
167 
168     /// Sets the alias of the remote device.
set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String)169     fn set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String);
170 
171     /// Gets the class of the remote device.
get_remote_class(&self, device: BluetoothDevice) -> u32172     fn get_remote_class(&self, device: BluetoothDevice) -> u32;
173 
174     /// Gets the appearance of the remote device.
get_remote_appearance(&self, device: BluetoothDevice) -> u16175     fn get_remote_appearance(&self, device: BluetoothDevice) -> u16;
176 
177     /// Gets whether the remote device is connected.
get_remote_connected(&self, device: BluetoothDevice) -> bool178     fn get_remote_connected(&self, device: BluetoothDevice) -> bool;
179 
180     /// Gets whether the remote device can wake the system.
get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool181     fn get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool;
182 
183     /// Returns a list of connected devices.
get_connected_devices(&self) -> Vec<BluetoothDevice>184     fn get_connected_devices(&self) -> Vec<BluetoothDevice>;
185 
186     /// Gets the connection state of a single device.
get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState187     fn get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState;
188 
189     /// Gets the connection state of a specific profile.
get_profile_connection_state(&self, profile: Uuid128Bit) -> ProfileConnectionState190     fn get_profile_connection_state(&self, profile: Uuid128Bit) -> ProfileConnectionState;
191 
192     /// Returns the cached UUIDs of a remote device.
get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid128Bit>193     fn get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid128Bit>;
194 
195     /// Triggers SDP to get UUIDs of a remote device.
fetch_remote_uuids(&self, device: BluetoothDevice) -> bool196     fn fetch_remote_uuids(&self, device: BluetoothDevice) -> bool;
197 
198     /// Triggers SDP and searches for a specific UUID on a remote device.
sdp_search(&self, device: BluetoothDevice, uuid: Uuid128Bit) -> bool199     fn sdp_search(&self, device: BluetoothDevice, uuid: Uuid128Bit) -> bool;
200 
201     /// Creates a new SDP record.
create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool202     fn create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool;
203 
204     /// Removes the SDP record associated with the provided handle.
remove_sdp_record(&self, handle: i32) -> bool205     fn remove_sdp_record(&self, handle: i32) -> bool;
206 
207     /// Connect all profiles supported by device and enabled on adapter.
connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool208     fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool;
209 
210     /// Disconnect all profiles supported by device and enabled on adapter.
disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool211     fn disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool;
212 
213     /// Returns whether WBS is supported.
is_wbs_supported(&self) -> bool214     fn is_wbs_supported(&self) -> bool;
215 
216     /// Returns whether SWB is supported.
is_swb_supported(&self) -> bool217     fn is_swb_supported(&self) -> bool;
218 }
219 
220 /// Adapter API for Bluetooth qualification and verification.
221 ///
222 /// This interface is provided for testing and debugging.
223 /// Clients should not use this interface for production.
224 pub trait IBluetoothQALegacy {
225     /// Returns whether the adapter is connectable.
get_connectable(&self) -> bool226     fn get_connectable(&self) -> bool;
227 
228     /// Sets connectability. Returns true on success, false otherwise.
set_connectable(&mut self, mode: bool) -> bool229     fn set_connectable(&mut self, mode: bool) -> bool;
230 
231     /// Returns the adapter's Bluetooth friendly name.
get_alias(&self) -> String232     fn get_alias(&self) -> String;
233 
234     /// Returns the adapter's Device ID information in modalias format
235     /// used by the kernel and udev.
get_modalias(&self) -> String236     fn get_modalias(&self) -> String;
237 
238     /// Gets HID report on the peer.
get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus239     fn get_hid_report(
240         &mut self,
241         addr: String,
242         report_type: BthhReportType,
243         report_id: u8,
244     ) -> BtStatus;
245 
246     /// Sets HID report to the peer.
set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus247     fn set_hid_report(
248         &mut self,
249         addr: String,
250         report_type: BthhReportType,
251         report: String,
252     ) -> BtStatus;
253 
254     /// Snd HID data report to the peer.
send_hid_data(&mut self, addr: String, data: String) -> BtStatus255     fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus;
256 }
257 
258 /// Delayed actions from adapter events.
259 pub enum DelayedActions {
260     /// Check whether the current set of found devices are still fresh.
261     DeviceFreshnessCheck,
262 
263     /// Connect to all supported profiles on target device.
264     ConnectAllProfiles(BluetoothDevice),
265 
266     /// Scanner for BLE discovery is registered with given status and scanner id.
267     BleDiscoveryScannerRegistered(Uuid128Bit, u8, GattStatus),
268 
269     /// Scanner for BLE discovery is reporting a result.
270     BleDiscoveryScannerResult(ScanResult),
271 }
272 
273 /// Serializable device used in various apis.
274 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
275 pub struct BluetoothDevice {
276     pub address: String,
277     pub name: String,
278 }
279 
280 impl BluetoothDevice {
new(address: String, name: String) -> BluetoothDevice281     pub(crate) fn new(address: String, name: String) -> BluetoothDevice {
282         BluetoothDevice { address, name }
283     }
284 
from_properties(in_properties: &Vec<BluetoothProperty>) -> BluetoothDevice285     pub(crate) fn from_properties(in_properties: &Vec<BluetoothProperty>) -> BluetoothDevice {
286         let mut address = String::from("");
287         let mut name = String::from("");
288 
289         for prop in in_properties {
290             match &prop {
291                 BluetoothProperty::BdAddr(bdaddr) => {
292                     address = bdaddr.to_string();
293                 }
294                 BluetoothProperty::BdName(bdname) => {
295                     name = bdname.clone();
296                 }
297                 _ => {}
298             }
299         }
300 
301         BluetoothDevice::new(address, name)
302     }
303 }
304 
305 /// Internal data structure that keeps a map of cached properties for a remote device.
306 struct BluetoothDeviceContext {
307     /// Transport type reported by ACL connection (if completed).
308     pub acl_reported_transport: BtTransport,
309 
310     pub acl_state: BtAclState,
311     pub bond_state: BtBondState,
312     pub info: BluetoothDevice,
313     pub last_seen: Instant,
314     pub properties: HashMap<BtPropertyType, BluetoothProperty>,
315 
316     /// Keep track of whether services have been resolved.
317     pub services_resolved: bool,
318 
319     /// If supported UUIDs weren't available in EIR, wait for services to be
320     /// resolved to connect.
321     pub wait_to_connect: bool,
322 }
323 
324 impl BluetoothDeviceContext {
new( bond_state: BtBondState, acl_state: BtAclState, info: BluetoothDevice, last_seen: Instant, properties: Vec<BluetoothProperty>, ) -> BluetoothDeviceContext325     pub(crate) fn new(
326         bond_state: BtBondState,
327         acl_state: BtAclState,
328         info: BluetoothDevice,
329         last_seen: Instant,
330         properties: Vec<BluetoothProperty>,
331     ) -> BluetoothDeviceContext {
332         let mut device = BluetoothDeviceContext {
333             acl_reported_transport: BtTransport::Auto,
334             acl_state,
335             bond_state,
336             info,
337             last_seen,
338             properties: HashMap::new(),
339             services_resolved: false,
340             wait_to_connect: false,
341         };
342         device.update_properties(&properties);
343         device
344     }
345 
update_properties(&mut self, in_properties: &Vec<BluetoothProperty>)346     pub(crate) fn update_properties(&mut self, in_properties: &Vec<BluetoothProperty>) {
347         for prop in in_properties {
348             // Handle merging of certain properties.
349             match &prop {
350                 BluetoothProperty::BdAddr(bdaddr) => {
351                     self.info.address = bdaddr.to_string();
352                     self.properties.insert(prop.get_type(), prop.clone());
353                 }
354                 BluetoothProperty::BdName(bdname) => {
355                     if !bdname.is_empty() {
356                         self.info.name = bdname.clone();
357                         self.properties.insert(prop.get_type(), prop.clone());
358                     }
359                 }
360                 _ => {
361                     self.properties.insert(prop.get_type(), prop.clone());
362                 }
363             }
364         }
365     }
366 
367     /// Mark this device as seen.
seen(&mut self)368     pub(crate) fn seen(&mut self) {
369         self.last_seen = Instant::now();
370     }
371 }
372 
373 /// The interface for adapter callbacks registered through `IBluetooth::register_callback`.
374 pub trait IBluetoothCallback: RPCProxy {
375     /// When any adapter property changes.
on_adapter_property_changed(&mut self, prop: BtPropertyType)376     fn on_adapter_property_changed(&mut self, prop: BtPropertyType);
377 
378     /// When any of the adapter local address is changed.
on_address_changed(&mut self, addr: String)379     fn on_address_changed(&mut self, addr: String);
380 
381     /// When the adapter name is changed.
on_name_changed(&mut self, name: String)382     fn on_name_changed(&mut self, name: String);
383 
384     /// When the adapter's discoverable mode is changed.
on_discoverable_changed(&mut self, discoverable: bool)385     fn on_discoverable_changed(&mut self, discoverable: bool);
386 
387     /// When a device is found via discovery.
on_device_found(&mut self, remote_device: BluetoothDevice)388     fn on_device_found(&mut self, remote_device: BluetoothDevice);
389 
390     /// When a device is cleared from discovered devices cache.
on_device_cleared(&mut self, remote_device: BluetoothDevice)391     fn on_device_cleared(&mut self, remote_device: BluetoothDevice);
392 
393     /// When the discovery state is changed.
on_discovering_changed(&mut self, discovering: bool)394     fn on_discovering_changed(&mut self, discovering: bool);
395 
396     /// 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, )397     fn on_ssp_request(
398         &mut self,
399         remote_device: BluetoothDevice,
400         cod: u32,
401         variant: BtSspVariant,
402         passkey: u32,
403     );
404 
405     /// 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)406     fn on_pin_request(&mut self, remote_device: BluetoothDevice, cod: u32, min_16_digit: bool);
407 
408     /// When there is a auto-gen pin to display the event to client.
on_pin_display(&mut self, remote_device: BluetoothDevice, pincode: String)409     fn on_pin_display(&mut self, remote_device: BluetoothDevice, pincode: String);
410 
411     /// When a bonding attempt has completed.
on_bond_state_changed(&mut self, status: u32, device_address: String, state: u32)412     fn on_bond_state_changed(&mut self, status: u32, device_address: String, state: u32);
413 
414     /// When an SDP search has completed.
on_sdp_search_complete( &mut self, remote_device: BluetoothDevice, searched_uuid: Uuid128Bit, sdp_records: Vec<BtSdpRecord>, )415     fn on_sdp_search_complete(
416         &mut self,
417         remote_device: BluetoothDevice,
418         searched_uuid: Uuid128Bit,
419         sdp_records: Vec<BtSdpRecord>,
420     );
421 
422     /// When an SDP record has been successfully created.
on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32)423     fn on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32);
424 }
425 
426 /// An interface for other modules to track found remote devices.
427 pub trait IBluetoothDeviceCallback {
428     /// When a device is found via discovery.
on_device_found(&mut self, remote_device: BluetoothDevice)429     fn on_device_found(&mut self, remote_device: BluetoothDevice);
430 
431     /// When a device is cleared from discovered devices cache.
on_device_cleared(&mut self, remote_device: BluetoothDevice)432     fn on_device_cleared(&mut self, remote_device: BluetoothDevice);
433 
434     /// When a device property is changed.
on_remote_device_properties_changed( &mut self, remote_device: BluetoothDevice, properties: Vec<BluetoothProperty>, )435     fn on_remote_device_properties_changed(
436         &mut self,
437         remote_device: BluetoothDevice,
438         properties: Vec<BluetoothProperty>,
439     );
440 }
441 
442 pub trait IBluetoothConnectionCallback: RPCProxy {
443     /// Notification sent when a remote device completes HCI connection.
on_device_connected(&mut self, remote_device: BluetoothDevice)444     fn on_device_connected(&mut self, remote_device: BluetoothDevice);
445 
446     /// Notification sent when a remote device completes HCI disconnection.
on_device_disconnected(&mut self, remote_device: BluetoothDevice)447     fn on_device_disconnected(&mut self, remote_device: BluetoothDevice);
448 }
449 
450 /// Implementation of the adapter API.
451 pub struct Bluetooth {
452     intf: Arc<Mutex<BluetoothInterface>>,
453 
454     adapter_index: i32,
455     bonded_devices: HashMap<String, BluetoothDeviceContext>,
456     ble_scanner_id: Option<u8>,
457     ble_scanner_uuid: Option<Uuid128Bit>,
458     bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
459     bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
460     bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
461     callbacks: Callbacks<dyn IBluetoothCallback + Send>,
462     connection_callbacks: Callbacks<dyn IBluetoothConnectionCallback + Send>,
463     discovering_started: Instant,
464     hh: Option<HidHost>,
465     is_connectable: bool,
466     is_discovering: bool,
467     is_discovering_before_suspend: bool,
468     is_discovery_paused: bool,
469     discovery_suspend_mode: SuspendMode,
470     local_address: Option<RawAddress>,
471     pending_discovery: bool,
472     properties: HashMap<BtPropertyType, BluetoothProperty>,
473     profiles_ready: bool,
474     found_devices: HashMap<String, BluetoothDeviceContext>,
475     freshness_check: Option<JoinHandle<()>>,
476     sdp: Option<Sdp>,
477     state: BtState,
478     tx: Sender<Message>,
479     // Internal API members
480     discoverable_timeout: Option<JoinHandle<()>>,
481 
482     /// Used to notify signal handler that we have turned off the stack.
483     sig_notifier: Arc<(Mutex<bool>, Condvar)>,
484 }
485 
486 impl Bluetooth {
487     /// Constructs the IBluetooth implementation.
new( adapter_index: i32, tx: Sender<Message>, sig_notifier: Arc<(Mutex<bool>, Condvar)>, intf: Arc<Mutex<BluetoothInterface>>, bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>, bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>, bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>, ) -> Bluetooth488     pub fn new(
489         adapter_index: i32,
490         tx: Sender<Message>,
491         sig_notifier: Arc<(Mutex<bool>, Condvar)>,
492         intf: Arc<Mutex<BluetoothInterface>>,
493         bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
494         bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
495         bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
496     ) -> Bluetooth {
497         Bluetooth {
498             adapter_index,
499             bonded_devices: HashMap::new(),
500             callbacks: Callbacks::new(tx.clone(), Message::AdapterCallbackDisconnected),
501             connection_callbacks: Callbacks::new(
502                 tx.clone(),
503                 Message::ConnectionCallbackDisconnected,
504             ),
505             hh: None,
506             ble_scanner_id: None,
507             ble_scanner_uuid: None,
508             bluetooth_admin,
509             bluetooth_gatt,
510             bluetooth_media,
511             discovering_started: Instant::now(),
512             intf,
513             is_connectable: false,
514             is_discovering: false,
515             is_discovering_before_suspend: false,
516             is_discovery_paused: false,
517             discovery_suspend_mode: SuspendMode::Normal,
518             local_address: None,
519             pending_discovery: false,
520             properties: HashMap::new(),
521             profiles_ready: false,
522             found_devices: HashMap::new(),
523             freshness_check: None,
524             sdp: None,
525             state: BtState::Off,
526             tx,
527             // Internal API members
528             discoverable_timeout: None,
529             sig_notifier,
530         }
531     }
532 
disable_profile(&mut self, profile: &Profile)533     fn disable_profile(&mut self, profile: &Profile) {
534         if !UuidHelper::is_profile_supported(profile) {
535             return;
536         }
537 
538         match profile {
539             Profile::Hid => {
540                 self.hh.as_mut().unwrap().activate_hidp(false);
541             }
542 
543             Profile::Hogp => {
544                 self.hh.as_mut().unwrap().activate_hogp(false);
545             }
546 
547             Profile::A2dpSource | Profile::Hfp | Profile::AvrcpTarget => {
548                 self.bluetooth_media.lock().unwrap().disable_profile(profile);
549             }
550             // Ignore profiles that we don't connect.
551             _ => (),
552         }
553     }
554 
enable_profile(&mut self, profile: &Profile)555     fn enable_profile(&mut self, profile: &Profile) {
556         if !UuidHelper::is_profile_supported(profile) {
557             return;
558         }
559 
560         match profile {
561             Profile::Hid => {
562                 self.hh.as_mut().unwrap().activate_hidp(true);
563             }
564 
565             Profile::Hogp => {
566                 self.hh.as_mut().unwrap().activate_hogp(true);
567             }
568 
569             Profile::A2dpSource | Profile::Hfp | Profile::AvrcpTarget => {
570                 self.bluetooth_media.lock().unwrap().enable_profile(profile);
571             }
572             // Ignore profiles that we don't connect.
573             _ => (),
574         }
575     }
576 
is_profile_enabled(&self, profile: &Profile) -> Option<bool>577     fn is_profile_enabled(&self, profile: &Profile) -> Option<bool> {
578         if !UuidHelper::is_profile_supported(profile) {
579             return None;
580         }
581 
582         match profile {
583             Profile::Hid => Some(self.hh.as_ref().unwrap().is_hidp_activated),
584 
585             Profile::Hogp => Some(self.hh.as_ref().unwrap().is_hogp_activated),
586 
587             Profile::A2dpSource | Profile::Hfp | Profile::AvrcpTarget => {
588                 self.bluetooth_media.lock().unwrap().is_profile_enabled(profile)
589             }
590             // Ignore profiles that we don't connect.
591             _ => None,
592         }
593     }
594 
toggle_enabled_profiles(&mut self, allowed_services: &Vec<Uuid128Bit>)595     pub fn toggle_enabled_profiles(&mut self, allowed_services: &Vec<Uuid128Bit>) {
596         for profile in UuidHelper::get_supported_profiles().clone() {
597             // Only toggle initializable profiles.
598             if let Some(enabled) = self.is_profile_enabled(&profile) {
599                 let allowed = allowed_services.len() == 0
600                     || allowed_services.contains(&UuidHelper::get_profile_uuid(&profile).unwrap());
601 
602                 if allowed && !enabled {
603                     debug!("Enabling profile {}", &profile);
604                     self.enable_profile(&profile);
605                 } else if !allowed && enabled {
606                     debug!("Disabling profile {}", &profile);
607                     self.disable_profile(&profile);
608                 }
609             }
610         }
611 
612         if self.hh.as_mut().unwrap().configure_enabled_profiles() {
613             self.hh.as_mut().unwrap().disable();
614             let txl = self.tx.clone();
615 
616             tokio::spawn(async move {
617                 // Wait 100 milliseconds to prevent race condition caused by quick disable then
618                 // enable.
619                 // TODO: (b/272191117): don't enable until we're sure disable is done.
620                 tokio::time::sleep(Duration::from_millis(100)).await;
621                 let _ = txl.send(Message::HidHostEnable).await;
622             });
623         }
624     }
625 
enable_hidhost(&mut self)626     pub fn enable_hidhost(&mut self) {
627         self.hh.as_mut().unwrap().enable();
628     }
629 
init_profiles(&mut self)630     pub fn init_profiles(&mut self) {
631         let sdptx = self.tx.clone();
632         self.sdp = Some(Sdp::new(&self.intf.lock().unwrap()));
633         self.sdp.as_mut().unwrap().initialize(SdpCallbacksDispatcher {
634             dispatch: Box::new(move |cb| {
635                 let txl = sdptx.clone();
636                 topstack::get_runtime().spawn(async move {
637                     let _ = txl.send(Message::Sdp(cb)).await;
638                 });
639             }),
640         });
641 
642         let hhtx = self.tx.clone();
643         self.hh = Some(HidHost::new(&self.intf.lock().unwrap()));
644         self.hh.as_mut().unwrap().initialize(HHCallbacksDispatcher {
645             dispatch: Box::new(move |cb| {
646                 let txl = hhtx.clone();
647                 topstack::get_runtime().spawn(async move {
648                     let _ = txl.send(Message::HidHost(cb)).await;
649                 });
650             }),
651         });
652 
653         let allowed_profiles = self.bluetooth_admin.lock().unwrap().get_allowed_services();
654         self.toggle_enabled_profiles(&allowed_profiles);
655         // Mark profiles as ready
656         self.profiles_ready = true;
657     }
658 
update_local_address(&mut self, addr: &RawAddress)659     fn update_local_address(&mut self, addr: &RawAddress) {
660         self.local_address = Some(addr.clone());
661 
662         self.callbacks.for_all_callbacks(|callback| {
663             callback.on_address_changed(addr.to_string());
664         });
665     }
666 
adapter_callback_disconnected(&mut self, id: u32)667     pub(crate) fn adapter_callback_disconnected(&mut self, id: u32) {
668         self.callbacks.remove_callback(id);
669     }
670 
connection_callback_disconnected(&mut self, id: u32)671     pub(crate) fn connection_callback_disconnected(&mut self, id: u32) {
672         self.connection_callbacks.remove_callback(id);
673     }
674 
get_remote_device_if_found(&self, address: &str) -> Option<&BluetoothDeviceContext>675     fn get_remote_device_if_found(&self, address: &str) -> Option<&BluetoothDeviceContext> {
676         self.bonded_devices.get(address).or_else(|| self.found_devices.get(address))
677     }
678 
get_remote_device_if_found_mut( &mut self, address: &str, ) -> Option<&mut BluetoothDeviceContext>679     fn get_remote_device_if_found_mut(
680         &mut self,
681         address: &str,
682     ) -> Option<&mut BluetoothDeviceContext> {
683         match self.bonded_devices.get_mut(address) {
684             None => self.found_devices.get_mut(address),
685             some => some,
686         }
687     }
688 
get_remote_device_info_if_found(&self, remote_address: &str) -> Option<BluetoothDevice>689     fn get_remote_device_info_if_found(&self, remote_address: &str) -> Option<BluetoothDevice> {
690         self.get_remote_device_if_found(remote_address)
691             .map(|device_context| device_context.info.clone())
692     }
693 
get_remote_device_property( &self, device: &BluetoothDevice, property_type: &BtPropertyType, ) -> Option<BluetoothProperty>694     fn get_remote_device_property(
695         &self,
696         device: &BluetoothDevice,
697         property_type: &BtPropertyType,
698     ) -> Option<BluetoothProperty> {
699         self.get_remote_device_if_found(&device.address)
700             .and_then(|d| d.properties.get(property_type).and_then(|p| Some(p.clone())))
701     }
702 
set_remote_device_property( &mut self, device: &BluetoothDevice, property_type: BtPropertyType, property: BluetoothProperty, ) -> Result<(), ()>703     fn set_remote_device_property(
704         &mut self,
705         device: &BluetoothDevice,
706         property_type: BtPropertyType,
707         property: BluetoothProperty,
708     ) -> Result<(), ()> {
709         let remote_device = match self.get_remote_device_if_found_mut(&device.address) {
710             Some(d) => d,
711             None => {
712                 return Err(());
713             }
714         };
715 
716         let mut addr = RawAddress::from_string(device.address.clone());
717         if addr.is_none() {
718             return Err(());
719         }
720         let addr = addr.as_mut().unwrap();
721 
722         // TODO: Determine why a callback isn't invoked to do this.
723         remote_device.properties.insert(property_type, property.clone());
724         self.intf.lock().unwrap().set_remote_device_property(addr, property);
725         Ok(())
726     }
727 
728     /// Returns whether the adapter is connectable.
get_connectable_internal(&self) -> bool729     pub(crate) fn get_connectable_internal(&self) -> bool {
730         match self.properties.get(&BtPropertyType::AdapterScanMode) {
731             Some(prop) => match prop {
732                 BluetoothProperty::AdapterScanMode(mode) => match *mode {
733                     BtScanMode::Connectable | BtScanMode::ConnectableDiscoverable => true,
734                     _ => false,
735                 },
736                 _ => false,
737             },
738             _ => false,
739         }
740     }
741 
742     /// Sets the adapter's connectable mode for classic connections.
set_connectable_internal(&mut self, mode: bool) -> bool743     pub(crate) fn set_connectable_internal(&mut self, mode: bool) -> bool {
744         self.is_connectable = mode;
745         if mode && self.get_discoverable() {
746             return true;
747         }
748         self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::AdapterScanMode(
749             if mode { BtScanMode::Connectable } else { BtScanMode::None_ },
750         )) == 0
751     }
752 
753     /// Returns adapter's discoverable mode.
get_discoverable_mode_internal(&self) -> BtDiscMode754     pub fn get_discoverable_mode_internal(&self) -> BtDiscMode {
755         let off_mode = BtDiscMode::NonDiscoverable;
756 
757         match self.properties.get(&BtPropertyType::AdapterScanMode) {
758             Some(prop) => match prop {
759                 BluetoothProperty::AdapterScanMode(mode) => match *mode {
760                     BtScanMode::ConnectableDiscoverable => BtDiscMode::GeneralDiscoverable,
761                     BtScanMode::ConnectableLimitedDiscoverable => BtDiscMode::LimitedDiscoverable,
762                     _ => off_mode,
763                 },
764                 _ => off_mode,
765             },
766             _ => off_mode,
767         }
768     }
769 
770     /// Caches the discoverable mode into BluetoothQA.
cache_discoverable_mode_into_qa(&self)771     pub fn cache_discoverable_mode_into_qa(&self) {
772         let disc_mode = self.get_discoverable_mode_internal();
773 
774         let txl = self.tx.clone();
775         tokio::spawn(async move {
776             let _ = txl.send(Message::QaOnDiscoverableModeChanged(disc_mode)).await;
777         });
778     }
779 
780     /// Returns all bonded and connected devices.
get_bonded_and_connected_devices(&mut self) -> Vec<BluetoothDevice>781     pub(crate) fn get_bonded_and_connected_devices(&mut self) -> Vec<BluetoothDevice> {
782         self.bonded_devices
783             .values()
784             .filter(|v| v.acl_state == BtAclState::Connected && v.bond_state == BtBondState::Bonded)
785             .map(|v| v.info.clone())
786             .collect()
787     }
788 
789     /// Gets the bond state of a single device with its address.
get_bond_state_by_addr(&self, addr: &String) -> BtBondState790     pub fn get_bond_state_by_addr(&self, addr: &String) -> BtBondState {
791         match self.bonded_devices.get(addr) {
792             Some(device) => device.bond_state.clone(),
793             None => BtBondState::NotBonded,
794         }
795     }
796 
797     /// Check whether found devices are still fresh. If they're outside the
798     /// freshness window, send a notification to clear the device from clients.
trigger_freshness_check(&mut self)799     fn trigger_freshness_check(&mut self) {
800         if let Some(ref handle) = self.freshness_check {
801             // Abort and drop the previous JoinHandle.
802             handle.abort();
803             self.freshness_check = None;
804         }
805 
806         // A found device is considered fresh if:
807         // * It was last seen less than |FOUND_DEVICE_FRESHNESS| ago.
808         // * It is currently connected.
809         fn is_fresh(d: &BluetoothDeviceContext, now: &Instant) -> bool {
810             let fresh_at = d.last_seen + FOUND_DEVICE_FRESHNESS;
811             now < &fresh_at || d.acl_state == BtAclState::Connected
812         }
813 
814         let now = Instant::now();
815         let stale_devices: Vec<BluetoothDevice> = self
816             .found_devices
817             .iter()
818             .filter(|(_, d)| !is_fresh(d, &now))
819             .map(|(_, d)| d.info.clone())
820             .collect();
821 
822         // Retain only devices that are fresh.
823         self.found_devices.retain(|_, d| is_fresh(d, &now));
824 
825         for d in stale_devices {
826             self.callbacks.for_all_callbacks(|callback| {
827                 callback.on_device_cleared(d.clone());
828             });
829 
830             self.bluetooth_admin.lock().unwrap().on_device_cleared(&d);
831         }
832 
833         // If we have any fresh devices remaining, re-queue a freshness check.
834         if self.found_devices.len() > 0 {
835             let txl = self.tx.clone();
836 
837             self.freshness_check = Some(tokio::spawn(async move {
838                 time::sleep(FOUND_DEVICE_FRESHNESS).await;
839                 let _ = txl
840                     .send(Message::DelayedAdapterActions(DelayedActions::DeviceFreshnessCheck))
841                     .await;
842             }));
843         }
844     }
845 
846     /// Makes an LE_RAND call to the Bluetooth interface.
le_rand(&mut self) -> bool847     pub fn le_rand(&mut self) -> bool {
848         self.intf.lock().unwrap().le_rand() == BTM_SUCCESS
849     }
850 
send_metrics_remote_device_info(device: &BluetoothDeviceContext)851     fn send_metrics_remote_device_info(device: &BluetoothDeviceContext) {
852         if device.bond_state != BtBondState::Bonded && device.acl_state != BtAclState::Connected {
853             return;
854         }
855 
856         let addr = RawAddress::from_string(device.info.address.clone()).unwrap();
857         let mut class_of_device = 0u32;
858         let mut device_type = BtDeviceType::Unknown;
859         let mut appearance = 0u16;
860         let mut vpi =
861             BtVendorProductInfo { vendor_id_src: 0, vendor_id: 0, product_id: 0, version: 0 };
862 
863         for prop in device.properties.values() {
864             match prop {
865                 BluetoothProperty::TypeOfDevice(p) => device_type = p.clone(),
866                 BluetoothProperty::ClassOfDevice(p) => class_of_device = p.clone(),
867                 BluetoothProperty::Appearance(p) => appearance = p.clone(),
868                 BluetoothProperty::VendorProductInfo(p) => vpi = p.clone(),
869                 _ => (),
870             }
871         }
872 
873         metrics::device_info_report(
874             addr,
875             device_type,
876             class_of_device,
877             appearance,
878             vpi.vendor_id,
879             vpi.vendor_id_src,
880             vpi.product_id,
881             vpi.version,
882         );
883     }
884 
885     /// Handle some delayed and recurring actions within the adapter.
handle_delayed_actions(&mut self, action: DelayedActions)886     pub(crate) fn handle_delayed_actions(&mut self, action: DelayedActions) {
887         match action {
888             DelayedActions::DeviceFreshnessCheck => {
889                 self.trigger_freshness_check();
890             }
891 
892             DelayedActions::ConnectAllProfiles(device) => {
893                 self.connect_all_enabled_profiles(device);
894             }
895 
896             DelayedActions::BleDiscoveryScannerRegistered(uuid, scanner_id, status) => {
897                 if let Some(app_uuid) = self.ble_scanner_uuid {
898                     if app_uuid == uuid {
899                         if status == GattStatus::Success {
900                             self.ble_scanner_id = Some(scanner_id);
901                         } else {
902                             log::error!("BLE discovery scanner failed to register: {:?}", status);
903                         }
904                     }
905                 }
906             }
907 
908             DelayedActions::BleDiscoveryScannerResult(result) => {
909                 let addr = RawAddress::from_string(result.address);
910 
911                 let properties = match addr {
912                     Some(v) => {
913                         let mut props = vec![];
914                         props.push(BluetoothProperty::BdName(result.name.clone()));
915                         props.push(BluetoothProperty::BdAddr(v.clone()));
916                         if result.service_uuids.len() > 0 {
917                             props.push(BluetoothProperty::Uuids(
918                                 result
919                                     .service_uuids
920                                     .iter()
921                                     .map(|&v| Uuid::from(v.clone()))
922                                     .collect(),
923                             ));
924                         }
925                         props.push(BluetoothProperty::RemoteRssi(result.rssi));
926 
927                         props
928                     }
929                     None => {
930                         return;
931                     }
932                 };
933 
934                 // Generate a vector of properties from ScanResult.
935                 let device = BluetoothDevice::from_properties(&properties);
936                 let address = device.address.clone();
937 
938                 if let Some(existing) = self.found_devices.get_mut(&address) {
939                     existing.update_properties(&properties);
940                     existing.seen();
941                 } else {
942                     let device_with_props = BluetoothDeviceContext::new(
943                         BtBondState::NotBonded,
944                         BtAclState::Disconnected,
945                         device,
946                         Instant::now(),
947                         properties,
948                     );
949                     self.found_devices.insert(address.clone(), device_with_props);
950                 }
951             }
952         }
953     }
954 
955     /// Creates a file to notify btmanagerd the adapter is enabled.
create_pid_file(&self) -> std::io::Result<()>956     fn create_pid_file(&self) -> std::io::Result<()> {
957         let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.adapter_index);
958         let mut f = File::create(&file_name)?;
959         f.write_all(process::id().to_string().as_bytes())?;
960         Ok(())
961     }
962 
963     /// Removes the file to notify btmanagerd the adapter is disabled.
remove_pid_file(&self) -> std::io::Result<()>964     fn remove_pid_file(&self) -> std::io::Result<()> {
965         let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.adapter_index);
966         std::fs::remove_file(&file_name)?;
967         Ok(())
968     }
969 
970     /// Set the suspend mode.
set_discovery_suspend_mode(&mut self, suspend_mode: SuspendMode)971     pub fn set_discovery_suspend_mode(&mut self, suspend_mode: SuspendMode) {
972         if suspend_mode != self.discovery_suspend_mode {
973             self.discovery_suspend_mode = suspend_mode;
974         }
975     }
976 
977     /// Gets current suspend mode.
get_discovery_suspend_mode(&self) -> SuspendMode978     pub fn get_discovery_suspend_mode(&self) -> SuspendMode {
979         self.discovery_suspend_mode.clone()
980     }
981 
982     /// Enters the suspend mode for discovery.
discovery_enter_suspend(&mut self) -> BtStatus983     pub fn discovery_enter_suspend(&mut self) -> BtStatus {
984         if self.get_discovery_suspend_mode() != SuspendMode::Normal {
985             return BtStatus::Busy;
986         }
987         self.set_discovery_suspend_mode(SuspendMode::Suspending);
988 
989         if self.is_discovering {
990             self.is_discovering_before_suspend = true;
991             self.cancel_discovery();
992         }
993         self.set_discovery_suspend_mode(SuspendMode::Suspended);
994 
995         return BtStatus::Success;
996     }
997 
998     /// Exits the suspend mode for discovery.
discovery_exit_suspend(&mut self) -> BtStatus999     pub fn discovery_exit_suspend(&mut self) -> BtStatus {
1000         if self.get_discovery_suspend_mode() != SuspendMode::Suspended {
1001             return BtStatus::Busy;
1002         }
1003         self.set_discovery_suspend_mode(SuspendMode::Resuming);
1004 
1005         if self.is_discovering_before_suspend {
1006             self.is_discovering_before_suspend = false;
1007             self.start_discovery();
1008         }
1009         self.set_discovery_suspend_mode(SuspendMode::Normal);
1010 
1011         return BtStatus::Success;
1012     }
1013 
1014     /// Temporarily stop the discovery process and mark it as paused so that clients cannot restart
1015     /// it.
pause_discovery(&mut self)1016     fn pause_discovery(&mut self) {
1017         self.cancel_discovery();
1018         self.is_discovery_paused = true;
1019     }
1020 
1021     /// Remove the paused flag to allow clients to begin discovery, and if there is already a
1022     /// pending request, start discovery.
resume_discovery(&mut self)1023     fn resume_discovery(&mut self) {
1024         if self.pending_discovery {
1025             self.pending_discovery = false;
1026             self.start_discovery();
1027         }
1028         self.is_discovery_paused = false;
1029     }
1030 }
1031 
1032 #[btif_callbacks_dispatcher(dispatch_base_callbacks, BaseCallbacks)]
1033 #[allow(unused_variables)]
1034 pub(crate) trait BtifBluetoothCallbacks {
1035     #[btif_callback(AdapterState)]
adapter_state_changed(&mut self, state: BtState)1036     fn adapter_state_changed(&mut self, state: BtState) {}
1037 
1038     #[btif_callback(AdapterProperties)]
adapter_properties_changed( &mut self, status: BtStatus, num_properties: i32, properties: Vec<BluetoothProperty>, )1039     fn adapter_properties_changed(
1040         &mut self,
1041         status: BtStatus,
1042         num_properties: i32,
1043         properties: Vec<BluetoothProperty>,
1044     ) {
1045     }
1046 
1047     #[btif_callback(DeviceFound)]
device_found(&mut self, n: i32, properties: Vec<BluetoothProperty>)1048     fn device_found(&mut self, n: i32, properties: Vec<BluetoothProperty>) {}
1049 
1050     #[btif_callback(DiscoveryState)]
discovery_state(&mut self, state: BtDiscoveryState)1051     fn discovery_state(&mut self, state: BtDiscoveryState) {}
1052 
1053     #[btif_callback(SspRequest)]
ssp_request( &mut self, remote_addr: RawAddress, remote_name: String, cod: u32, variant: BtSspVariant, passkey: u32, )1054     fn ssp_request(
1055         &mut self,
1056         remote_addr: RawAddress,
1057         remote_name: String,
1058         cod: u32,
1059         variant: BtSspVariant,
1060         passkey: u32,
1061     ) {
1062     }
1063 
1064     #[btif_callback(BondState)]
bond_state( &mut self, status: BtStatus, addr: RawAddress, bond_state: BtBondState, fail_reason: i32, )1065     fn bond_state(
1066         &mut self,
1067         status: BtStatus,
1068         addr: RawAddress,
1069         bond_state: BtBondState,
1070         fail_reason: i32,
1071     ) {
1072     }
1073 
1074     #[btif_callback(RemoteDeviceProperties)]
remote_device_properties_changed( &mut self, status: BtStatus, addr: RawAddress, num_properties: i32, properties: Vec<BluetoothProperty>, )1075     fn remote_device_properties_changed(
1076         &mut self,
1077         status: BtStatus,
1078         addr: RawAddress,
1079         num_properties: i32,
1080         properties: Vec<BluetoothProperty>,
1081     ) {
1082     }
1083 
1084     #[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, )1085     fn acl_state(
1086         &mut self,
1087         status: BtStatus,
1088         addr: RawAddress,
1089         state: BtAclState,
1090         link_type: BtTransport,
1091         hci_reason: BtHciErrorCode,
1092         conn_direction: BtConnectionDirection,
1093         acl_handle: u16,
1094     ) {
1095     }
1096 
1097     #[btif_callback(LeRandCallback)]
le_rand_cb(&mut self, random: u64)1098     fn le_rand_cb(&mut self, random: u64) {}
1099 
1100     #[btif_callback(PinRequest)]
pin_request( &mut self, remote_addr: RawAddress, remote_name: String, cod: u32, min_16_digit: bool, )1101     fn pin_request(
1102         &mut self,
1103         remote_addr: RawAddress,
1104         remote_name: String,
1105         cod: u32,
1106         min_16_digit: bool,
1107     ) {
1108     }
1109 }
1110 
1111 #[btif_callbacks_dispatcher(dispatch_hid_host_callbacks, HHCallbacks)]
1112 pub(crate) trait BtifHHCallbacks {
1113     #[btif_callback(ConnectionState)]
connection_state(&mut self, address: RawAddress, state: BthhConnectionState)1114     fn connection_state(&mut self, address: RawAddress, state: BthhConnectionState);
1115 
1116     #[btif_callback(HidInfo)]
hid_info(&mut self, address: RawAddress, info: BthhHidInfo)1117     fn hid_info(&mut self, address: RawAddress, info: BthhHidInfo);
1118 
1119     #[btif_callback(ProtocolMode)]
protocol_mode(&mut self, address: RawAddress, status: BthhStatus, mode: BthhProtocolMode)1120     fn protocol_mode(&mut self, address: RawAddress, status: BthhStatus, mode: BthhProtocolMode);
1121 
1122     #[btif_callback(IdleTime)]
idle_time(&mut self, address: RawAddress, status: BthhStatus, idle_rate: i32)1123     fn idle_time(&mut self, address: RawAddress, status: BthhStatus, idle_rate: i32);
1124 
1125     #[btif_callback(GetReport)]
get_report(&mut self, address: RawAddress, status: BthhStatus, data: Vec<u8>, size: i32)1126     fn get_report(&mut self, address: RawAddress, status: BthhStatus, data: Vec<u8>, size: i32);
1127 
1128     #[btif_callback(Handshake)]
handshake(&mut self, address: RawAddress, status: BthhStatus)1129     fn handshake(&mut self, address: RawAddress, status: BthhStatus);
1130 }
1131 
1132 #[btif_callbacks_dispatcher(dispatch_sdp_callbacks, SdpCallbacks)]
1133 pub(crate) trait BtifSdpCallbacks {
1134     #[btif_callback(SdpSearch)]
sdp_search( &mut self, status: BtStatus, address: RawAddress, uuid: Uuid, count: i32, records: Vec<BtSdpRecord>, )1135     fn sdp_search(
1136         &mut self,
1137         status: BtStatus,
1138         address: RawAddress,
1139         uuid: Uuid,
1140         count: i32,
1141         records: Vec<BtSdpRecord>,
1142     );
1143 }
1144 
get_bt_dispatcher(tx: Sender<Message>) -> BaseCallbacksDispatcher1145 pub fn get_bt_dispatcher(tx: Sender<Message>) -> BaseCallbacksDispatcher {
1146     BaseCallbacksDispatcher {
1147         dispatch: Box::new(move |cb| {
1148             let txl = tx.clone();
1149             topstack::get_runtime().spawn(async move {
1150                 let _ = txl.send(Message::Base(cb)).await;
1151             });
1152         }),
1153     }
1154 }
1155 
1156 impl BtifBluetoothCallbacks for Bluetooth {
adapter_state_changed(&mut self, state: BtState)1157     fn adapter_state_changed(&mut self, state: BtState) {
1158         let prev_state = self.state.clone();
1159         self.state = state;
1160         metrics::adapter_state_changed(self.state.clone());
1161 
1162         // If it's the same state as before, no further action
1163         if self.state == prev_state {
1164             return;
1165         }
1166 
1167         match self.state {
1168             BtState::Off => {
1169                 self.properties.clear();
1170                 match self.remove_pid_file() {
1171                     Err(err) => warn!("remove_pid_file() error: {}", err),
1172                     _ => (),
1173                 }
1174 
1175                 // Let the signal notifier know we are turned off.
1176                 *self.sig_notifier.0.lock().unwrap() = false;
1177                 self.sig_notifier.1.notify_all();
1178             }
1179 
1180             BtState::On => {
1181                 // Initialize media
1182                 self.bluetooth_media.lock().unwrap().initialize();
1183 
1184                 // Trigger properties update
1185                 self.intf.lock().unwrap().get_adapter_properties();
1186 
1187                 // Also need to manually request some properties
1188                 self.intf.lock().unwrap().get_adapter_property(BtPropertyType::ClassOfDevice);
1189 
1190                 // Initialize the BLE scanner for discovery.
1191                 let callback_id = self.bluetooth_gatt.lock().unwrap().register_scanner_callback(
1192                     Box::new(BleDiscoveryCallbacks::new(self.tx.clone())),
1193                 );
1194                 self.ble_scanner_uuid =
1195                     Some(self.bluetooth_gatt.lock().unwrap().register_scanner(callback_id));
1196 
1197                 // Ensure device is connectable so that disconnected device can reconnect
1198                 self.set_connectable(true);
1199 
1200                 // Notify the signal notifier that we are turned on.
1201                 *self.sig_notifier.0.lock().unwrap() = true;
1202                 self.sig_notifier.1.notify_all();
1203 
1204                 // Signal that the stack is up and running.
1205                 match self.create_pid_file() {
1206                     Err(err) => warn!("create_pid_file() error: {}", err),
1207                     _ => (),
1208                 }
1209 
1210                 // Inform the rest of the stack we're ready.
1211                 let txl = self.tx.clone();
1212                 tokio::spawn(async move {
1213                     let _ = txl.send(Message::AdapterReady).await;
1214                 });
1215             }
1216         }
1217     }
1218 
1219     #[allow(unused_variables)]
adapter_properties_changed( &mut self, status: BtStatus, num_properties: i32, properties: Vec<BluetoothProperty>, )1220     fn adapter_properties_changed(
1221         &mut self,
1222         status: BtStatus,
1223         num_properties: i32,
1224         properties: Vec<BluetoothProperty>,
1225     ) {
1226         if status != BtStatus::Success {
1227             return;
1228         }
1229 
1230         // Update local property cache
1231         for prop in properties {
1232             self.properties.insert(prop.get_type(), prop.clone());
1233 
1234             match &prop {
1235                 BluetoothProperty::BdAddr(bdaddr) => {
1236                     self.update_local_address(&bdaddr);
1237                 }
1238                 BluetoothProperty::AdapterBondedDevices(bondlist) => {
1239                     for addr in bondlist.iter() {
1240                         let address = addr.to_string();
1241 
1242                         // Update bonded state if already in the list. Otherwise create a new
1243                         // context with empty properties and name.
1244                         self.bonded_devices
1245                             .entry(address.clone())
1246                             .and_modify(|d| d.bond_state = BtBondState::Bonded)
1247                             .or_insert(BluetoothDeviceContext::new(
1248                                 BtBondState::Bonded,
1249                                 BtAclState::Disconnected,
1250                                 BluetoothDevice::new(address.clone(), "".to_string()),
1251                                 Instant::now(),
1252                                 vec![],
1253                             ));
1254                     }
1255                 }
1256                 BluetoothProperty::BdName(bdname) => {
1257                     self.callbacks.for_all_callbacks(|callback| {
1258                         callback.on_name_changed(bdname.clone());
1259                     });
1260                 }
1261                 BluetoothProperty::AdapterScanMode(mode) => {
1262                     self.cache_discoverable_mode_into_qa();
1263 
1264                     self.callbacks.for_all_callbacks(|callback| {
1265                         callback
1266                             .on_discoverable_changed(*mode == BtScanMode::ConnectableDiscoverable);
1267                     });
1268                 }
1269                 _ => {}
1270             }
1271 
1272             self.callbacks.for_all_callbacks(|callback| {
1273                 callback.on_adapter_property_changed(prop.get_type());
1274             });
1275         }
1276     }
1277 
device_found(&mut self, _n: i32, properties: Vec<BluetoothProperty>)1278     fn device_found(&mut self, _n: i32, properties: Vec<BluetoothProperty>) {
1279         let device = BluetoothDevice::from_properties(&properties);
1280         let address = device.address.clone();
1281 
1282         if let Some(existing) = self.found_devices.get_mut(&address) {
1283             existing.update_properties(&properties);
1284             existing.seen();
1285         } else {
1286             let device_with_props = BluetoothDeviceContext::new(
1287                 BtBondState::NotBonded,
1288                 BtAclState::Disconnected,
1289                 device,
1290                 Instant::now(),
1291                 properties,
1292             );
1293             self.found_devices.insert(address.clone(), device_with_props);
1294         }
1295 
1296         let device = self.found_devices.get(&address).unwrap();
1297 
1298         self.callbacks.for_all_callbacks(|callback| {
1299             callback.on_device_found(device.info.clone());
1300         });
1301 
1302         self.bluetooth_admin.lock().unwrap().on_device_found(&device.info);
1303     }
1304 
discovery_state(&mut self, state: BtDiscoveryState)1305     fn discovery_state(&mut self, state: BtDiscoveryState) {
1306         let is_discovering = &state == &BtDiscoveryState::Started;
1307 
1308         // No-op if we're updating the state to the same value again.
1309         if &is_discovering == &self.is_discovering {
1310             return;
1311         }
1312 
1313         // Cache discovering state
1314         self.is_discovering = &state == &BtDiscoveryState::Started;
1315         if self.is_discovering {
1316             self.discovering_started = Instant::now();
1317         }
1318 
1319         // Prevent sending out discovering changes or freshness checks when
1320         // suspending. Clients don't need to be notified of discovery pausing
1321         // during suspend. They will probably try to restore it and fail.
1322         let discovery_suspend_mode = self.get_discovery_suspend_mode();
1323         if discovery_suspend_mode != SuspendMode::Normal
1324             && discovery_suspend_mode != SuspendMode::Resuming
1325         {
1326             return;
1327         }
1328 
1329         self.callbacks.for_all_callbacks(|callback| {
1330             callback.on_discovering_changed(state == BtDiscoveryState::Started);
1331         });
1332 
1333         // Stopped discovering and no freshness check is active. Immediately do
1334         // freshness check which will schedule a recurring future until all
1335         // entries are cleared.
1336         if !is_discovering && self.freshness_check.is_none() {
1337             self.trigger_freshness_check();
1338         }
1339 
1340         // Start or stop BLE scanning based on discovering state
1341         if let Some(scanner_id) = self.ble_scanner_id {
1342             if is_discovering {
1343                 self.bluetooth_gatt.lock().unwrap().start_active_scan(scanner_id);
1344             } else {
1345                 self.bluetooth_gatt.lock().unwrap().stop_active_scan(scanner_id);
1346             }
1347         }
1348     }
1349 
ssp_request( &mut self, remote_addr: RawAddress, remote_name: String, cod: u32, variant: BtSspVariant, passkey: u32, )1350     fn ssp_request(
1351         &mut self,
1352         remote_addr: RawAddress,
1353         remote_name: String,
1354         cod: u32,
1355         variant: BtSspVariant,
1356         passkey: u32,
1357     ) {
1358         // Currently this supports many agent because we accept many callbacks.
1359         // TODO(b/274706838): We need a way to select the default agent.
1360         self.callbacks.for_all_callbacks(|callback| {
1361             callback.on_ssp_request(
1362                 BluetoothDevice::new(remote_addr.to_string(), remote_name.clone()),
1363                 cod,
1364                 variant.clone(),
1365                 passkey,
1366             );
1367         });
1368     }
1369 
pin_request( &mut self, remote_addr: RawAddress, remote_name: String, cod: u32, min_16_digit: bool, )1370     fn pin_request(
1371         &mut self,
1372         remote_addr: RawAddress,
1373         remote_name: String,
1374         cod: u32,
1375         min_16_digit: bool,
1376     ) {
1377         let device = BluetoothDevice::new(remote_addr.to_string(), remote_name.clone());
1378 
1379         let digits = match min_16_digit {
1380             true => 16,
1381             false => 6,
1382         };
1383 
1384         if is_cod_hid_keyboard(cod) || is_cod_hid_combo(cod) {
1385             debug!("auto gen pin for device {} (cod={:#x})", device.address, cod);
1386             // generate a random pin code to display.
1387             let pin = rand::random::<u64>() % pow(10, digits);
1388             let display_pin = format!("{:06}", pin);
1389 
1390             // Currently this supports many agent because we accept many callbacks.
1391             // TODO(b/274706838): We need a way to select the default agent.
1392             self.callbacks.for_all_callbacks(|callback| {
1393                 callback.on_pin_display(device.clone(), display_pin.clone());
1394             });
1395 
1396             let pin_vec = display_pin.chars().map(|d| d.try_into().unwrap()).collect::<Vec<u8>>();
1397 
1398             self.set_pin(device, true, pin_vec);
1399         } else {
1400             debug!("sending pin request for device {} (cod={:#x}) to clients", device.address, cod);
1401             // Currently this supports many agent because we accept many callbacks.
1402             // TODO(b/274706838): We need a way to select the default agent.
1403             self.callbacks.for_all_callbacks(|callback| {
1404                 callback.on_pin_request(device.clone(), cod, min_16_digit);
1405             });
1406         }
1407     }
1408 
bond_state( &mut self, status: BtStatus, addr: RawAddress, bond_state: BtBondState, fail_reason: i32, )1409     fn bond_state(
1410         &mut self,
1411         status: BtStatus,
1412         addr: RawAddress,
1413         bond_state: BtBondState,
1414         fail_reason: i32,
1415     ) {
1416         let address = addr.to_string();
1417 
1418         // Get the device type before the device is potentially deleted.
1419         let device_type =
1420             self.get_remote_type(BluetoothDevice::new(address.clone(), "".to_string()));
1421 
1422         // Easy case of not bonded -- we remove the device from the bonded list and change the bond
1423         // state in the found list (in case it was previously bonding).
1424         if &bond_state == &BtBondState::NotBonded {
1425             self.bonded_devices.remove(&address);
1426             self.found_devices
1427                 .entry(address.clone())
1428                 .and_modify(|d| d.bond_state = bond_state.clone());
1429         }
1430         // We will only insert into the bonded list after bonding is complete
1431         else if &bond_state == &BtBondState::Bonded && !self.bonded_devices.contains_key(&address)
1432         {
1433             // We either need to construct a new BluetoothDeviceContext or grab it from the found
1434             // devices map. Immediately insert that into the bonded list.
1435             let mut device = match self.found_devices.remove(&address) {
1436                 Some(mut v) => {
1437                     v.bond_state = bond_state.clone();
1438                     v
1439                 }
1440                 None => BluetoothDeviceContext::new(
1441                     bond_state.clone(),
1442                     BtAclState::Disconnected,
1443                     BluetoothDevice::new(address.clone(), "".to_string()),
1444                     Instant::now(),
1445                     vec![],
1446                 ),
1447             };
1448             let device_info = device.info.clone();
1449 
1450             // Since this is a newly bonded device, we also need to trigger SDP
1451             // on it.
1452             device.services_resolved = false;
1453             self.bonded_devices.insert(address.clone(), device);
1454             self.fetch_remote_uuids(device_info);
1455         } else {
1456             // If we're bonding, we need to update the found devices list
1457             self.found_devices
1458                 .entry(address.clone())
1459                 .and_modify(|d| d.bond_state = bond_state.clone());
1460         }
1461 
1462         // Resume discovery once the bonding process is complete. Discovery was paused before the
1463         // bond request to avoid ACL connection from interfering with active inquiry.
1464         if &bond_state == &BtBondState::NotBonded || &bond_state == &BtBondState::Bonded {
1465             self.resume_discovery();
1466         }
1467 
1468         // Send bond state changed notifications
1469         self.callbacks.for_all_callbacks(|callback| {
1470             callback.on_bond_state_changed(
1471                 status.to_u32().unwrap(),
1472                 address.clone(),
1473                 bond_state.to_u32().unwrap(),
1474             );
1475         });
1476 
1477         metrics::bond_state_changed(addr, device_type, status, bond_state, fail_reason);
1478     }
1479 
remote_device_properties_changed( &mut self, _status: BtStatus, addr: RawAddress, _num_properties: i32, properties: Vec<BluetoothProperty>, )1480     fn remote_device_properties_changed(
1481         &mut self,
1482         _status: BtStatus,
1483         addr: RawAddress,
1484         _num_properties: i32,
1485         properties: Vec<BluetoothProperty>,
1486     ) {
1487         let address = addr.to_string();
1488         let txl = self.tx.clone();
1489         let device = match self.get_remote_device_if_found_mut(&address) {
1490             None => {
1491                 self.found_devices.insert(
1492                     address.clone(),
1493                     BluetoothDeviceContext::new(
1494                         BtBondState::NotBonded,
1495                         BtAclState::Disconnected,
1496                         BluetoothDevice::new(address.clone(), String::from("")),
1497                         Instant::now(),
1498                         vec![],
1499                     ),
1500                 );
1501 
1502                 self.found_devices.get_mut(&address)
1503             }
1504             some => some,
1505         };
1506 
1507         match device {
1508             Some(d) => {
1509                 d.update_properties(&properties);
1510                 d.seen();
1511 
1512                 Bluetooth::send_metrics_remote_device_info(d);
1513 
1514                 let info = d.info.clone();
1515                 let has_uuids = d
1516                     .properties
1517                     .get(&BtPropertyType::Uuids)
1518                     .and_then(|prop| match prop {
1519                         BluetoothProperty::Uuids(uu) => Some(uu.len() > 0),
1520                         _ => None,
1521                     })
1522                     .map_or(false, |v| v);
1523 
1524                 // Services are resolved when uuids are fetched.
1525                 d.services_resolved = has_uuids;
1526 
1527                 if d.wait_to_connect && has_uuids {
1528                     d.wait_to_connect = false;
1529 
1530                     let sent_info = info.clone();
1531                     tokio::spawn(async move {
1532                         let _ = txl
1533                             .send(Message::DelayedAdapterActions(
1534                                 DelayedActions::ConnectAllProfiles(sent_info),
1535                             ))
1536                             .await;
1537                     });
1538                 }
1539 
1540                 self.bluetooth_admin
1541                     .lock()
1542                     .unwrap()
1543                     .on_remote_device_properties_changed(&info, &properties);
1544             }
1545             None => (),
1546         }
1547     }
1548 
acl_state( &mut self, status: BtStatus, addr: RawAddress, state: BtAclState, link_type: BtTransport, hci_reason: BtHciErrorCode, conn_direction: BtConnectionDirection, _acl_handle: u16, )1549     fn acl_state(
1550         &mut self,
1551         status: BtStatus,
1552         addr: RawAddress,
1553         state: BtAclState,
1554         link_type: BtTransport,
1555         hci_reason: BtHciErrorCode,
1556         conn_direction: BtConnectionDirection,
1557         _acl_handle: u16,
1558     ) {
1559         // If discovery was previously paused at connect_all_enabled_profiles to avoid an outgoing
1560         // ACL connection colliding with an ongoing inquiry, resume it.
1561         self.resume_discovery();
1562 
1563         if status != BtStatus::Success {
1564             warn!(
1565                 "Connection to [{}] failed. Status: {:?}, Reason: {:?}",
1566                 addr.to_string(),
1567                 status,
1568                 hci_reason
1569             );
1570             metrics::acl_connection_state_changed(
1571                 addr,
1572                 link_type,
1573                 status,
1574                 BtAclState::Disconnected,
1575                 conn_direction,
1576                 hci_reason,
1577             );
1578             return;
1579         }
1580 
1581         let address = addr.to_string();
1582         let device = match self.get_remote_device_if_found_mut(&address) {
1583             None => {
1584                 self.found_devices.insert(
1585                     address.clone(),
1586                     BluetoothDeviceContext::new(
1587                         BtBondState::NotBonded,
1588                         BtAclState::Disconnected,
1589                         BluetoothDevice::new(address.clone(), String::from("")),
1590                         Instant::now(),
1591                         vec![],
1592                     ),
1593                 );
1594 
1595                 self.found_devices.get_mut(&address)
1596             }
1597             some => some,
1598         };
1599 
1600         match device {
1601             Some(found) => {
1602                 // Only notify if there's been a change in state
1603                 let prev_state = &found.acl_state;
1604                 if prev_state != &state {
1605                     let device = found.info.clone();
1606                     found.acl_state = state.clone();
1607                     found.acl_reported_transport = link_type;
1608 
1609                     metrics::acl_connection_state_changed(
1610                         addr,
1611                         link_type,
1612                         BtStatus::Success,
1613                         state.clone(),
1614                         conn_direction,
1615                         hci_reason,
1616                     );
1617 
1618                     match state {
1619                         BtAclState::Connected => {
1620                             let bluetooth_device = found.info.clone();
1621                             let acl_reported_transport = found.acl_reported_transport.clone();
1622                             Bluetooth::send_metrics_remote_device_info(found);
1623                             self.connection_callbacks.for_all_callbacks(|callback| {
1624                                 callback.on_device_connected(device.clone());
1625                             });
1626                             let tx = self.tx.clone();
1627                             let transport = match self.get_remote_type(bluetooth_device.clone()) {
1628                                 BtDeviceType::Bredr => BtTransport::Bredr,
1629                                 BtDeviceType::Ble => BtTransport::Le,
1630                                 _ => acl_reported_transport,
1631                             };
1632                             tokio::spawn(async move {
1633                                 let _ = tx
1634                                     .send(Message::OnAclConnected(bluetooth_device, transport))
1635                                     .await;
1636                             });
1637                         }
1638                         BtAclState::Disconnected => {
1639                             self.connection_callbacks.for_all_callbacks(|callback| {
1640                                 callback.on_device_disconnected(device.clone());
1641                             });
1642                             let tx = self.tx.clone();
1643                             tokio::spawn(async move {
1644                                 let _ = tx.send(Message::OnAclDisconnected(device.clone())).await;
1645                             });
1646                         }
1647                     };
1648                 }
1649             }
1650             None => (),
1651         };
1652     }
1653 }
1654 
1655 struct BleDiscoveryCallbacks {
1656     tx: Sender<Message>,
1657 }
1658 
1659 impl BleDiscoveryCallbacks {
new(tx: Sender<Message>) -> Self1660     fn new(tx: Sender<Message>) -> Self {
1661         Self { tx }
1662     }
1663 }
1664 
1665 // Handle BLE scanner results.
1666 impl IScannerCallback for BleDiscoveryCallbacks {
on_scanner_registered(&mut self, uuid: Uuid128Bit, scanner_id: u8, status: GattStatus)1667     fn on_scanner_registered(&mut self, uuid: Uuid128Bit, scanner_id: u8, status: GattStatus) {
1668         let tx = self.tx.clone();
1669         tokio::spawn(async move {
1670             let _ = tx
1671                 .send(Message::DelayedAdapterActions(
1672                     DelayedActions::BleDiscoveryScannerRegistered(uuid, scanner_id, status),
1673                 ))
1674                 .await;
1675         });
1676     }
1677 
on_scan_result(&mut self, scan_result: ScanResult)1678     fn on_scan_result(&mut self, scan_result: ScanResult) {
1679         let tx = self.tx.clone();
1680         tokio::spawn(async move {
1681             let _ = tx
1682                 .send(Message::DelayedAdapterActions(DelayedActions::BleDiscoveryScannerResult(
1683                     scan_result,
1684                 )))
1685                 .await;
1686         });
1687     }
1688 
on_advertisement_found(&mut self, _scanner_id: u8, _scan_result: ScanResult)1689     fn on_advertisement_found(&mut self, _scanner_id: u8, _scan_result: ScanResult) {}
on_advertisement_lost(&mut self, _scanner_id: u8, _scan_result: ScanResult)1690     fn on_advertisement_lost(&mut self, _scanner_id: u8, _scan_result: ScanResult) {}
on_suspend_mode_change(&mut self, _suspend_mode: SuspendMode)1691     fn on_suspend_mode_change(&mut self, _suspend_mode: SuspendMode) {}
1692 }
1693 
1694 impl RPCProxy for BleDiscoveryCallbacks {
get_object_id(&self) -> String1695     fn get_object_id(&self) -> String {
1696         "BLE Discovery Callback".to_string()
1697     }
1698 }
1699 
1700 // TODO: Add unit tests for this implementation
1701 impl IBluetooth for Bluetooth {
register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>)1702     fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) {
1703         self.callbacks.add_callback(callback);
1704     }
1705 
register_connection_callback( &mut self, callback: Box<dyn IBluetoothConnectionCallback + Send>, ) -> u321706     fn register_connection_callback(
1707         &mut self,
1708         callback: Box<dyn IBluetoothConnectionCallback + Send>,
1709     ) -> u32 {
1710         self.connection_callbacks.add_callback(callback)
1711     }
1712 
unregister_connection_callback(&mut self, callback_id: u32) -> bool1713     fn unregister_connection_callback(&mut self, callback_id: u32) -> bool {
1714         self.connection_callbacks.remove_callback(callback_id)
1715     }
1716 
enable(&mut self) -> bool1717     fn enable(&mut self) -> bool {
1718         self.intf.lock().unwrap().enable() == 0
1719     }
1720 
disable(&mut self) -> bool1721     fn disable(&mut self) -> bool {
1722         self.intf.lock().unwrap().disable() == 0
1723     }
1724 
get_address(&self) -> String1725     fn get_address(&self) -> String {
1726         match self.local_address {
1727             None => String::from(""),
1728             Some(addr) => addr.to_string(),
1729         }
1730     }
1731 
get_uuids(&self) -> Vec<Uuid128Bit>1732     fn get_uuids(&self) -> Vec<Uuid128Bit> {
1733         match self.properties.get(&BtPropertyType::Uuids) {
1734             Some(prop) => match prop {
1735                 BluetoothProperty::Uuids(uuids) => {
1736                     uuids.iter().map(|&x| x.uu.clone()).collect::<Vec<Uuid128Bit>>()
1737                 }
1738                 _ => vec![],
1739             },
1740             _ => vec![],
1741         }
1742     }
1743 
get_name(&self) -> String1744     fn get_name(&self) -> String {
1745         match self.properties.get(&BtPropertyType::BdName) {
1746             Some(prop) => match prop {
1747                 BluetoothProperty::BdName(name) => name.clone(),
1748                 _ => String::new(),
1749             },
1750             _ => String::new(),
1751         }
1752     }
1753 
set_name(&self, name: String) -> bool1754     fn set_name(&self, name: String) -> bool {
1755         self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::BdName(name)) == 0
1756     }
1757 
get_bluetooth_class(&self) -> u321758     fn get_bluetooth_class(&self) -> u32 {
1759         match self.properties.get(&BtPropertyType::ClassOfDevice) {
1760             Some(prop) => match prop {
1761                 BluetoothProperty::ClassOfDevice(cod) => cod.clone(),
1762                 _ => 0,
1763             },
1764             _ => 0,
1765         }
1766     }
1767 
set_bluetooth_class(&self, cod: u32) -> bool1768     fn set_bluetooth_class(&self, cod: u32) -> bool {
1769         self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::ClassOfDevice(cod)) == 0
1770     }
1771 
get_discoverable(&self) -> bool1772     fn get_discoverable(&self) -> bool {
1773         match self.properties.get(&BtPropertyType::AdapterScanMode) {
1774             Some(prop) => match prop {
1775                 BluetoothProperty::AdapterScanMode(mode) => match mode {
1776                     BtScanMode::ConnectableDiscoverable => true,
1777                     _ => false,
1778                 },
1779                 _ => false,
1780             },
1781             _ => false,
1782         }
1783     }
1784 
get_discoverable_timeout(&self) -> u321785     fn get_discoverable_timeout(&self) -> u32 {
1786         match self.properties.get(&BtPropertyType::AdapterDiscoverableTimeout) {
1787             Some(prop) => match prop {
1788                 BluetoothProperty::AdapterDiscoverableTimeout(timeout) => timeout.clone(),
1789                 _ => 0,
1790             },
1791             _ => 0,
1792         }
1793     }
1794 
set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool1795     fn set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool {
1796         let intf = self.intf.lock().unwrap();
1797 
1798         // Checks if the duration is valid.
1799         if mode == BtDiscMode::LimitedDiscoverable && (duration > 60 || duration <= 0) {
1800             warn!("Invalid duration for setting the device into limited discoverable mode. The valid duration is 1~60 seconds.");
1801             return false;
1802         }
1803 
1804         let off_mode =
1805             if self.is_connectable { BtScanMode::Connectable } else { BtScanMode::None_ };
1806 
1807         let new_mode = match mode {
1808             BtDiscMode::LimitedDiscoverable => BtScanMode::ConnectableLimitedDiscoverable,
1809             BtDiscMode::GeneralDiscoverable => BtScanMode::ConnectableDiscoverable,
1810             BtDiscMode::NonDiscoverable => off_mode.clone(),
1811         };
1812 
1813         // The old timer should be overwritten regardless of what the new mode is.
1814         if let Some(ref handle) = self.discoverable_timeout {
1815             handle.abort();
1816             self.discoverable_timeout = None;
1817         }
1818 
1819         if intf.set_adapter_property(BluetoothProperty::AdapterDiscoverableTimeout(duration)) != 0
1820             || intf.set_adapter_property(BluetoothProperty::AdapterScanMode(new_mode)) != 0
1821         {
1822             return false;
1823         }
1824 
1825         if (mode != BtDiscMode::NonDiscoverable) && (duration != 0) {
1826             let intf_clone = self.intf.clone();
1827             self.discoverable_timeout = Some(tokio::spawn(async move {
1828                 time::sleep(Duration::from_secs(duration.into())).await;
1829                 intf_clone
1830                     .lock()
1831                     .unwrap()
1832                     .set_adapter_property(BluetoothProperty::AdapterScanMode(off_mode));
1833             }));
1834         }
1835 
1836         true
1837     }
1838 
is_multi_advertisement_supported(&self) -> bool1839     fn is_multi_advertisement_supported(&self) -> bool {
1840         match self.properties.get(&BtPropertyType::LocalLeFeatures) {
1841             Some(prop) => match prop {
1842                 BluetoothProperty::LocalLeFeatures(llf) => {
1843                     llf.max_adv_instance >= MIN_ADV_INSTANCES_FOR_MULTI_ADV
1844                 }
1845                 _ => false,
1846             },
1847             _ => false,
1848         }
1849     }
1850 
is_le_extended_advertising_supported(&self) -> bool1851     fn is_le_extended_advertising_supported(&self) -> bool {
1852         match self.properties.get(&BtPropertyType::LocalLeFeatures) {
1853             Some(prop) => match prop {
1854                 BluetoothProperty::LocalLeFeatures(llf) => llf.le_extended_advertising_supported,
1855                 _ => false,
1856             },
1857             _ => false,
1858         }
1859     }
1860 
start_discovery(&mut self) -> bool1861     fn start_discovery(&mut self) -> bool {
1862         // Short-circuit to avoid sending multiple start discovery calls.
1863         if self.is_discovering {
1864             return true;
1865         }
1866 
1867         // Short-circuit if paused and add the discovery intent to the queue.
1868         if self.is_discovery_paused {
1869             self.pending_discovery = true;
1870             debug!("Queue the discovery request during paused state");
1871             return true;
1872         }
1873 
1874         let discovery_suspend_mode = self.get_discovery_suspend_mode();
1875         if discovery_suspend_mode != SuspendMode::Normal
1876             && discovery_suspend_mode != SuspendMode::Resuming
1877         {
1878             log::warn!("start_discovery is not allowed when suspending or suspended.");
1879             return false;
1880         }
1881 
1882         self.intf.lock().unwrap().start_discovery() == 0
1883     }
1884 
cancel_discovery(&mut self) -> bool1885     fn cancel_discovery(&mut self) -> bool {
1886         // Client no longer want to discover, clear the request
1887         if self.is_discovery_paused {
1888             self.pending_discovery = false;
1889             debug!("Cancel the discovery request during paused state");
1890         }
1891 
1892         // Reject the cancel discovery request if the underlying stack is not in a discovering
1893         // state. For example, previous start discovery was enqueued for ongoing discovery.
1894         if !self.is_discovering {
1895             debug!("Reject cancel_discovery as it's not in discovering state.");
1896             return false;
1897         }
1898 
1899         let discovery_suspend_mode = self.get_discovery_suspend_mode();
1900         if discovery_suspend_mode != SuspendMode::Normal
1901             && discovery_suspend_mode != SuspendMode::Suspending
1902         {
1903             log::warn!("cancel_discovery is not allowed when resuming or suspended.");
1904             return false;
1905         }
1906 
1907         self.intf.lock().unwrap().cancel_discovery() == 0
1908     }
1909 
is_discovering(&self) -> bool1910     fn is_discovering(&self) -> bool {
1911         self.is_discovering
1912     }
1913 
get_discovery_end_millis(&self) -> u641914     fn get_discovery_end_millis(&self) -> u64 {
1915         if !self.is_discovering {
1916             return 0;
1917         }
1918 
1919         let elapsed_ms = self.discovering_started.elapsed().as_millis() as u64;
1920         if elapsed_ms >= DEFAULT_DISCOVERY_TIMEOUT_MS {
1921             0
1922         } else {
1923             DEFAULT_DISCOVERY_TIMEOUT_MS - elapsed_ms
1924         }
1925     }
1926 
create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> bool1927     fn create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> bool {
1928         let addr = RawAddress::from_string(device.address.clone());
1929 
1930         if addr.is_none() {
1931             metrics::bond_create_attempt(RawAddress::default(), BtDeviceType::Unknown);
1932             metrics::bond_state_changed(
1933                 RawAddress::default(),
1934                 BtDeviceType::Unknown,
1935                 BtStatus::InvalidParam,
1936                 BtBondState::NotBonded,
1937                 0,
1938             );
1939             warn!("Can't create bond. Address {} is not valid", device.address);
1940             return false;
1941         }
1942 
1943         let address = addr.unwrap();
1944         let device_type = match transport {
1945             BtTransport::Bredr => BtDeviceType::Bredr,
1946             BtTransport::Le => BtDeviceType::Ble,
1947             _ => self.get_remote_type(device.clone()),
1948         };
1949 
1950         // We explicitly log the attempt to start the bonding separate from logging the bond state.
1951         // The start of the attempt is critical to help identify a bonding/pairing session.
1952         metrics::bond_create_attempt(address, device_type.clone());
1953 
1954         // BREDR connection won't work when Inquiry is in progress.
1955         self.pause_discovery();
1956         let status = self.intf.lock().unwrap().create_bond(&address, transport);
1957 
1958         if status != 0 {
1959             metrics::bond_state_changed(
1960                 address,
1961                 device_type,
1962                 BtStatus::from(status as u32),
1963                 BtBondState::NotBonded,
1964                 0,
1965             );
1966             return false;
1967         }
1968 
1969         // Creating bond automatically create ACL connection as well, therefore also log metrics
1970         // ACL connection attempt here.
1971         let is_connected = self
1972             .get_remote_device_if_found(&device.address)
1973             .map_or(false, |d| d.acl_state == BtAclState::Connected);
1974         if !is_connected {
1975             metrics::acl_connect_attempt(address, BtAclState::Connected);
1976         }
1977 
1978         return true;
1979     }
1980 
cancel_bond_process(&self, device: BluetoothDevice) -> bool1981     fn cancel_bond_process(&self, device: BluetoothDevice) -> bool {
1982         let addr = RawAddress::from_string(device.address.clone());
1983 
1984         if addr.is_none() {
1985             warn!("Can't cancel bond. Address {} is not valid.", device.address);
1986             return false;
1987         }
1988 
1989         let address = addr.unwrap();
1990         self.intf.lock().unwrap().cancel_bond(&address) == 0
1991     }
1992 
remove_bond(&self, device: BluetoothDevice) -> bool1993     fn remove_bond(&self, device: BluetoothDevice) -> bool {
1994         // Temporary for debugging b/255849761. Should change to debug after fix.
1995         log::info!("Removing bond for {}", device.address);
1996 
1997         let addr = RawAddress::from_string(device.address.clone());
1998 
1999         if addr.is_none() {
2000             warn!("Can't remove bond. Address {} is not valid.", device.address);
2001             return false;
2002         }
2003 
2004         let address = addr.unwrap();
2005         let status = self.intf.lock().unwrap().remove_bond(&address);
2006 
2007         if status != 0 {
2008             return false;
2009         }
2010 
2011         // Removing bond also disconnects the ACL if is connected. Therefore, also log ACL
2012         // disconnection attempt here.
2013         let is_connected = self
2014             .get_remote_device_if_found(&device.address)
2015             .map_or(false, |d| d.acl_state == BtAclState::Connected);
2016         if is_connected {
2017             metrics::acl_connect_attempt(address, BtAclState::Disconnected);
2018         }
2019 
2020         return true;
2021     }
2022 
get_bonded_devices(&self) -> Vec<BluetoothDevice>2023     fn get_bonded_devices(&self) -> Vec<BluetoothDevice> {
2024         let mut devices: Vec<BluetoothDevice> = vec![];
2025 
2026         for (_, device) in self.bonded_devices.iter() {
2027             devices.push(device.info.clone());
2028         }
2029 
2030         devices
2031     }
2032 
get_bond_state(&self, device: BluetoothDevice) -> BtBondState2033     fn get_bond_state(&self, device: BluetoothDevice) -> BtBondState {
2034         self.get_bond_state_by_addr(&device.address)
2035     }
2036 
set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool2037     fn set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool {
2038         let addr = RawAddress::from_string(device.address.clone());
2039 
2040         if addr.is_none() {
2041             warn!("Can't set pin. Address {} is not valid.", device.address);
2042             return false;
2043         }
2044 
2045         let is_bonding = match self.found_devices.get(&device.address) {
2046             Some(d) => d.bond_state == BtBondState::Bonding,
2047             None => false,
2048         };
2049 
2050         if !is_bonding {
2051             warn!("Can't set pin. Device {} isn't bonding.", device.address);
2052             return false;
2053         }
2054 
2055         let mut btpin = BtPinCode { pin: array_utils::to_sized_array(&pin_code) };
2056 
2057         self.intf.lock().unwrap().pin_reply(
2058             &addr.unwrap(),
2059             accept as u8,
2060             pin_code.len() as u8,
2061             &mut btpin,
2062         ) == 0
2063     }
2064 
set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool2065     fn set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool {
2066         let addr = RawAddress::from_string(device.address.clone());
2067 
2068         if addr.is_none() {
2069             warn!("Can't set passkey. Address {} is not valid.", device.address);
2070             return false;
2071         }
2072 
2073         let is_bonding = match self.found_devices.get(&device.address) {
2074             Some(d) => d.bond_state == BtBondState::Bonding,
2075             None => false,
2076         };
2077 
2078         if !is_bonding {
2079             warn!("Can't set passkey. Device {} isn't bonding.", device.address);
2080             return false;
2081         }
2082 
2083         let mut tmp: [u8; 4] = [0; 4];
2084         tmp.copy_from_slice(passkey.as_slice());
2085         let passkey = u32::from_ne_bytes(tmp);
2086 
2087         self.intf.lock().unwrap().ssp_reply(
2088             &addr.unwrap(),
2089             BtSspVariant::PasskeyEntry,
2090             accept as u8,
2091             passkey,
2092         ) == 0
2093     }
2094 
set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool2095     fn set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool {
2096         let addr = RawAddress::from_string(device.address.clone());
2097 
2098         if addr.is_none() {
2099             warn!("Can't set pairing confirmation. Address {} is not valid.", device.address);
2100             return false;
2101         }
2102 
2103         self.intf.lock().unwrap().ssp_reply(
2104             &addr.unwrap(),
2105             BtSspVariant::PasskeyConfirmation,
2106             accept as u8,
2107             0,
2108         ) == 0
2109     }
2110 
get_remote_name(&self, device: BluetoothDevice) -> String2111     fn get_remote_name(&self, device: BluetoothDevice) -> String {
2112         match self.get_remote_device_property(&device, &BtPropertyType::BdName) {
2113             Some(BluetoothProperty::BdName(name)) => return name.clone(),
2114             _ => return "".to_string(),
2115         }
2116     }
2117 
get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType2118     fn get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType {
2119         match self.get_remote_device_property(&device, &BtPropertyType::TypeOfDevice) {
2120             Some(BluetoothProperty::TypeOfDevice(device_type)) => return device_type,
2121             _ => return BtDeviceType::Unknown,
2122         }
2123     }
2124 
get_remote_alias(&self, device: BluetoothDevice) -> String2125     fn get_remote_alias(&self, device: BluetoothDevice) -> String {
2126         match self.get_remote_device_property(&device, &BtPropertyType::RemoteFriendlyName) {
2127             Some(BluetoothProperty::RemoteFriendlyName(name)) => return name.clone(),
2128             _ => "".to_string(),
2129         }
2130     }
2131 
set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String)2132     fn set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String) {
2133         let _ = self.set_remote_device_property(
2134             &device,
2135             BtPropertyType::RemoteFriendlyName,
2136             BluetoothProperty::RemoteFriendlyName(new_alias),
2137         );
2138     }
2139 
get_remote_class(&self, device: BluetoothDevice) -> u322140     fn get_remote_class(&self, device: BluetoothDevice) -> u32 {
2141         match self.get_remote_device_property(&device, &BtPropertyType::ClassOfDevice) {
2142             Some(BluetoothProperty::ClassOfDevice(class)) => return class,
2143             _ => 0,
2144         }
2145     }
2146 
get_remote_appearance(&self, device: BluetoothDevice) -> u162147     fn get_remote_appearance(&self, device: BluetoothDevice) -> u16 {
2148         match self.get_remote_device_property(&device, &BtPropertyType::Appearance) {
2149             Some(BluetoothProperty::Appearance(appearance)) => appearance,
2150             _ => 0,
2151         }
2152     }
2153 
get_remote_connected(&self, device: BluetoothDevice) -> bool2154     fn get_remote_connected(&self, device: BluetoothDevice) -> bool {
2155         self.get_connection_state(device) != BtConnectionState::NotConnected
2156     }
2157 
get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool2158     fn get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool {
2159         // Wake is allowed if the device supports HIDP or HOGP only.
2160         match self.get_remote_device_property(&device, &BtPropertyType::Uuids) {
2161             Some(BluetoothProperty::Uuids(uuids)) => {
2162                 return uuids.iter().any(|&x| {
2163                     UuidHelper::is_known_profile(&x.uu).map_or(false, |profile| {
2164                         profile == Profile::Hid || profile == Profile::Hogp
2165                     })
2166                 });
2167             }
2168             _ => false,
2169         }
2170     }
2171 
get_connected_devices(&self) -> Vec<BluetoothDevice>2172     fn get_connected_devices(&self) -> Vec<BluetoothDevice> {
2173         let bonded_connected: HashMap<String, BluetoothDevice> = self
2174             .bonded_devices
2175             .iter()
2176             .filter(|(_, v)| v.acl_state == BtAclState::Connected)
2177             .map(|(k, v)| (k.clone(), v.info.clone()))
2178             .collect();
2179         let mut found_connected: Vec<BluetoothDevice> = self
2180             .found_devices
2181             .iter()
2182             .filter(|(k, v)| {
2183                 v.acl_state == BtAclState::Connected
2184                     && !bonded_connected.contains_key(&k.to_string())
2185             })
2186             .map(|(_, v)| v.info.clone())
2187             .collect();
2188 
2189         let mut all =
2190             bonded_connected.iter().map(|(_, v)| v.clone()).collect::<Vec<BluetoothDevice>>();
2191         all.append(&mut found_connected);
2192 
2193         all
2194     }
2195 
get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState2196     fn get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState {
2197         let addr = RawAddress::from_string(device.address.clone());
2198 
2199         if addr.is_none() {
2200             warn!("Can't check connection state. Address {} is not valid.", device.address);
2201             return BtConnectionState::NotConnected;
2202         }
2203 
2204         // The underlying api adds whether this is ENCRYPTED_BREDR or ENCRYPTED_LE.
2205         // As long as it is non-zero, it is connected.
2206         self.intf.lock().unwrap().get_connection_state(&addr.unwrap())
2207     }
2208 
get_profile_connection_state(&self, profile: Uuid128Bit) -> ProfileConnectionState2209     fn get_profile_connection_state(&self, profile: Uuid128Bit) -> ProfileConnectionState {
2210         if let Some(known) = UuidHelper::is_known_profile(&profile) {
2211             match known {
2212                 Profile::A2dpSink | Profile::A2dpSource => {
2213                     self.bluetooth_media.lock().unwrap().get_a2dp_connection_state()
2214                 }
2215                 Profile::Hfp | Profile::HfpAg => {
2216                     self.bluetooth_media.lock().unwrap().get_hfp_connection_state()
2217                 }
2218                 // TODO: (b/223431229) Profile::Hid and Profile::Hogp
2219                 _ => ProfileConnectionState::Disconnected,
2220             }
2221         } else {
2222             ProfileConnectionState::Disconnected
2223         }
2224     }
2225 
get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid128Bit>2226     fn get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid128Bit> {
2227         match self.get_remote_device_property(&device, &BtPropertyType::Uuids) {
2228             Some(BluetoothProperty::Uuids(uuids)) => {
2229                 return uuids.iter().map(|&x| x.uu.clone()).collect::<Vec<Uuid128Bit>>()
2230             }
2231             _ => return vec![],
2232         }
2233     }
2234 
fetch_remote_uuids(&self, remote_device: BluetoothDevice) -> bool2235     fn fetch_remote_uuids(&self, remote_device: BluetoothDevice) -> bool {
2236         let device = match self.get_remote_device_if_found(&remote_device.address) {
2237             Some(v) => v,
2238             None => {
2239                 warn!("Won't fetch UUIDs on unknown device {}", remote_device.address);
2240                 return false;
2241             }
2242         };
2243 
2244         let mut addr = match RawAddress::from_string(device.info.address.clone()) {
2245             Some(v) => v,
2246             None => {
2247                 warn!("Can't fetch UUIDs. Address {} is not valid.", device.info.address);
2248                 return false;
2249             }
2250         };
2251 
2252         let transport = match self.get_remote_type(device.info.clone()) {
2253             BtDeviceType::Bredr => BtTransport::Bredr,
2254             BtDeviceType::Ble => BtTransport::Le,
2255             _ => device.acl_reported_transport,
2256         };
2257 
2258         self.intf.lock().unwrap().get_remote_services(&mut addr, transport) == 0
2259     }
2260 
sdp_search(&self, device: BluetoothDevice, uuid: Uuid128Bit) -> bool2261     fn sdp_search(&self, device: BluetoothDevice, uuid: Uuid128Bit) -> bool {
2262         if self.sdp.is_none() {
2263             warn!("SDP is not initialized. Can't do SDP search.");
2264             return false;
2265         }
2266 
2267         let addr = RawAddress::from_string(device.address.clone());
2268         if addr.is_none() {
2269             warn!("Can't SDP search. Address {} is not valid.", device.address);
2270             return false;
2271         }
2272 
2273         let uu = Uuid::from(uuid);
2274         self.sdp.as_ref().unwrap().sdp_search(&mut addr.unwrap(), &uu) == BtStatus::Success
2275     }
2276 
create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool2277     fn create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool {
2278         let mut handle: i32 = -1;
2279         let mut sdp_record = sdp_record;
2280         match self.sdp.as_ref().unwrap().create_sdp_record(&mut sdp_record, &mut handle) {
2281             BtStatus::Success => {
2282                 let record_clone = sdp_record.clone();
2283                 self.callbacks.for_all_callbacks(|callback| {
2284                     callback.on_sdp_record_created(record_clone.clone(), handle);
2285                 });
2286                 true
2287             }
2288             _ => false,
2289         }
2290     }
2291 
remove_sdp_record(&self, handle: i32) -> bool2292     fn remove_sdp_record(&self, handle: i32) -> bool {
2293         self.sdp.as_ref().unwrap().remove_sdp_record(handle) == BtStatus::Success
2294     }
2295 
connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool2296     fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool {
2297         // Profile init must be complete before this api is callable
2298         if !self.profiles_ready {
2299             return false;
2300         }
2301 
2302         let mut addr = match RawAddress::from_string(device.address.clone()) {
2303             Some(v) => v,
2304             None => {
2305                 warn!("Can't connect profiles on invalid address [{}]", &device.address);
2306                 return false;
2307             }
2308         };
2309 
2310         let is_connected = self
2311             .get_remote_device_if_found(&device.address)
2312             .map_or(false, |d| d.acl_state == BtAclState::Connected);
2313         if !is_connected {
2314             // log ACL connection attempt if it's not already connected.
2315             metrics::acl_connect_attempt(addr, BtAclState::Connected);
2316             // Pause discovery before connecting, or the ACL connection request may conflict with
2317             // the ongoing inquiry.
2318             self.pause_discovery();
2319         }
2320 
2321         // Check all remote uuids to see if they match enabled profiles and connect them.
2322         let mut has_enabled_uuids = false;
2323         let mut has_media_profile = false;
2324         let mut has_supported_profile = false;
2325         let uuids = self.get_remote_uuids(device.clone());
2326         for uuid in uuids.iter() {
2327             match UuidHelper::is_known_profile(uuid) {
2328                 Some(p) => {
2329                     if UuidHelper::is_profile_supported(&p) {
2330                         match p {
2331                             Profile::Hid | Profile::Hogp => {
2332                                 has_supported_profile = true;
2333                                 let status = self.hh.as_ref().unwrap().connect(&mut addr);
2334                                 metrics::profile_connection_state_changed(
2335                                     addr,
2336                                     p as u32,
2337                                     BtStatus::Success,
2338                                     BthhConnectionState::Connecting as u32,
2339                                 );
2340 
2341                                 if status != BtStatus::Success {
2342                                     metrics::profile_connection_state_changed(
2343                                         addr,
2344                                         p as u32,
2345                                         status,
2346                                         BthhConnectionState::Disconnected as u32,
2347                                     );
2348                                 }
2349                             }
2350 
2351                             Profile::A2dpSink | Profile::A2dpSource | Profile::Hfp
2352                                 if !has_media_profile =>
2353                             {
2354                                 has_supported_profile = true;
2355                                 has_media_profile = true;
2356                                 let txl = self.tx.clone();
2357                                 let address = device.address.clone();
2358                                 topstack::get_runtime().spawn(async move {
2359                                     let _ = txl
2360                                         .send(Message::Media(MediaActions::Connect(address)))
2361                                         .await;
2362                                 });
2363                             }
2364 
2365                             Profile::Bas => {
2366                                 has_supported_profile = true;
2367                                 let tx = self.tx.clone();
2368                                 let transport =
2369                                     match self.get_remote_device_if_found(&device.address) {
2370                                         Some(context) => context.acl_reported_transport,
2371                                         None => return false,
2372                                     };
2373                                 let device_to_send = device.clone();
2374                                 let transport = match self.get_remote_type(device.clone()) {
2375                                     BtDeviceType::Bredr => BtTransport::Bredr,
2376                                     BtDeviceType::Ble => BtTransport::Le,
2377                                     _ => transport,
2378                                 };
2379                                 topstack::get_runtime().spawn(async move {
2380                                     let _ = tx
2381                                         .send(Message::BatteryService(
2382                                             BatteryServiceActions::Connect(
2383                                                 device_to_send,
2384                                                 transport,
2385                                             ),
2386                                         ))
2387                                         .await;
2388                                 });
2389                             }
2390 
2391                             // We don't connect most profiles
2392                             _ => (),
2393                         }
2394                     }
2395                     has_enabled_uuids = true;
2396                 }
2397                 _ => {}
2398             }
2399         }
2400 
2401         // If SDP isn't completed yet, we wait for it to complete and retry the connection again.
2402         // Otherwise, this connection request is done, no retry is required.
2403         if !has_enabled_uuids {
2404             warn!("[{}] SDP hasn't completed for device, wait to connect.", DisplayAddress(&addr));
2405             if let Some(d) = self.get_remote_device_if_found_mut(&device.address) {
2406                 if uuids.len() == 0 || !d.services_resolved {
2407                     d.wait_to_connect = true;
2408                 }
2409             }
2410         }
2411 
2412         // If the SDP has not been completed or the device does not have a profile that we are
2413         // interested in connecting to, resume discovery now. Other cases will be handled in the
2414         // ACL connection state or bond state callbacks.
2415         if !has_enabled_uuids || !has_supported_profile {
2416             self.resume_discovery();
2417         }
2418 
2419         return true;
2420     }
2421 
disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool2422     fn disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool {
2423         if !self.profiles_ready {
2424             return false;
2425         }
2426 
2427         let addr = RawAddress::from_string(device.address.clone());
2428         if addr.is_none() {
2429             warn!("Can't connect profiles on invalid address [{}]", &device.address);
2430             return false;
2431         }
2432 
2433         // log ACL disconnection attempt if it's not already disconnected.
2434         let is_connected = self
2435             .get_remote_device_if_found(&device.address)
2436             .map_or(false, |d| d.acl_state == BtAclState::Connected);
2437         if is_connected {
2438             metrics::acl_connect_attempt(addr.unwrap(), BtAclState::Disconnected);
2439         }
2440 
2441         let uuids = self.get_remote_uuids(device.clone());
2442         let mut has_media_profile = false;
2443         for uuid in uuids.iter() {
2444             match UuidHelper::is_known_profile(uuid) {
2445                 Some(p) => {
2446                     if UuidHelper::is_profile_supported(&p) {
2447                         match p {
2448                             Profile::Hid | Profile::Hogp => {
2449                                 self.hh.as_ref().unwrap().disconnect(&mut addr.unwrap());
2450                             }
2451 
2452                             Profile::A2dpSink
2453                             | Profile::A2dpSource
2454                             | Profile::Hfp
2455                             | Profile::AvrcpController
2456                                 if !has_media_profile =>
2457                             {
2458                                 has_media_profile = true;
2459                                 let txl = self.tx.clone();
2460                                 let address = device.address.clone();
2461                                 topstack::get_runtime().spawn(async move {
2462                                     let _ = txl
2463                                         .send(Message::Media(MediaActions::Disconnect(address)))
2464                                         .await;
2465                                 });
2466                             }
2467 
2468                             Profile::Bas => {
2469                                 let tx = self.tx.clone();
2470                                 let device_to_send = device.clone();
2471                                 topstack::get_runtime().spawn(async move {
2472                                     let _ = tx
2473                                         .send(Message::BatteryService(
2474                                             BatteryServiceActions::Disconnect(device_to_send),
2475                                         ))
2476                                         .await;
2477                                 });
2478                             }
2479 
2480                             // We don't connect most profiles
2481                             _ => (),
2482                         }
2483                     }
2484                 }
2485                 _ => {}
2486             }
2487         }
2488 
2489         return true;
2490     }
2491 
is_wbs_supported(&self) -> bool2492     fn is_wbs_supported(&self) -> bool {
2493         self.intf.lock().unwrap().get_wbs_supported()
2494     }
2495 
is_swb_supported(&self) -> bool2496     fn is_swb_supported(&self) -> bool {
2497         self.intf.lock().unwrap().get_swb_supported()
2498     }
2499 }
2500 
2501 impl BtifSdpCallbacks for Bluetooth {
sdp_search( &mut self, status: BtStatus, address: RawAddress, uuid: Uuid, _count: i32, records: Vec<BtSdpRecord>, )2502     fn sdp_search(
2503         &mut self,
2504         status: BtStatus,
2505         address: RawAddress,
2506         uuid: Uuid,
2507         _count: i32,
2508         records: Vec<BtSdpRecord>,
2509     ) {
2510         let uuid_to_send = match UuidHelper::from_string(uuid.to_string()) {
2511             Some(uu) => uu,
2512             None => return,
2513         };
2514         let device_info = match self.get_remote_device_info_if_found(&address.to_string()) {
2515             Some(info) => info,
2516             None => BluetoothDevice::new(address.to_string(), "".to_string()),
2517         };
2518 
2519         // The SDP records we get back do not populate the UUID so we populate it ourselves before
2520         // sending them on.
2521         let mut records = records;
2522         records.iter_mut().for_each(|record| {
2523             match record {
2524                 BtSdpRecord::HeaderOverlay(header) => header.uuid = uuid.clone(),
2525                 BtSdpRecord::MapMas(record) => record.hdr.uuid = uuid.clone(),
2526                 BtSdpRecord::MapMns(record) => record.hdr.uuid = uuid.clone(),
2527                 BtSdpRecord::PbapPse(record) => record.hdr.uuid = uuid.clone(),
2528                 BtSdpRecord::PbapPce(record) => record.hdr.uuid = uuid.clone(),
2529                 BtSdpRecord::OppServer(record) => record.hdr.uuid = uuid.clone(),
2530                 BtSdpRecord::SapServer(record) => record.hdr.uuid = uuid.clone(),
2531                 BtSdpRecord::Dip(record) => record.hdr.uuid = uuid.clone(),
2532                 BtSdpRecord::Mps(record) => record.hdr.uuid = uuid.clone(),
2533             };
2534         });
2535         self.callbacks.for_all_callbacks(|callback| {
2536             callback.on_sdp_search_complete(device_info.clone(), uuid_to_send, records.clone());
2537         });
2538         debug!(
2539             "Sdp search result found: Status({:?}) Address({:?}) Uuid({:?})",
2540             status, address, uuid
2541         );
2542     }
2543 }
2544 
2545 impl BtifHHCallbacks for Bluetooth {
connection_state(&mut self, mut address: RawAddress, state: BthhConnectionState)2546     fn connection_state(&mut self, mut address: RawAddress, state: BthhConnectionState) {
2547         debug!("Hid host connection state updated: Address({:?}) State({:?})", address, state);
2548 
2549         // HID or HOG is not differentiated by the hid host when callback this function. Assume HOG
2550         // if the device is LE only and HID if classic only. And assume HOG if UUID said so when
2551         // device type is dual or unknown.
2552         let device = BluetoothDevice::new(address.to_string(), "".to_string());
2553         let profile = match self.get_remote_type(device.clone()) {
2554             BtDeviceType::Ble => Profile::Hogp,
2555             BtDeviceType::Bredr => Profile::Hid,
2556             _ => {
2557                 if self.get_remote_uuids(device).contains(&UuidHelper::from_string(HOGP).unwrap()) {
2558                     Profile::Hogp
2559                 } else {
2560                     Profile::Hid
2561                 }
2562             }
2563         };
2564 
2565         metrics::profile_connection_state_changed(
2566             address,
2567             profile as u32,
2568             BtStatus::Success,
2569             state as u32,
2570         );
2571 
2572         if BtBondState::Bonded != self.get_bond_state_by_addr(&address.to_string()) {
2573             warn!(
2574                 "[{}]: Rejecting a unbonded device's attempt to connect to HID/HOG profiles",
2575                 DisplayAddress(&address)
2576             );
2577             self.hh.as_ref().unwrap().disconnect(&mut address);
2578         }
2579     }
2580 
hid_info(&mut self, address: RawAddress, info: BthhHidInfo)2581     fn hid_info(&mut self, address: RawAddress, info: BthhHidInfo) {
2582         debug!("Hid host info updated: Address({:?}) Info({:?})", address, info);
2583     }
2584 
protocol_mode(&mut self, address: RawAddress, status: BthhStatus, mode: BthhProtocolMode)2585     fn protocol_mode(&mut self, address: RawAddress, status: BthhStatus, mode: BthhProtocolMode) {
2586         debug!(
2587             "Hid host protocol mode updated: Address({:?}) Status({:?}) Mode({:?})",
2588             address, status, mode
2589         );
2590     }
2591 
idle_time(&mut self, address: RawAddress, status: BthhStatus, idle_rate: i32)2592     fn idle_time(&mut self, address: RawAddress, status: BthhStatus, idle_rate: i32) {
2593         debug!(
2594             "Hid host idle time updated: Address({:?}) Status({:?}) Idle Rate({:?})",
2595             address, status, idle_rate
2596         );
2597     }
2598 
get_report( &mut self, mut address: RawAddress, status: BthhStatus, mut data: Vec<u8>, size: i32, )2599     fn get_report(
2600         &mut self,
2601         mut address: RawAddress,
2602         status: BthhStatus,
2603         mut data: Vec<u8>,
2604         size: i32,
2605     ) {
2606         debug!(
2607             "Hid host got report: Address({:?}) Status({:?}) Report Size({:?})",
2608             address, status, size
2609         );
2610         self.hh.as_ref().unwrap().get_report_reply(&mut address, status, &mut data, size as u16);
2611     }
2612 
handshake(&mut self, address: RawAddress, status: BthhStatus)2613     fn handshake(&mut self, address: RawAddress, status: BthhStatus) {
2614         debug!("Hid host handshake: Address({:?}) Status({:?})", address, status);
2615     }
2616 }
2617 
2618 impl IBluetoothQALegacy for Bluetooth {
get_connectable(&self) -> bool2619     fn get_connectable(&self) -> bool {
2620         self.get_connectable_internal()
2621     }
2622 
set_connectable(&mut self, mode: bool) -> bool2623     fn set_connectable(&mut self, mode: bool) -> bool {
2624         self.set_connectable_internal(mode)
2625     }
2626 
get_alias(&self) -> String2627     fn get_alias(&self) -> String {
2628         let name = self.get_name();
2629         if !name.is_empty() {
2630             return name;
2631         }
2632 
2633         // If the adapter name is empty, generate one based on local BDADDR
2634         // so that test programs can have a friendly name for the adapter.
2635         match self.local_address {
2636             None => "floss_0000".to_string(),
2637             Some(addr) => format!("floss_{:02X}{:02X}", addr.address[4], addr.address[5]),
2638         }
2639     }
2640 
get_modalias(&self) -> String2641     fn get_modalias(&self) -> String {
2642         format!("bluetooth:v00E0pC405d{:04x}", FLOSS_VER)
2643     }
2644 
get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus2645     fn get_hid_report(
2646         &mut self,
2647         addr: String,
2648         report_type: BthhReportType,
2649         report_id: u8,
2650     ) -> BtStatus {
2651         if let Some(mut addr) = RawAddress::from_string(addr) {
2652             self.hh.as_mut().unwrap().get_report(&mut addr, report_type, report_id, 128)
2653         } else {
2654             BtStatus::InvalidParam
2655         }
2656     }
2657 
set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus2658     fn set_hid_report(
2659         &mut self,
2660         addr: String,
2661         report_type: BthhReportType,
2662         report: String,
2663     ) -> BtStatus {
2664         if let Some(mut addr) = RawAddress::from_string(addr) {
2665             let mut rb = report.clone().into_bytes();
2666             self.hh.as_mut().unwrap().set_report(&mut addr, report_type, rb.as_mut_slice())
2667         } else {
2668             BtStatus::InvalidParam
2669         }
2670     }
2671 
send_hid_data(&mut self, addr: String, data: String) -> BtStatus2672     fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus {
2673         if let Some(mut addr) = RawAddress::from_string(addr) {
2674             let mut rb = data.clone().into_bytes();
2675             self.hh.as_mut().unwrap().send_data(&mut addr, rb.as_mut_slice())
2676         } else {
2677             BtStatus::InvalidParam
2678         }
2679     }
2680 }
2681