Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59853096 authored by Hsin-chen Chuang's avatar Hsin-chen Chuang Committed by Gerrit Code Review
Browse files

Merge "floss: Decouple set connect/discoverable functions and revise the...

Merge "floss: Decouple set connect/discoverable functions and revise the suspend/resume code" into main
parents 2ad1194e 16f4a760
Loading
Loading
Loading
Loading
+134 −43
Original line number Diff line number Diff line
@@ -309,8 +309,12 @@ pub enum DelayedActions {
    /// Scanner for BLE discovery is reporting a result.
    BleDiscoveryScannerResult(ScanResult),

    /// Update the connectable mode to allow or disallow classic reconnect
    /// Update the connectable mode to allow or disallow classic reconnect.
    /// Parameter: Whether or not there are Classic listening sockets
    UpdateConnectableMode(bool),

    /// Reset the discoverable mode to BtDiscMode::NonDiscoverable.
    ResetDiscoverable,
}

/// Serializable device used in various apis.
@@ -523,6 +527,10 @@ pub struct Bluetooth {
    discovering_started: Instant,
    hh: Option<HidHost>,
    is_connectable: bool,
    discoverable_mode: BtDiscMode,
    // This refers to the suspend mode of the functionality related to Classic scan mode,
    // i.e., page scan and inquiry scan; Also known as connectable and discoverable.
    scan_suspend_mode: SuspendMode,
    is_discovering: bool,
    is_discovering_before_suspend: bool,
    is_discovery_paused: bool,
@@ -581,6 +589,8 @@ impl Bluetooth {
            discovering_started: Instant::now(),
            intf,
            is_connectable: false,
            discoverable_mode: BtDiscMode::NonDiscoverable,
            scan_suspend_mode: SuspendMode::Normal,
            is_discovering: false,
            is_discovering_before_suspend: false,
            is_discovery_paused: false,
@@ -628,6 +638,9 @@ impl Bluetooth {
    }

    fn trigger_update_connectable_mode(&self) {
        if self.get_scan_suspend_mode() != SuspendMode::Normal {
            return;
        }
        let txl = self.tx.clone();
        tokio::spawn(async move {
            let _ = txl.send(Message::TriggerUpdateConnectableMode).await;
@@ -837,22 +850,30 @@ impl Bluetooth {

    /// Returns whether the adapter is connectable.
    pub(crate) fn get_connectable_internal(&self) -> bool {
        match self.properties.get(&BtPropertyType::AdapterScanMode) {
            Some(prop) => match prop {
        self.properties.get(&BtPropertyType::AdapterScanMode).map_or(false, |prop| match prop {
            BluetoothProperty::AdapterScanMode(mode) => match *mode {
                    BtScanMode::Connectable | BtScanMode::ConnectableDiscoverable => true,
                    _ => false,
                BtScanMode::Connectable
                | BtScanMode::ConnectableDiscoverable
                | BtScanMode::ConnectableLimitedDiscoverable => true,
                BtScanMode::None_ => false,
            },
            _ => false,
            },
            _ => false,
        }
        })
    }

    /// Sets the adapter's connectable mode for classic connections.
    pub(crate) fn set_connectable_internal(&mut self, mode: bool) -> bool {
        if self.get_scan_suspend_mode() != SuspendMode::Normal {
            // We will always trigger an update on resume so no need so store the mode change.
            return false;
        }
        if self.is_connectable == mode {
            return true;
        }
        self.is_connectable = mode;
        if mode && self.get_discoverable() {
        if self.discoverable_mode != BtDiscMode::NonDiscoverable {
            // Discoverable always implies connectable. Don't affect the discoverable mode for now
            // and the connectable mode would be restored when discoverable becomes off.
            return true;
        }
        self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::AdapterScanMode(
@@ -861,20 +882,86 @@ impl Bluetooth {
    }

    /// Returns adapter's discoverable mode.
    pub fn get_discoverable_mode_internal(&self) -> BtDiscMode {
    pub(crate) fn get_discoverable_mode_internal(&self) -> BtDiscMode {
        let off_mode = BtDiscMode::NonDiscoverable;

        match self.properties.get(&BtPropertyType::AdapterScanMode) {
            Some(prop) => match prop {
        self.properties.get(&BtPropertyType::AdapterScanMode).map_or(off_mode.clone(), |prop| {
            match prop {
                BluetoothProperty::AdapterScanMode(mode) => match *mode {
                    BtScanMode::ConnectableDiscoverable => BtDiscMode::GeneralDiscoverable,
                    BtScanMode::ConnectableLimitedDiscoverable => BtDiscMode::LimitedDiscoverable,
                    _ => off_mode,
                    BtScanMode::Connectable | BtScanMode::None_ => off_mode,
                },
                _ => off_mode,
            }
        })
    }

    /// Set the suspend mode for scan mode (connectable/discoverable mode).
    pub(crate) fn set_scan_suspend_mode(&mut self, suspend_mode: SuspendMode) {
        if suspend_mode != self.scan_suspend_mode {
            self.scan_suspend_mode = suspend_mode;
        }
    }

    /// Gets current suspend mode for scan mode (connectable/discoverable mode).
    pub(crate) fn get_scan_suspend_mode(&self) -> SuspendMode {
        self.scan_suspend_mode.clone()
    }

    /// Enters the suspend mode for scan mode (connectable/discoverable mode).
    pub(crate) fn scan_mode_enter_suspend(&mut self) -> BtStatus {
        if self.get_scan_suspend_mode() != SuspendMode::Normal {
            return BtStatus::Busy;
        }
        self.set_scan_suspend_mode(SuspendMode::Suspending);

        if self
            .intf
            .lock()
            .unwrap()
            .set_adapter_property(BluetoothProperty::AdapterScanMode(BtScanMode::None_))
            != 0
        {
            warn!("scan_mode_enter_suspend: Failed to set BtScanMode::None_");
        }

        self.set_scan_suspend_mode(SuspendMode::Suspended);

        return BtStatus::Success;
    }

    /// Exits the suspend mode for scan mode (connectable/discoverable mode).
    pub(crate) fn scan_mode_exit_suspend(&mut self) -> BtStatus {
        if self.get_scan_suspend_mode() != SuspendMode::Suspended {
            return BtStatus::Busy;
        }
        self.set_scan_suspend_mode(SuspendMode::Resuming);

        let mode = match self.discoverable_mode {
            BtDiscMode::LimitedDiscoverable => BtScanMode::ConnectableLimitedDiscoverable,
            BtDiscMode::GeneralDiscoverable => BtScanMode::ConnectableDiscoverable,
            BtDiscMode::NonDiscoverable => match self.is_connectable {
                true => BtScanMode::Connectable,
                false => BtScanMode::None_,
            },
            _ => off_mode,
        };
        if self
            .intf
            .lock()
            .unwrap()
            .set_adapter_property(BluetoothProperty::AdapterScanMode(mode.clone()))
            != 0
        {
            warn!("scan_mode_exit_suspend: Failed to restore scan mode {:?}", mode);
        }

        self.set_scan_suspend_mode(SuspendMode::Normal);

        // Update is only available after SuspendMode::Normal
        self.trigger_update_connectable_mode();

        return BtStatus::Success;
    }

    /// Returns adapter's alias.
@@ -1106,9 +1193,14 @@ impl Bluetooth {
                    self.found_devices.insert(address.clone(), device_with_props);
                }
            }

            DelayedActions::UpdateConnectableMode(is_sock_listening) => {
                self.update_connectable_mode(is_sock_listening);
            }

            DelayedActions::ResetDiscoverable => {
                self.set_discoverable(BtDiscMode::NonDiscoverable, 0);
            }
        }
    }

@@ -2128,16 +2220,7 @@ impl IBluetooth for Bluetooth {
    }

    fn get_discoverable(&self) -> bool {
        match self.properties.get(&BtPropertyType::AdapterScanMode) {
            Some(prop) => match prop {
                BluetoothProperty::AdapterScanMode(mode) => match mode {
                    BtScanMode::ConnectableDiscoverable => true,
                    _ => false,
                },
                _ => false,
            },
            _ => false,
        }
        self.get_discoverable_mode_internal() != BtDiscMode::NonDiscoverable
    }

    fn get_discoverable_timeout(&self) -> u32 {
@@ -2159,7 +2242,11 @@ impl IBluetooth for Bluetooth {
            return false;
        }

        let new_mode = match mode {
        // Don't really set the mode when suspend. The mode would be instead restored on resume.
        // However, we still need to set the discoverable timeout so it would properly reset
        // |self.discoverable_mode| after resume.
        if self.get_scan_suspend_mode() == SuspendMode::Normal {
            let scan_mode = match mode {
                BtDiscMode::LimitedDiscoverable => BtScanMode::ConnectableLimitedDiscoverable,
                BtDiscMode::GeneralDiscoverable => BtScanMode::ConnectableDiscoverable,
                BtDiscMode::NonDiscoverable => match self.is_connectable {
@@ -2167,24 +2254,28 @@ impl IBluetooth for Bluetooth {
                    false => BtScanMode::None_,
                },
            };
            if intf.set_adapter_property(BluetoothProperty::AdapterDiscoverableTimeout(duration))
                != 0
                || intf.set_adapter_property(BluetoothProperty::AdapterScanMode(scan_mode)) != 0
            {
                return false;
            }
        }

        self.discoverable_mode = mode.clone();

        // The old timer should be overwritten regardless of what the new mode is.
        if let Some(ref handle) = self.discoverable_timeout {
        if let Some(handle) = self.discoverable_timeout.take() {
            handle.abort();
            self.discoverable_timeout = None;
        }

        if intf.set_adapter_property(BluetoothProperty::AdapterDiscoverableTimeout(duration)) != 0
            || intf.set_adapter_property(BluetoothProperty::AdapterScanMode(new_mode)) != 0
        {
            return false;
        }

        if (mode != BtDiscMode::NonDiscoverable) && (duration != 0) {
        if mode != BtDiscMode::NonDiscoverable && duration != 0 {
            let txl = self.tx.clone();
            self.discoverable_timeout = Some(tokio::spawn(async move {
                time::sleep(Duration::from_secs(duration.into())).await;
                let _ = txl.send(Message::TriggerUpdateConnectableMode).await;
                let _ = txl
                    .send(Message::DelayedAdapterActions(DelayedActions::ResetDiscoverable))
                    .await;
            }));
        }

+4 −19
Original line number Diff line number Diff line
//! Suspend/Resume API.

use crate::bluetooth::{
    Bluetooth, BluetoothDevice, BtifBluetoothCallbacks, DelayedActions, IBluetooth,
};
use crate::bluetooth::{Bluetooth, BluetoothDevice, BtifBluetoothCallbacks, DelayedActions};
use crate::bluetooth_media::BluetoothMedia;
use crate::callbacks::Callbacks;
use crate::{BluetoothGatt, Message, RPCProxy};
use bt_topshim::btif::{BluetoothInterface, BtDiscMode};
use bt_topshim::btif::BluetoothInterface;
use bt_topshim::metrics;
use log::warn;
use num_derive::{FromPrimitive, ToPrimitive};
@@ -145,11 +143,6 @@ pub struct Suspend {

    suspend_timeout_joinhandle: Option<tokio::task::JoinHandle<()>>,
    suspend_state: Arc<Mutex<SuspendState>>,

    /// Bluetooth adapter connectable state before suspending.
    connectable_to_restore: bool,
    /// Bluetooth adapter discoverable mode before suspending.
    discoverable_mode_to_restore: BtDiscMode,
}

impl Suspend {
@@ -171,8 +164,6 @@ impl Suspend {
            audio_reconnect_joinhandle: None,
            suspend_timeout_joinhandle: None,
            suspend_state: Arc::new(Mutex::new(SuspendState::new())),
            connectable_to_restore: false,
            discoverable_mode_to_restore: BtDiscMode::NonDiscoverable,
        }
    }

@@ -236,10 +227,7 @@ impl ISuspend for Suspend {
        // Set suspend event mask
        self.intf.lock().unwrap().set_default_event_mask_except(MASKED_EVENTS_FOR_SUSPEND, 0u64);

        self.connectable_to_restore = self.bt.lock().unwrap().get_connectable_internal();
        self.discoverable_mode_to_restore =
            self.bt.lock().unwrap().get_discoverable_mode_internal();
        self.bt.lock().unwrap().set_connectable_internal(false);
        self.bt.lock().unwrap().scan_mode_enter_suspend();
        self.intf.lock().unwrap().clear_event_filter();
        self.intf.lock().unwrap().clear_filter_accept_list();

@@ -327,10 +315,7 @@ impl ISuspend for Suspend {
        self.intf.lock().unwrap().clear_event_filter();
        self.intf.lock().unwrap().clear_filter_accept_list();
        self.intf.lock().unwrap().restore_filter_accept_list();
        self.bt.lock().unwrap().set_connectable_internal(self.connectable_to_restore);
        if self.discoverable_mode_to_restore != BtDiscMode::NonDiscoverable {
            self.bt.lock().unwrap().set_discoverable(self.discoverable_mode_to_restore.clone(), 0);
        }
        self.bt.lock().unwrap().scan_mode_exit_suspend();

        if !self.audio_reconnect_list.is_empty() {
            let reconnect_list = self.audio_reconnect_list.clone();