From dc6aa72db613996e42ab78b860ab9a325d79f9b2 Mon Sep 17 00:00:00 2001 From: Vibhav Pant Date: Wed, 23 Aug 2023 20:33:57 +0530 Subject: [PATCH] Use sdbus-c++ glue proxies for device info. --- .../implementation/linux/device_info.cc | 85 +++--- .../implementation/linux/device_info.h | 53 +++- .../linux/hostname_client_glue.h | 198 ++++++++++++++ .../linux/login_session_client_glue.h | 254 ++++++++++++++++++ .../linux/org.freedesktop.hostname1.xml | 86 ++++++ .../linux/org.freedesktop.login1.Session.xml | 121 +++++++++ 6 files changed, 751 insertions(+), 46 deletions(-) create mode 100644 internal/platform/implementation/linux/hostname_client_glue.h create mode 100644 internal/platform/implementation/linux/login_session_client_glue.h create mode 100644 internal/platform/implementation/linux/org.freedesktop.hostname1.xml create mode 100644 internal/platform/implementation/linux/org.freedesktop.login1.Session.xml diff --git a/internal/platform/implementation/linux/device_info.cc b/internal/platform/implementation/linux/device_info.cc index 83a63ab1..b5ed037e 100644 --- a/internal/platform/implementation/linux/device_info.cc +++ b/internal/platform/implementation/linux/device_info.cc @@ -7,49 +7,64 @@ #include #include -#include #include "internal/platform/implementation/device_info.h" +#include "internal/platform/implementation/linux/dbus.h" #include "internal/platform/implementation/linux/device_info.h" #include "internal/platform/logging.h" +#include "absl/synchronization/mutex.h" namespace nearby { namespace linux { +void CurrentUserSession::RegisterScreenLockedListener( + absl::string_view listener_name, + std::function callback) { + absl::MutexLock l(&screen_lock_listeners_mutex_); + screen_lock_listeners_[listener_name] = callback; +} -const char *HOSTNAME_DEST = "org.freedesktop.hostname1"; -const char *HOSTNAME_PATH = "/org/freedesktop/hostname1"; -const char *HOSTNAME_INTERFACE = "org.freedesktop.hostname1"; +void + CurrentUserSession::UnregisterScreenLockedListener(absl::string_view listener_name) +{ + absl::MutexLock l(&screen_lock_listeners_mutex_); + screen_lock_listeners_.erase(listener_name); +} -const char *LOGIN_DEST = "org.freedesktop.login1"; -const char *LOGIN_PATH = "/org/freedesktop/login1/session/_"; -const char *LOGIN_INTERFACE = "org.freedesktop.login1.Session"; +void CurrentUserSession::onLock() { + absl::ReaderMutexLock l(&screen_lock_listeners_mutex_); + for (auto &[_, callback] : screen_lock_listeners_) { + callback(api::DeviceInfo::ScreenStatus::kLocked); + } +} -DeviceInfo::DeviceInfo(sdbus::IConnection &system_bus) { - hostname_proxy_ = - sdbus::createProxy(system_bus, HOSTNAME_DEST, HOSTNAME_PATH); - hostname_proxy_->finishRegistration(); - login_proxy_ = sdbus::createProxy(system_bus, LOGIN_PATH, LOGIN_PATH); - login_proxy_->finishRegistration(); +void CurrentUserSession::onUnlock() { + absl::ReaderMutexLock l(&screen_lock_listeners_mutex_); + for (auto &[_, callback] : screen_lock_listeners_) { + callback(api::DeviceInfo::ScreenStatus::kUnlocked); + } +} + +DeviceInfo::DeviceInfo(sdbus::IConnection &system_bus) + : system_bus_(system_bus), + current_user_session_(std::make_unique(system_bus_)) { } std::optional DeviceInfo::GetOsDeviceName() const { + Hostnamed hostnamed(system_bus_); try { - std::string hostname = hostname_proxy_->getProperty("PrettyHostname") - .onInterface(HOSTNAME_INTERFACE); + std::string hostname = hostnamed.PrettyHostname(); std::wstring_convert, char16_t> convert; return convert.from_bytes(hostname); } catch (const sdbus::Error &e) { - NEARBY_LOGS(ERROR) << __func__ << "Got error '" << e.getName() - << "' with message '" << e.getMessage() - << "' while trying to get PrettyHostname"; + DBUS_LOG_PROPERTY_GET_ERROR(&hostnamed, "PrettyHostname", e); return std::nullopt; } } api::DeviceInfo::DeviceType DeviceInfo::GetDeviceType() const { + Hostnamed hostnamed(system_bus_); try { - std::string chasis = hostname_proxy_->getProperty("Chasis") - .onInterface(HOSTNAME_INTERFACE); + std::string chasis = hostnamed.Chassis(); api::DeviceInfo::DeviceType device = api::DeviceInfo::DeviceType::kUnknown; if (chasis == "phone") { device = api::DeviceInfo::DeviceType::kPhone; @@ -62,9 +77,7 @@ api::DeviceInfo::DeviceType DeviceInfo::GetDeviceType() const { } return device; } catch (const sdbus::Error &e) { - NEARBY_LOGS(ERROR) << __func__ << "Got error '" << e.getName() - << "' with message '" << e.getMessage() - << "' while trying to get PrettyHostname"; + DBUS_LOG_PROPERTY_GET_ERROR(&hostnamed, "Chasis", e); return api::DeviceInfo::DeviceType::kUnknown; } } @@ -107,7 +120,7 @@ std::optional DeviceInfo::GetTemporaryPath() const { if (dir == NULL) { return std::filesystem::path("/tmp"); } - return std::filesystem::path(std::string(dir)) / "com.github.google.nearby"; + return std::filesystem::path(std::string(dir)) / "Google Nearby"; } std::optional DeviceInfo::GetLogPath() const { @@ -115,7 +128,7 @@ std::optional DeviceInfo::GetLogPath() const { if (dir == NULL) { return std::filesystem::path("/tmp"); } - return std::filesystem::path(std::string(dir)) / "com.github.google.nearby" / + return std::filesystem::path(std::string(dir)) / "Google Nearby" / "logs"; } @@ -124,31 +137,15 @@ std::optional DeviceInfo::GetCrashDumpPath() const { if (dir == NULL) { return std::filesystem::path("/tmp"); } - return std::filesystem::path(std::string(dir)) / "com.github.google.nearby" / + return std::filesystem::path(std::string(dir)) / "Google Nearby" / "crashes"; } bool DeviceInfo::IsScreenLocked() const { - char *session = nullptr; - if (sd_pid_get_session(getpid(), &session) < 0) { - NEARBY_LOGS(ERROR) << __func__ - << ": Error getting session for current user"; - return false; - } - - std::string session_path(LOGIN_PATH); - session_path += session; - free(session); - try { - bool locked = - login_proxy_->getProperty("LockedHint").onInterface(LOGIN_INTERFACE); - return locked; + return current_user_session_->LockedHint(); } catch (const sdbus::Error &e) { - NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName() - << "' with message '" << e.getMessage() - << "' while trying to get LockedHint for session " - << session_path; + DBUS_LOG_PROPERTY_GET_ERROR(current_user_session_, "LockedHint", e); return false; } } diff --git a/internal/platform/implementation/linux/device_info.h b/internal/platform/implementation/linux/device_info.h index 3ca5b762..b1c4c7de 100644 --- a/internal/platform/implementation/linux/device_info.h +++ b/internal/platform/implementation/linux/device_info.h @@ -2,17 +2,66 @@ #define PLATFORM_IMPL_LINUX_DEVICE_INFO_H_ #include +#include #include #include #include +#include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" +#include "absl/synchronization/mutex.h" #include "internal/platform/implementation/device_info.h" +#include "internal/platform/implementation/linux/hostname_client_glue.h" +#include "internal/platform/implementation/linux/login_session_client_glue.h" namespace nearby { namespace linux { +class CurrentUserSession + : public sdbus::ProxyInterfaces { +public: + CurrentUserSession(sdbus::IConnection &system_bus) + : ProxyInterfaces(system_bus, "org.freedesktop.login1", + "/org/freedesktop/login1/session/auto") { + registerProxy(); + } + ~CurrentUserSession() { unregisterProxy(); } + + void RegisterScreenLockedListener( + absl::string_view listener_name, + std::function callback) + ABSL_LOCKS_EXCLUDED(screen_lock_listeners_mutex_); + void UnregisterScreenLockedListener(absl::string_view listener_name) + ABSL_LOCKS_EXCLUDED(screen_lock_listeners_mutex_); + +protected: + void onPauseDevice(const uint32_t &major, const uint32_t &minor, + const std::string &type) override {} + void onResumeDevice(const uint32_t &major, const uint32_t &minor, + const sdbus::UnixFd &fd) override {} + + void onLock() override ABSL_LOCKS_EXCLUDED(screen_lock_listeners_mutex_); + void onUnlock() override ABSL_LOCKS_EXCLUDED(screen_lock_listeners_mutex_); + +private: + absl::Mutex screen_lock_listeners_mutex_; + absl::flat_hash_map> + screen_lock_listeners_ ABSL_GUARDED_BY(screen_lock_listeners_mutex_); +}; + +class Hostnamed + : public sdbus::ProxyInterfaces { +public: + Hostnamed(sdbus::IConnection &system_bus) + : ProxyInterfaces(system_bus, "org.freedesktop.hostname1", + "/org/freedesktop/hostname1") { + registerProxy(); + } + ~Hostnamed() { unregisterProxy(); } +}; + class DeviceInfo : public api::DeviceInfo { public: DeviceInfo(sdbus::IConnection &system_bus); @@ -50,8 +99,8 @@ public: UnregisterScreenLockedListener(absl::string_view listener_name) override{}; private: - std::unique_ptr hostname_proxy_; - std::unique_ptr login_proxy_; + sdbus::IConnection &system_bus_; + std::unique_ptr current_user_session_; }; } // namespace linux } // namespace nearby diff --git a/internal/platform/implementation/linux/hostname_client_glue.h b/internal/platform/implementation/linux/hostname_client_glue.h new file mode 100644 index 00000000..de07c548 --- /dev/null +++ b/internal/platform/implementation/linux/hostname_client_glue.h @@ -0,0 +1,198 @@ + +/* + * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! + */ + +#ifndef __sdbuscpp__hostname_client_glue_h__proxy__H__ +#define __sdbuscpp__hostname_client_glue_h__proxy__H__ + +#include +#include +#include + +namespace org { +namespace freedesktop { + +class hostname1_proxy +{ +public: + static constexpr const char* INTERFACE_NAME = "org.freedesktop.hostname1"; + +protected: + hostname1_proxy(sdbus::IProxy& proxy) + : proxy_(proxy) + { + } + + ~hostname1_proxy() = default; + +public: + void SetHostname(const std::string& hostname, const bool& interactive) + { + proxy_.callMethod("SetHostname").onInterface(INTERFACE_NAME).withArguments(hostname, interactive); + } + + void SetStaticHostname(const std::string& hostname, const bool& interactive) + { + proxy_.callMethod("SetStaticHostname").onInterface(INTERFACE_NAME).withArguments(hostname, interactive); + } + + void SetPrettyHostname(const std::string& hostname, const bool& interactive) + { + proxy_.callMethod("SetPrettyHostname").onInterface(INTERFACE_NAME).withArguments(hostname, interactive); + } + + void SetIconName(const std::string& icon, const bool& interactive) + { + proxy_.callMethod("SetIconName").onInterface(INTERFACE_NAME).withArguments(icon, interactive); + } + + void SetChassis(const std::string& chassis, const bool& interactive) + { + proxy_.callMethod("SetChassis").onInterface(INTERFACE_NAME).withArguments(chassis, interactive); + } + + void SetDeployment(const std::string& deployment, const bool& interactive) + { + proxy_.callMethod("SetDeployment").onInterface(INTERFACE_NAME).withArguments(deployment, interactive); + } + + void SetLocation(const std::string& location, const bool& interactive) + { + proxy_.callMethod("SetLocation").onInterface(INTERFACE_NAME).withArguments(location, interactive); + } + + std::vector GetProductUUID(const bool& interactive) + { + std::vector result; + proxy_.callMethod("GetProductUUID").onInterface(INTERFACE_NAME).withArguments(interactive).storeResultsTo(result); + return result; + } + + std::string GetHardwareSerial() + { + std::string result; + proxy_.callMethod("GetHardwareSerial").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + + std::string Describe() + { + std::string result; + proxy_.callMethod("Describe").onInterface(INTERFACE_NAME).storeResultsTo(result); + return result; + } + +public: + std::string Hostname() + { + return proxy_.getProperty("Hostname").onInterface(INTERFACE_NAME); + } + + std::string StaticHostname() + { + return proxy_.getProperty("StaticHostname").onInterface(INTERFACE_NAME); + } + + std::string PrettyHostname() + { + return proxy_.getProperty("PrettyHostname").onInterface(INTERFACE_NAME); + } + + std::string DefaultHostname() + { + return proxy_.getProperty("DefaultHostname").onInterface(INTERFACE_NAME); + } + + std::string HostnameSource() + { + return proxy_.getProperty("HostnameSource").onInterface(INTERFACE_NAME); + } + + std::string IconName() + { + return proxy_.getProperty("IconName").onInterface(INTERFACE_NAME); + } + + std::string Chassis() + { + return proxy_.getProperty("Chassis").onInterface(INTERFACE_NAME); + } + + std::string Deployment() + { + return proxy_.getProperty("Deployment").onInterface(INTERFACE_NAME); + } + + std::string Location() + { + return proxy_.getProperty("Location").onInterface(INTERFACE_NAME); + } + + std::string KernelName() + { + return proxy_.getProperty("KernelName").onInterface(INTERFACE_NAME); + } + + std::string KernelRelease() + { + return proxy_.getProperty("KernelRelease").onInterface(INTERFACE_NAME); + } + + std::string KernelVersion() + { + return proxy_.getProperty("KernelVersion").onInterface(INTERFACE_NAME); + } + + std::string OperatingSystemPrettyName() + { + return proxy_.getProperty("OperatingSystemPrettyName").onInterface(INTERFACE_NAME); + } + + std::string OperatingSystemCPEName() + { + return proxy_.getProperty("OperatingSystemCPEName").onInterface(INTERFACE_NAME); + } + + uint64_t OperatingSystemSupportEnd() + { + return proxy_.getProperty("OperatingSystemSupportEnd").onInterface(INTERFACE_NAME); + } + + std::string HomeURL() + { + return proxy_.getProperty("HomeURL").onInterface(INTERFACE_NAME); + } + + std::string HardwareVendor() + { + return proxy_.getProperty("HardwareVendor").onInterface(INTERFACE_NAME); + } + + std::string HardwareModel() + { + return proxy_.getProperty("HardwareModel").onInterface(INTERFACE_NAME); + } + + std::string FirmwareVersion() + { + return proxy_.getProperty("FirmwareVersion").onInterface(INTERFACE_NAME); + } + + std::string FirmwareVendor() + { + return proxy_.getProperty("FirmwareVendor").onInterface(INTERFACE_NAME); + } + + uint64_t FirmwareDate() + { + return proxy_.getProperty("FirmwareDate").onInterface(INTERFACE_NAME); + } + +private: + sdbus::IProxy& proxy_; +}; + +}} // namespaces + +#endif diff --git a/internal/platform/implementation/linux/login_session_client_glue.h b/internal/platform/implementation/linux/login_session_client_glue.h new file mode 100644 index 00000000..77cd9e97 --- /dev/null +++ b/internal/platform/implementation/linux/login_session_client_glue.h @@ -0,0 +1,254 @@ + +/* + * This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT! + */ + +#ifndef __sdbuscpp__login_session_client_glue_h__proxy__H__ +#define __sdbuscpp__login_session_client_glue_h__proxy__H__ + +#include +#include +#include + +namespace org { +namespace freedesktop { +namespace login1 { + +class Session_proxy +{ +public: + static constexpr const char* INTERFACE_NAME = "org.freedesktop.login1.Session"; + +protected: + Session_proxy(sdbus::IProxy& proxy) + : proxy_(proxy) + { + proxy_.uponSignal("PauseDevice").onInterface(INTERFACE_NAME).call([this](const uint32_t& major, const uint32_t& minor, const std::string& type){ this->onPauseDevice(major, minor, type); }); + proxy_.uponSignal("ResumeDevice").onInterface(INTERFACE_NAME).call([this](const uint32_t& major, const uint32_t& minor, const sdbus::UnixFd& fd){ this->onResumeDevice(major, minor, fd); }); + proxy_.uponSignal("Lock").onInterface(INTERFACE_NAME).call([this](){ this->onLock(); }); + proxy_.uponSignal("Unlock").onInterface(INTERFACE_NAME).call([this](){ this->onUnlock(); }); + } + + ~Session_proxy() = default; + + virtual void onPauseDevice(const uint32_t& major, const uint32_t& minor, const std::string& type) = 0; + virtual void onResumeDevice(const uint32_t& major, const uint32_t& minor, const sdbus::UnixFd& fd) = 0; + virtual void onLock() = 0; + virtual void onUnlock() = 0; + +public: + void Terminate() + { + proxy_.callMethod("Terminate").onInterface(INTERFACE_NAME); + } + + void Activate() + { + proxy_.callMethod("Activate").onInterface(INTERFACE_NAME); + } + + void Lock() + { + proxy_.callMethod("Lock").onInterface(INTERFACE_NAME); + } + + void Unlock() + { + proxy_.callMethod("Unlock").onInterface(INTERFACE_NAME); + } + + void SetIdleHint(const bool& idle) + { + proxy_.callMethod("SetIdleHint").onInterface(INTERFACE_NAME).withArguments(idle); + } + + void SetLockedHint(const bool& locked) + { + proxy_.callMethod("SetLockedHint").onInterface(INTERFACE_NAME).withArguments(locked); + } + + void Kill(const std::string& who, const int32_t& signal_number) + { + proxy_.callMethod("Kill").onInterface(INTERFACE_NAME).withArguments(who, signal_number); + } + + void TakeControl(const bool& force) + { + proxy_.callMethod("TakeControl").onInterface(INTERFACE_NAME).withArguments(force); + } + + void ReleaseControl() + { + proxy_.callMethod("ReleaseControl").onInterface(INTERFACE_NAME); + } + + void SetType(const std::string& type) + { + proxy_.callMethod("SetType").onInterface(INTERFACE_NAME).withArguments(type); + } + + void SetDisplay(const std::string& display) + { + proxy_.callMethod("SetDisplay").onInterface(INTERFACE_NAME).withArguments(display); + } + + void SetTTY(const sdbus::UnixFd& tty_fd) + { + proxy_.callMethod("SetTTY").onInterface(INTERFACE_NAME).withArguments(tty_fd); + } + + std::tuple TakeDevice(const uint32_t& major, const uint32_t& minor) + { + std::tuple result; + proxy_.callMethod("TakeDevice").onInterface(INTERFACE_NAME).withArguments(major, minor).storeResultsTo(result); + return result; + } + + void ReleaseDevice(const uint32_t& major, const uint32_t& minor) + { + proxy_.callMethod("ReleaseDevice").onInterface(INTERFACE_NAME).withArguments(major, minor); + } + + void PauseDeviceComplete(const uint32_t& major, const uint32_t& minor) + { + proxy_.callMethod("PauseDeviceComplete").onInterface(INTERFACE_NAME).withArguments(major, minor); + } + + void SetBrightness(const std::string& subsystem, const std::string& name, const uint32_t& brightness) + { + proxy_.callMethod("SetBrightness").onInterface(INTERFACE_NAME).withArguments(subsystem, name, brightness); + } + +public: + std::string Id() + { + return proxy_.getProperty("Id").onInterface(INTERFACE_NAME); + } + + sdbus::Struct User() + { + return proxy_.getProperty("User").onInterface(INTERFACE_NAME); + } + + std::string Name() + { + return proxy_.getProperty("Name").onInterface(INTERFACE_NAME); + } + + uint64_t Timestamp() + { + return proxy_.getProperty("Timestamp").onInterface(INTERFACE_NAME); + } + + uint64_t TimestampMonotonic() + { + return proxy_.getProperty("TimestampMonotonic").onInterface(INTERFACE_NAME); + } + + uint32_t VTNr() + { + return proxy_.getProperty("VTNr").onInterface(INTERFACE_NAME); + } + + sdbus::Struct Seat() + { + return proxy_.getProperty("Seat").onInterface(INTERFACE_NAME); + } + + std::string TTY() + { + return proxy_.getProperty("TTY").onInterface(INTERFACE_NAME); + } + + std::string Display() + { + return proxy_.getProperty("Display").onInterface(INTERFACE_NAME); + } + + bool Remote() + { + return proxy_.getProperty("Remote").onInterface(INTERFACE_NAME); + } + + std::string RemoteHost() + { + return proxy_.getProperty("RemoteHost").onInterface(INTERFACE_NAME); + } + + std::string RemoteUser() + { + return proxy_.getProperty("RemoteUser").onInterface(INTERFACE_NAME); + } + + std::string Service() + { + return proxy_.getProperty("Service").onInterface(INTERFACE_NAME); + } + + std::string Desktop() + { + return proxy_.getProperty("Desktop").onInterface(INTERFACE_NAME); + } + + std::string Scope() + { + return proxy_.getProperty("Scope").onInterface(INTERFACE_NAME); + } + + uint32_t Leader() + { + return proxy_.getProperty("Leader").onInterface(INTERFACE_NAME); + } + + uint32_t Audit() + { + return proxy_.getProperty("Audit").onInterface(INTERFACE_NAME); + } + + std::string Type() + { + return proxy_.getProperty("Type").onInterface(INTERFACE_NAME); + } + + std::string Class() + { + return proxy_.getProperty("Class").onInterface(INTERFACE_NAME); + } + + bool Active() + { + return proxy_.getProperty("Active").onInterface(INTERFACE_NAME); + } + + std::string State() + { + return proxy_.getProperty("State").onInterface(INTERFACE_NAME); + } + + bool IdleHint() + { + return proxy_.getProperty("IdleHint").onInterface(INTERFACE_NAME); + } + + uint64_t IdleSinceHint() + { + return proxy_.getProperty("IdleSinceHint").onInterface(INTERFACE_NAME); + } + + uint64_t IdleSinceHintMonotonic() + { + return proxy_.getProperty("IdleSinceHintMonotonic").onInterface(INTERFACE_NAME); + } + + bool LockedHint() + { + return proxy_.getProperty("LockedHint").onInterface(INTERFACE_NAME); + } + +private: + sdbus::IProxy& proxy_; +}; + +}}} // namespaces + +#endif diff --git a/internal/platform/implementation/linux/org.freedesktop.hostname1.xml b/internal/platform/implementation/linux/org.freedesktop.hostname1.xml new file mode 100644 index 00000000..822e99b2 --- /dev/null +++ b/internal/platform/implementation/linux/org.freedesktop.hostname1.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal/platform/implementation/linux/org.freedesktop.login1.Session.xml b/internal/platform/implementation/linux/org.freedesktop.login1.Session.xml new file mode 100644 index 00000000..dbad22f3 --- /dev/null +++ b/internal/platform/implementation/linux/org.freedesktop.login1.Session.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +