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

Commit 969c41a0 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I9f283e05,Iaa5fe05b into main

* changes:
  floss: Scanner: Remove existing/pending MSFT handles on start/stop_scan
  floss: Scanner: Remove async and don't call to BTIF when powering off
parents 1b3f02aa 3043d3d7
Loading
Loading
Loading
Loading
+0 −85
Original line number Diff line number Diff line
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use tokio::sync::oneshot;
use tokio::time::Duration;

/// Helper for managing an async topshim function. It takes care of calling the function, preparing
/// the channel, waiting for the callback, and returning it in a Result.
///
/// `R` is the type of the return.
pub(crate) struct AsyncHelper<R> {
    // Name of the method that this struct helps. Useful for logging.
    method_name: String,

    // Keeps track of call_id. Increment each time and wrap to 0 when u32 max is reached.
    last_call_id: u32,

    // Keep pending calls' ids and senders.
    senders: Arc<Mutex<HashMap<u32, oneshot::Sender<R>>>>,
}

pub(crate) type CallbackSender<R> = Arc<Mutex<Box<(dyn Fn(u32, R) + Send)>>>;

impl<R: 'static + Send> AsyncHelper<R> {
    pub(crate) fn new(method_name: &str) -> Self {
        Self {
            method_name: String::from(method_name),
            last_call_id: 0,
            senders: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    /// Calls a topshim method that expects the async return to be delivered via a callback.
    pub(crate) async fn call_method<F>(&mut self, f: F, timeout_ms: Option<u64>) -> Result<R, ()>
    where
        F: Fn(u32),
    {
        // Create a oneshot channel to be used by the callback to notify us that the return is
        // available.
        let (tx, rx) = oneshot::channel();

        // Use a unique method call ID so that we know which callback is corresponding to which
        // method call. The actual value of the ID does not matter as long as it's always unique,
        // so a simple increment (and wraps back to 0) is good enough.
        self.last_call_id = self.last_call_id.wrapping_add(1);

        // Keep track of the sender belonging to this call id.
        self.senders.lock().unwrap().insert(self.last_call_id, tx);

        // Call the method. `f` is freely defined by the user of this utility. This must be an
        // operation that expects a callback that will trigger sending of the return via the
        // oneshot channel.
        f(self.last_call_id);

        if let Some(timeout_ms) = timeout_ms {
            let senders = self.senders.clone();
            let call_id = self.last_call_id;
            tokio::spawn(async move {
                tokio::time::sleep(Duration::from_millis(timeout_ms)).await;

                // If the timer expires first before a callback is triggered, we remove the sender
                // which will invalidate the channel which in turn will notify the receiver of
                // an error.
                // If the callback gets triggered first, this does nothing since the entry has been
                // removed when sending the response.
                senders.lock().unwrap().remove(&call_id);
            });
        }

        // Wait for the callback and return when available.
        rx.await.map_err(|_| ())
    }

    /// Returns a function to be invoked when callback is triggered.
    pub(crate) fn get_callback_sender(&self) -> CallbackSender<R> {
        let senders = self.senders.clone();
        let method_name = self.method_name.clone();
        return Arc::new(Mutex::new(Box::new(move |call_id, ret| {
            if let Some(sender) = senders.lock().unwrap().remove(&call_id) {
                sender.send(ret).ok();
            } else {
                log::warn!("AsyncHelper {}: Sender no longer exists.", method_name);
            }
        })));
    }
}
+391 −419

File changed.

Preview size limit exceeded, changes collapsed.

+0 −1
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@
//! This crate provides the API implementation of the Fluoride/GD Bluetooth
//! stack, independent of any RPC projection.

pub mod async_helper;
pub mod battery_manager;
pub mod battery_provider_manager;
pub mod battery_service;
+22 −22
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <algorithm>
#include <iterator>
#include <memory>
#include <utility>
#include <vector>

#include "include/hardware/bt_common_types.h"
@@ -228,30 +229,30 @@ void BleScannerIntf::ScanFilterEnable(bool enable) {

bool BleScannerIntf::IsMsftSupported() { return scanner_intf_->IsMsftSupported(); }

void BleScannerIntf::MsftAdvMonitorAdd(uint32_t call_id, const RustMsftAdvMonitor& monitor) {
  scanner_intf_->MsftAdvMonitorAdd(internal::ConvertAdvMonitor(monitor),
                                   base::Bind(&BleScannerIntf::OnMsftAdvMonitorAddCallback,
                                              base::Unretained(this), call_id));
void BleScannerIntf::MsftAdvMonitorAdd(const RustMsftAdvMonitor& monitor) {
  scanner_intf_->MsftAdvMonitorAdd(
          internal::ConvertAdvMonitor(monitor),
          base::Bind(&BleScannerIntf::OnMsftAdvMonitorAddCallback, base::Unretained(this)));
}

void BleScannerIntf::MsftAdvMonitorRemove(uint32_t call_id, uint8_t monitor_handle) {
  scanner_intf_->MsftAdvMonitorRemove(monitor_handle,
                                      base::Bind(&BleScannerIntf::OnMsftAdvMonitorRemoveCallback,
                                                 base::Unretained(this), call_id));
void BleScannerIntf::MsftAdvMonitorRemove(uint8_t monitor_handle) {
  scanner_intf_->MsftAdvMonitorRemove(
          monitor_handle,
          base::Bind(&BleScannerIntf::OnMsftAdvMonitorRemoveCallback, base::Unretained(this)));
}

void BleScannerIntf::MsftAdvMonitorEnable(uint32_t call_id, bool enable) {
  scanner_intf_->MsftAdvMonitorEnable(enable,
                                      base::Bind(&BleScannerIntf::OnMsftAdvMonitorEnableCallback,
                                                 base::Unretained(this), call_id));
void BleScannerIntf::MsftAdvMonitorEnable(bool enable) {
  scanner_intf_->MsftAdvMonitorEnable(
          enable,
          base::Bind(&BleScannerIntf::OnMsftAdvMonitorEnableCallback, base::Unretained(this)));
}

#else

bool BleScannerIntf::IsMsftSupported() { return false; }
void BleScannerIntf::MsftAdvMonitorAdd(uint32_t, const RustMsftAdvMonitor&) {}
void BleScannerIntf::MsftAdvMonitorRemove(uint32_t, uint8_t) {}
void BleScannerIntf::MsftAdvMonitorEnable(uint32_t, bool) {}
void BleScannerIntf::MsftAdvMonitorAdd(const RustMsftAdvMonitor&) {}
void BleScannerIntf::MsftAdvMonitorRemove(uint8_t) {}
void BleScannerIntf::MsftAdvMonitorEnable(bool) {}

#endif

@@ -335,17 +336,16 @@ void BleScannerIntf::OnFilterConfigCallback(uint8_t filter_index, uint8_t filt_t
}

#if TARGET_FLOSS
void BleScannerIntf::OnMsftAdvMonitorAddCallback(uint32_t call_id, uint8_t monitor_handle,
                                                 uint8_t status) {
  rusty::gdscan_msft_adv_monitor_add_callback(call_id, monitor_handle, status);
void BleScannerIntf::OnMsftAdvMonitorAddCallback(uint8_t monitor_handle, uint8_t status) {
  rusty::gdscan_msft_adv_monitor_add_callback(monitor_handle, status);
}

void BleScannerIntf::OnMsftAdvMonitorRemoveCallback(uint32_t call_id, uint8_t status) {
  rusty::gdscan_msft_adv_monitor_remove_callback(call_id, status);
void BleScannerIntf::OnMsftAdvMonitorRemoveCallback(uint8_t status) {
  rusty::gdscan_msft_adv_monitor_remove_callback(status);
}

void BleScannerIntf::OnMsftAdvMonitorEnableCallback(uint32_t call_id, uint8_t status) {
  rusty::gdscan_msft_adv_monitor_enable_callback(call_id, status);
void BleScannerIntf::OnMsftAdvMonitorEnableCallback(uint8_t status) {
  rusty::gdscan_msft_adv_monitor_enable_callback(status);
}
#endif

+11 −10
Original line number Diff line number Diff line
@@ -13,10 +13,11 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef GD_RUST_TOPSHIM_GATT_GATT_BLE_SCANNER_SHIM_H
#define GD_RUST_TOPSHIM_GATT_GATT_BLE_SCANNER_SHIM_H
#ifndef SYSTEM_GD_RUST_TOPSHIM_GATT_GATT_BLE_SCANNER_SHIM_H_
#define SYSTEM_GD_RUST_TOPSHIM_GATT_GATT_BLE_SCANNER_SHIM_H_

#include <memory>
#include <vector>

#include "include/hardware/ble_scanner.h"
#include "rust/cxx.h"
@@ -30,7 +31,7 @@ struct RustMsftAdvMonitor;

class BleScannerIntf : public ScanningCallbacks {
public:
  BleScannerIntf(BleScannerInterface* scanner_intf) : scanner_intf_(scanner_intf) {}
  explicit BleScannerIntf(BleScannerInterface* scanner_intf) : scanner_intf_(scanner_intf) {}
  ~BleScannerIntf() = default;

  // ScanningCallbacks overrides
@@ -92,13 +93,13 @@ public:
  bool IsMsftSupported();

  // Adds an MSFT filter. Gets responses via |OnMsftAdvMonitorAddCallback|.
  void MsftAdvMonitorAdd(uint32_t call_id, const RustMsftAdvMonitor& monitor);
  void MsftAdvMonitorAdd(const RustMsftAdvMonitor& monitor);

  // Removes a previously added MSFT scan filter.
  void MsftAdvMonitorRemove(uint32_t call_id, uint8_t monitor_handle);
  void MsftAdvMonitorRemove(uint8_t monitor_handle);

  // Enables or disables MSFT advertisement monitor.
  void MsftAdvMonitorEnable(uint32_t call_id, bool enable);
  void MsftAdvMonitorEnable(bool enable);

  // Sets the LE scan interval and window in units of N * 0.625 msec. The result
  // of this action is returned via |OnStatusCallback|.
@@ -160,9 +161,9 @@ private:
  void OnFilterConfigCallback(uint8_t filt_index, uint8_t filt_type, uint8_t avbl_space,
                              uint8_t action, uint8_t btm_status);
#if TARGET_FLOSS
  void OnMsftAdvMonitorAddCallback(uint32_t call_id, uint8_t monitor_handle, uint8_t status);
  void OnMsftAdvMonitorRemoveCallback(uint32_t call_id, uint8_t status);
  void OnMsftAdvMonitorEnableCallback(uint32_t call_id, uint8_t status);
  void OnMsftAdvMonitorAddCallback(uint8_t monitor_handle, uint8_t status);
  void OnMsftAdvMonitorRemoveCallback(uint8_t status);
  void OnMsftAdvMonitorEnableCallback(uint8_t status);
#endif

  BleScannerInterface* scanner_intf_;
@@ -174,4 +175,4 @@ std::unique_ptr<BleScannerIntf> GetBleScannerIntf(const unsigned char* gatt_intf
}  // namespace topshim
}  // namespace bluetooth

#endif  // GD_RUST_TOPSHIM_GATT_GATT_BLE_SCANNER_SHIM_H
#endif  // SYSTEM_GD_RUST_TOPSHIM_GATT_GATT_BLE_SCANNER_SHIM_H_
Loading