From c83767c7e52b9660427dd143f34d2959ec3f0a7f Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Mon, 19 Feb 2024 11:22:12 -0500 Subject: [PATCH] feat: geoclue bindings --- Cargo.toml | 5 +- geoclue2/Cargo.toml | 13 +++++ geoclue2/src/lib.rs | 139 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 geoclue2/Cargo.toml create mode 100644 geoclue2/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 4f04c5f..fa44987 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ resolver = "2" members = [ "cosmic-settings-daemon", + "geoclue2", "mpris2", "networkmanager", "switcheroo-control", @@ -15,5 +16,5 @@ members = [ serde = { version = "1.0", features = ["derive"] } thiserror = "1.0" time = { version = "0.3", features = ["parsing"] } -zbus = { version = "3.14" } -zvariant = { version = "3.15"} +zbus = { version = "3.15.0" } +zvariant = { version = "3.15.0"} diff --git a/geoclue2/Cargo.toml b/geoclue2/Cargo.toml new file mode 100644 index 0000000..f012527 --- /dev/null +++ b/geoclue2/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "geoclue2" +description = "zbus-based bindings for GeoClue2 on Linux" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde.workspace = true +serde_repr = "0.1.18" +zbus.workspace = true \ No newline at end of file diff --git a/geoclue2/src/lib.rs b/geoclue2/src/lib.rs new file mode 100644 index 0000000..b218a0d --- /dev/null +++ b/geoclue2/src/lib.rs @@ -0,0 +1,139 @@ +use serde_repr::{Deserialize_repr, Serialize_repr}; +use zbus::{ + dbus_proxy, + zvariant::{ObjectPath, OwnedValue, Type}, + Result, +}; + +#[repr(u32)] +#[derive(Deserialize_repr, Serialize_repr, Type, Debug, PartialEq, Eq)] +pub enum Accuracy { + /// Accuracy level unknown or unset + None, + /// Country level accuracy + Country, + /// City level accuracy + City, + /// Neighborhood level accuracy + Neighborhood, + /// Street level accuracy + Street, + /// Exact accuracy. Typically requires GPS receiver + Exact, +} + +impl From for u32 { + fn from(value: Accuracy) -> Self { + value as u32 + } +} + +impl TryFrom for Accuracy { + type Error = >::Error; + + fn try_from(value: OwnedValue) -> std::prelude::v1::Result { + Ok(match ::try_from(value)? { + 1 => Accuracy::Country, + 2 => Accuracy::City, + 3 => Accuracy::Neighborhood, + 4 => Accuracy::Street, + 5 => Accuracy::Exact, + _ => Accuracy::None, + }) + } +} + +#[dbus_proxy( + default_service = "org.freedesktop.GeoClue2", + interface = "org.freedesktop.GeoClue2.Manager", + default_path = "/org/freedesktop/GeoClue2/Manager" +)] +trait Manager { + /// Retrieves a client object which can only be used by the calling application only. On the first call from a specific D-Bus peer, this method will create the client object but subsequent calls will return the path of the existing client. + #[dbus_proxy(object = "Client")] + fn get_client(&self); + + #[dbus_proxy(object = "Client")] + fn delete_client<'a>(&self, client: ObjectPath<'a>); + + /// InUse property + #[dbus_proxy(property)] + fn in_use(&self) -> Result; + + /// AvailableAccuracyLevel property + #[dbus_proxy(property)] + fn available_accuracy_level(&self) -> zbus::Result; +} + +#[dbus_proxy( + default_service = "org.freedesktop.GeoClue2", + interface = "org.freedesktop.GeoClue2.Client" +)] +trait Client { + /// Start method + fn start(&self) -> zbus::Result<()>; + + /// Stop method + fn stop(&self) -> zbus::Result<()>; + + /// LocationUpdated signal + #[dbus_proxy(signal)] + fn location_updated( + &self, + old: zbus::zvariant::ObjectPath<'_>, + new: zbus::zvariant::ObjectPath<'_>, + ) -> zbus::Result<()>; + + /// Active property + #[dbus_proxy(property)] + fn active(&self) -> zbus::Result; + + /// DesktopId property + #[dbus_proxy(property)] + fn desktop_id(&self) -> zbus::Result; + #[dbus_proxy(property)] + fn set_desktop_id(&self, value: &str) -> zbus::Result<()>; + + /// DistanceThreshold property + #[dbus_proxy(property)] + fn distance_threshold(&self) -> zbus::Result; + #[dbus_proxy(property)] + fn set_distance_threshold(&self, value: u32) -> zbus::Result<()>; + + /// Location property + #[dbus_proxy(property, object = "Location")] + fn location(&self) -> zbus::Result; + + /// RequestedAccuracyLevel property + #[dbus_proxy(property)] + fn requested_accuracy_level(&self) -> zbus::Result; + #[dbus_proxy(property)] + fn set_requested_accuracy_level(&self, value: u32) -> zbus::Result<()>; + + /// TimeThreshold property + #[dbus_proxy(property)] + fn time_threshold(&self) -> zbus::Result; + fn set_time_threshold(&self, value: u32) -> zbus::Result<()>; +} + +#[dbus_proxy( + default_service = "org.freedesktop.GeoClue2", + interface = "org.freedesktop.GeoClue2.Location" +)] +trait Location { + #[dbus_proxy(property)] + fn latitude(&self) -> Result; + #[dbus_proxy(property)] + fn longitude(&self) -> Result; + #[dbus_proxy(property)] + fn accuracy(&self) -> Result; + #[dbus_proxy(property)] + fn altitude(&self) -> Result; + /// Speed in meters per second. + /// When unknown, it's set to -1.0. + #[dbus_proxy(property)] + fn speed(&self) -> Result; + /// The heading direction in degrees with respect to North direction, in clockwise order. That means North becomes 0 degree, East: 90 degrees, South: 180 degrees, West: 270 degrees and so on. When unknown, it's set to -1.0. + #[dbus_proxy(property)] + fn heading(&self) -> Result; +}