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

Commit 1202de09 authored by Sonny Sasaka's avatar Sonny Sasaka
Browse files

Integrate dbus_projection for btmanagerd

To reduce boilerplate codes, this migrates btmanagerd to using
dbus_projection framework:

* dbus_arg.rs: generated code necessary to use dbus_projection macros
* iface_bluetooth_manager.rs: API definitions
* bluetooth_manager.rs: D-Bus-agnostic implementation of the API, with
  logic copied almost unchanged from main.rs
* bluetooth_manager_dbus.rs: D-Bus projections
* main.rs: Moved D-Bus handlers to bluetooth_manager.rs
* lib.rs: Added iface_bluetooth_manager module so that the interface
  definition can be shared with btclient
* state_machine.rs: Migrated away from dbus_callback_util

Bug: 189501475
Tag: #floss
Test: Build floss on Linux

Change-Id: I25b7e02243752fb0a1f2b75fb8384141e85bd91b
parent 02909efb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -173,8 +173,8 @@ pub fn generate_dbus_exporter(attr: TokenStream, item: TokenStream) -> TokenStre
    let gen = quote! {
        #ori_item

        pub fn #fn_ident<T: 'static + #api_iface_ident + Send + ?Sized>(
            path: String,
        pub fn #fn_ident<T: 'static + #api_iface_ident + Send + ?Sized, P: Into<dbus::Path<'static>>>(
            path: P,
            conn: std::sync::Arc<SyncConnection>,
            cr: &mut dbus_crossroads::Crossroads,
            obj: #obj_type,
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@ bt_common = { path = "../../common" }
dbus = "0.9.2"
dbus-tokio = "0.7.3"
dbus-crossroads = "0.4.0"
dbus_projection = { path = "../dbus_projection" }
dbus_macros = { path = "../dbus_projection/dbus_macros" }
futures = "0.3.13"
inotify = "*"
log = "0.4.14"
+90 −0
Original line number Diff line number Diff line
use log::error;

use manager_service::iface_bluetooth_manager::{IBluetoothManager, IBluetoothManagerCallback};

use std::process::Command;
use std::sync::atomic::Ordering;

use crate::{config_util, state_machine, ManagerContext};

const BLUEZ_INIT_TARGET: &str = "bluetoothd";

/// Implementation of IBluetoothManager.
pub struct BluetoothManager {
    manager_context: ManagerContext,
    callbacks: Vec<Box<dyn IBluetoothManagerCallback + Send>>,
}

impl BluetoothManager {
    pub(crate) fn new(manager_context: ManagerContext) -> BluetoothManager {
        BluetoothManager { manager_context, callbacks: vec![] }
    }

    pub(crate) fn callback_hci_device_change(&self, hci_device: i32, present: bool) {
        for callback in &self.callbacks {
            callback.on_hci_device_changed(hci_device, present);
        }
    }
}

impl IBluetoothManager for BluetoothManager {
    fn start(&mut self, hci_interface: i32) {
        if !config_util::modify_hci_n_enabled(hci_interface, true) {
            error!("Config is not successfully modified");
        }
        self.manager_context.proxy.start_bluetooth(hci_interface);
    }

    fn stop(&mut self, hci_interface: i32) {
        if !config_util::modify_hci_n_enabled(hci_interface, false) {
            error!("Config is not successfully modified");
        }
        self.manager_context.proxy.stop_bluetooth(hci_interface);
    }

    fn get_state(&mut self) -> i32 {
        let proxy = self.manager_context.proxy.clone();
        let state = proxy.get_state();
        let result = state_machine::state_to_i32(state);
        result
    }

    fn register_callback(&mut self, callback: Box<dyn IBluetoothManagerCallback + Send>) {
        // TODO: Handle callback disconnects.
        self.callbacks.push(callback);
    }

    fn get_floss_enabled(&mut self) -> bool {
        let enabled = self.manager_context.floss_enabled.load(Ordering::Relaxed);
        enabled
    }

    fn set_floss_enabled(&mut self, enabled: bool) {
        let prev = self.manager_context.floss_enabled.swap(enabled, Ordering::Relaxed);
        config_util::write_floss_enabled(enabled);
        if prev != enabled && enabled {
            Command::new("initctl")
                .args(&["stop", BLUEZ_INIT_TARGET])
                .output()
                .expect("failed to stop bluetoothd");
            // TODO: Implement multi-hci case
            let default_device = config_util::list_hci_devices()[0];
            if config_util::is_hci_n_enabled(default_device) {
                let _ = self.manager_context.proxy.start_bluetooth(default_device);
            }
        } else if prev != enabled {
            // TODO: Implement multi-hci case
            let default_device = config_util::list_hci_devices()[0];
            self.manager_context.proxy.stop_bluetooth(default_device);
            Command::new("initctl")
                .args(&["start", BLUEZ_INIT_TARGET])
                .output()
                .expect("failed to start bluetoothd");
        }
    }

    fn list_hci_devices(&mut self) -> Vec<i32> {
        let devices = config_util::list_hci_devices();
        devices
    }
}
+53 −0
Original line number Diff line number Diff line
use dbus::nonblock::SyncConnection;
use dbus::strings::Path;

use dbus_macros::{dbus_method, dbus_proxy_obj, generate_dbus_exporter};

use dbus_projection::DisconnectWatcher;

use manager_service::iface_bluetooth_manager::{IBluetoothManager, IBluetoothManagerCallback};
use manager_service::RPCProxy;

use crate::dbus_arg::DBusArg;

/// D-Bus projection of IBluetoothManager.
struct BluetoothManagerDBus {}

#[generate_dbus_exporter(export_bluetooth_manager_dbus_obj, "org.chromium.bluetooth.Manager")]
impl IBluetoothManager for BluetoothManagerDBus {
    #[dbus_method("Start")]
    fn start(&mut self, _hci_interface: i32) {}

    #[dbus_method("Stop")]
    fn stop(&mut self, _hci_interface: i32) {}

    #[dbus_method("GetState")]
    fn get_state(&mut self) -> i32 {
        0
    }

    #[dbus_method("RegisterCallback")]
    fn register_callback(&mut self, _callback: Box<dyn IBluetoothManagerCallback + Send>) {}

    #[dbus_method("GetFlossEnabled")]
    fn get_floss_enabled(&mut self) -> bool {
        false
    }

    #[dbus_method("SetFlossEnabled")]
    fn set_floss_enabled(&mut self, _enabled: bool) {}

    #[dbus_method("ListHciDevices")]
    fn list_hci_devices(&mut self) -> Vec<i32> {
        vec![]
    }
}

/// D-Bus projection of IBluetoothManagerCallback.
struct BluetoothManagerCallbackDBus {}

#[dbus_proxy_obj(BluetoothManagerCallback, "org.chromium.bluetooth.ManagerCallback")]
impl IBluetoothManagerCallback for BluetoothManagerCallbackDBus {
    #[dbus_method("OnHciDeviceChanged")]
    fn on_hci_device_changed(&self, hci_interface: i32, present: bool) {}
}
+3 −0
Original line number Diff line number Diff line
use dbus_macros::generate_dbus_arg;

generate_dbus_arg!();
Loading