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

Commit 93f6d584 authored by Sonny Sasaka's avatar Sonny Sasaka
Browse files

Floss: Refactors ClientDBusProxy to be reusable

This refactors ClientDBusProxy to be reusable by moving it into the
dbus_projection crate.

Bug: 224606285
Tag: #floss
Test: Manual - build.py

Change-Id: Id7604ce3b268570b7555509aac3b3dff9deb6a74
parent 7a194cf6
Loading
Loading
Loading
Loading
+26 −75
Original line number Original line Diff line number Diff line
@@ -16,10 +16,10 @@ use btstack::RPCProxy;
use btstack::suspend::{ISuspend, ISuspendCallback, SuspendType};
use btstack::suspend::{ISuspend, ISuspendCallback, SuspendType};


use btstack::uuid::Profile;
use btstack::uuid::Profile;
use dbus::arg::{AppendAll, RefArg};
use dbus::arg::RefArg;
use dbus::nonblock::SyncConnection;
use dbus::nonblock::SyncConnection;


use dbus_projection::{impl_dbus_arg_enum, DisconnectWatcher};
use dbus_projection::{impl_dbus_arg_enum, ClientDBusProxy, DisconnectWatcher};


use dbus_macros::{
use dbus_macros::{
    dbus_method, dbus_propmap, generate_dbus_exporter, generate_dbus_interface_client,
    dbus_method, dbus_propmap, generate_dbus_exporter, generate_dbus_interface_client,
@@ -101,55 +101,6 @@ pub struct BluetoothDeviceDBus {
    name: String,
    name: String,
}
}


struct ClientDBusProxy {
    conn: Arc<SyncConnection>,
    bus_name: String,
    objpath: dbus::Path<'static>,
    interface: String,
}

impl ClientDBusProxy {
    fn create_proxy(&self) -> dbus::nonblock::Proxy<Arc<SyncConnection>> {
        let conn = self.conn.clone();
        dbus::nonblock::Proxy::new(
            self.bus_name.clone(),
            self.objpath.clone(),
            std::time::Duration::from_secs(2),
            conn,
        )
    }

    /// Calls a method and returns the dbus result.
    fn method_withresult<A: AppendAll, T: 'static + dbus::arg::Arg + for<'z> dbus::arg::Get<'z>>(
        &self,
        member: &str,
        args: A,
    ) -> Result<(T,), dbus::Error> {
        let proxy = self.create_proxy();
        // We know that all APIs return immediately, so we can block on it for simplicity.
        return futures::executor::block_on(async {
            proxy.method_call(self.interface.clone(), member, args).await
        });
    }

    fn method<A: AppendAll, T: 'static + dbus::arg::Arg + for<'z> dbus::arg::Get<'z>>(
        &self,
        member: &str,
        args: A,
    ) -> T {
        let (ret,): (T,) = self.method_withresult(member, args).unwrap();
        return ret;
    }

    fn method_noreturn<A: AppendAll>(&self, member: &str, args: A) {
        // The real type should be Result<((),), _> since there is no return value. However, to
        // meet trait constraints, we just use bool and never unwrap the result. This calls the
        // method, waits for the response but doesn't actually attempt to parse the result (on
        // unwrap).
        let _: Result<(bool,), _> = self.method_withresult(member, args);
    }
}

#[allow(dead_code)]
#[allow(dead_code)]
struct IBluetoothCallbackDBus {}
struct IBluetoothCallbackDBus {}


@@ -240,12 +191,12 @@ pub(crate) struct BluetoothDBus {
impl BluetoothDBus {
impl BluetoothDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothDBus {
        BluetoothDBus {
        BluetoothDBus {
            client_proxy: ClientDBusProxy {
            client_proxy: ClientDBusProxy::new(
                conn: conn.clone(),
                conn.clone(),
                bus_name: String::from("org.chromium.bluetooth"),
                String::from("org.chromium.bluetooth"),
                objpath: make_object_path(index, "adapter"),
                make_object_path(index, "adapter"),
                interface: String::from("org.chromium.bluetooth.Bluetooth"),
                String::from("org.chromium.bluetooth.Bluetooth"),
            },
            ),
        }
        }
    }
    }
}
}
@@ -469,12 +420,12 @@ pub(crate) struct BluetoothManagerDBus {
impl BluetoothManagerDBus {
impl BluetoothManagerDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>) -> BluetoothManagerDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>) -> BluetoothManagerDBus {
        BluetoothManagerDBus {
        BluetoothManagerDBus {
            client_proxy: ClientDBusProxy {
            client_proxy: ClientDBusProxy::new(
                conn: conn.clone(),
                conn.clone(),
                bus_name: String::from("org.chromium.bluetooth.Manager"),
                String::from("org.chromium.bluetooth.Manager"),
                objpath: dbus::Path::new("/org/chromium/bluetooth/Manager").unwrap(),
                dbus::Path::new("/org/chromium/bluetooth/Manager").unwrap(),
                interface: String::from("org.chromium.bluetooth.Manager"),
                String::from("org.chromium.bluetooth.Manager"),
            },
            ),
        }
        }
    }
    }


@@ -558,12 +509,12 @@ pub(crate) struct BluetoothGattDBus {
impl BluetoothGattDBus {
impl BluetoothGattDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus {
        BluetoothGattDBus {
        BluetoothGattDBus {
            client_proxy: ClientDBusProxy {
            client_proxy: ClientDBusProxy::new(
                conn: conn.clone(),
                conn.clone(),
                bus_name: String::from("org.chromium.bluetooth"),
                String::from("org.chromium.bluetooth"),
                objpath: make_object_path(index, "gatt"),
                make_object_path(index, "gatt"),
                interface: String::from("org.chromium.bluetooth.BluetoothGatt"),
                String::from("org.chromium.bluetooth.BluetoothGatt"),
            },
            ),
        }
        }
    }
    }
}
}
@@ -830,12 +781,12 @@ pub(crate) struct SuspendDBus {
impl SuspendDBus {
impl SuspendDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> SuspendDBus {
    pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> SuspendDBus {
        SuspendDBus {
        SuspendDBus {
            client_proxy: ClientDBusProxy {
            client_proxy: ClientDBusProxy::new(
                conn: conn.clone(),
                conn.clone(),
                bus_name: String::from("org.chromium.bluetooth"),
                String::from("org.chromium.bluetooth"),
                objpath: make_object_path(index, "suspend"),
                make_object_path(index, "suspend"),
                interface: String::from("org.chromium.bluetooth.Suspend"),
                String::from("org.chromium.bluetooth.Suspend"),
            },
            ),
        }
        }
    }
    }
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -7,3 +7,4 @@ edition = "2018"
dbus_macros = { path = "dbus_macros" }
dbus_macros = { path = "dbus_macros" }
dbus = "0.9.2"
dbus = "0.9.2"
dbus-tokio = "0.7.3"
dbus-tokio = "0.7.3"
futures = "0.3.13"
+66 −0
Original line number Original line Diff line number Diff line
@@ -45,6 +45,7 @@
//!   passing in the object path, D-Bus connection, Crossroads object, the Rust object to be
//!   passing in the object path, D-Bus connection, Crossroads object, the Rust object to be
//!   projected, and a [`DisconnectWatcher`](DisconnectWatcher) object.
//!   projected, and a [`DisconnectWatcher`](DisconnectWatcher) object.


use dbus::arg::AppendAll;
use dbus::channel::MatchingReceiver;
use dbus::channel::MatchingReceiver;
use dbus::message::MatchRule;
use dbus::message::MatchRule;
use dbus::nonblock::SyncConnection;
use dbus::nonblock::SyncConnection;
@@ -155,6 +156,71 @@ impl DisconnectWatcher {
    }
    }
}
}


/// A client proxy to conveniently call API methods generated with the
/// [`generate_dbus_interface_client`](dbus_macros::generate_dbus_interface_client) macro.
pub struct ClientDBusProxy {
    conn: Arc<SyncConnection>,
    bus_name: String,
    objpath: dbus::Path<'static>,
    interface: String,
}

impl ClientDBusProxy {
    pub fn new(
        conn: Arc<SyncConnection>,
        bus_name: String,
        objpath: dbus::Path<'static>,
        interface: String,
    ) -> Self {
        Self { conn, bus_name, objpath, interface }
    }

    fn create_proxy(&self) -> dbus::nonblock::Proxy<Arc<SyncConnection>> {
        let conn = self.conn.clone();
        dbus::nonblock::Proxy::new(
            self.bus_name.clone(),
            self.objpath.clone(),
            std::time::Duration::from_secs(2),
            conn,
        )
    }

    /// Calls the method and returns the D-Bus result and lets the caller unwrap.
    pub fn method_withresult<
        A: AppendAll,
        T: 'static + dbus::arg::Arg + for<'z> dbus::arg::Get<'z>,
    >(
        &self,
        member: &str,
        args: A,
    ) -> Result<(T,), dbus::Error> {
        let proxy = self.create_proxy();
        // We know that all APIs return immediately, so we can block on it for simplicity.
        return futures::executor::block_on(async {
            proxy.method_call(self.interface.clone(), member, args).await
        });
    }

    /// Calls the method and unwrap the returned D-Bus result.
    pub fn method<A: AppendAll, T: 'static + dbus::arg::Arg + for<'z> dbus::arg::Get<'z>>(
        &self,
        member: &str,
        args: A,
    ) -> T {
        let (ret,): (T,) = self.method_withresult(member, args).unwrap();
        return ret;
    }

    /// Calls the void method and does not need to unwrap the result.
    pub fn method_noreturn<A: AppendAll>(&self, member: &str, args: A) {
        // The real type should be Result<((),), _> since there is no return value. However, to
        // meet trait constraints, we just use bool and never unwrap the result. This calls the
        // method, waits for the response but doesn't actually attempt to parse the result (on
        // unwrap).
        let _: Result<(bool,), _> = self.method_withresult(member, args);
    }
}

/// Implements `DBusArg` for an enum.
/// Implements `DBusArg` for an enum.
///
///
/// A Rust enum is converted to D-Bus INT32 type.
/// A Rust enum is converted to D-Bus INT32 type.