DBusManager to centralize dbus connection

This commit is contained in:
iamanaws 2024-12-26 08:00:29 -08:00
parent f9f77d3b53
commit a4a6a5248a
6 changed files with 137 additions and 65 deletions

View file

@ -1,5 +1,6 @@
#include "Fingerprint.hpp"
#include "../core/hyprlock.hpp"
#include "../core/DBusManager.hpp"
#include "../helpers/Log.hpp"
#include "../config/ConfigManager.hpp"
@ -48,8 +49,10 @@ CFingerprint::~CFingerprint() {
}
void CFingerprint::init() {
m_sDBUSState.connection = sdbus::createSystemBusConnection();
m_sDBUSState.login = sdbus::createProxy(*m_sDBUSState.connection, sdbus::ServiceName{"org.freedesktop.login1"}, sdbus::ObjectPath{"/org/freedesktop/login1"});
auto& dbusManager = DBusManager::getInstance();
m_sDBUSState.connection = dbusManager.getConnection();
m_sDBUSState.login = dbusManager.getLoginProxy();
m_sDBUSState.login->getPropertyAsync("PreparingForSleep").onInterface(LOGIN_MANAGER).uponReplyInvoke([this](std::optional<sdbus::Error> e, sdbus::Variant preparingForSleep) {
if (e) {
Debug::log(WARN, "fprint: Failed getting value for PreparingForSleep: {}", e->what());
@ -62,6 +65,7 @@ void CFingerprint::init() {
inhibitSleep();
startVerify();
});
m_sDBUSState.login->uponSignal("PrepareForSleep").onInterface(LOGIN_MANAGER).call([this](bool start) {
Debug::log(LOG, "fprint: PrepareForSleep (start: {})", start);
if (start) {
@ -97,10 +101,6 @@ void CFingerprint::terminate() {
releaseDevice();
}
std::shared_ptr<sdbus::IConnection> CFingerprint::getConnection() {
return m_sDBUSState.connection;
}
void CFingerprint::inhibitSleep() {
m_sDBUSState.login->callMethodAsync("Inhibit")
.onInterface(LOGIN_MANAGER)

View file

@ -22,14 +22,12 @@ class CFingerprint : public IAuthImplementation {
virtual std::optional<std::string> getLastPrompt();
virtual void terminate();
std::shared_ptr<sdbus::IConnection> getConnection();
private:
struct SDBUSState {
std::string message = "";
std::shared_ptr<sdbus::IConnection> connection;
std::unique_ptr<sdbus::IProxy> login;
std::shared_ptr<sdbus::IProxy> login;
std::unique_ptr<sdbus::IProxy> device;
sdbus::UnixFd inhibitLock;

88
src/core/DBusManager.cpp Normal file
View file

@ -0,0 +1,88 @@
#include "DBusManager.hpp"
#include "../helpers/Log.hpp"
DBusManager& DBusManager::getInstance() {
static DBusManager instance;
return instance;
}
DBusManager::DBusManager() {
initializeConnection();
}
DBusManager::~DBusManager() {
// Resources are automatically cleaned up.
}
void DBusManager::initializeConnection() {
try {
m_connection = sdbus::createSystemBusConnection();
const sdbus::ServiceName destination{"org.freedesktop.login1"};
const sdbus::ObjectPath loginPath{"/org/freedesktop/login1"};
const sdbus::ObjectPath sessionPath{"/org/freedesktop/login1/session/auto"};
m_loginProxy = sdbus::createProxy(*m_connection, destination, loginPath);
m_sessionProxy = sdbus::createProxy(*m_connection, destination, sessionPath);
Debug::log(LOG, "[DBusManager] Initialized D-Bus connection. Service: {}. Login path: {}, Session path: {}",
std::string(destination), std::string(loginPath), std::string(sessionPath));
} catch (const sdbus::Error& e) {
Debug::log(ERR, "[DBusManager] D-Bus connection initialization failed: {}", e.what());
}
}
std::shared_ptr<sdbus::IConnection> DBusManager::getConnection() {
std::lock_guard<std::mutex> lock(m_mutex);
return m_connection;
}
std::shared_ptr<sdbus::IProxy> DBusManager::getLoginProxy() {
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_loginProxy) {
initializeConnection();
}
return m_loginProxy;
}
std::shared_ptr<sdbus::IProxy> DBusManager::getSessionProxy() {
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_sessionProxy) {
initializeConnection();
}
return m_sessionProxy;
}
void DBusManager::setLockedHint(bool locked) {
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_sessionProxy) {
Debug::log(WARN, "[DBusManager] Cannot set locked hint: Proxy is not initialized.");
return;
}
try {
const sdbus::ServiceName interface{"org.freedesktop.login1.Session"};
m_sessionProxy->callMethod("SetLockedHint").onInterface(interface).withArguments(locked);
Debug::log(LOG, "[DBusManager] Sent 'SetLockedHint({})' on {}", locked, std::string(interface));
} catch (const sdbus::Error& e) {
Debug::log(WARN, "[DBusManager] Failed to send 'SetLockedHint({})': {}", locked, e.what());
}
}
void DBusManager::sendUnlockSignal() {
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_sessionProxy) {
Debug::log(WARN, "[DBusManager] Unlock signal skipped: Proxy is not initialized.");
return;
}
try {
const sdbus::ServiceName interface{"org.freedesktop.login1.Session"};
m_sessionProxy->callMethod("Unlock").onInterface(interface);
Debug::log(LOG, "[DBusManager] Sent 'Unlock' on {}", std::string(interface));
} catch (const sdbus::Error& e) {
Debug::log(WARN, "[DBusManager] Unlock signal failed: {}", e.what());
}
}

30
src/core/DBusManager.hpp Normal file
View file

@ -0,0 +1,30 @@
#pragma once
#include <memory>
#include <string>
#include <mutex>
#include <sdbus-c++/sdbus-c++.h>
class DBusManager {
public:
static DBusManager& getInstance();
std::shared_ptr<sdbus::IConnection> getConnection();
std::shared_ptr<sdbus::IProxy> getLoginProxy();
std::shared_ptr<sdbus::IProxy> getSessionProxy();
void setLockedHint(bool locked);
void sendUnlockSignal();
private:
DBusManager();
~DBusManager();
void initializeConnection();
std::shared_ptr<sdbus::IConnection> m_connection;
std::shared_ptr<sdbus::IProxy> m_loginProxy;
std::shared_ptr<sdbus::IProxy> m_sessionProxy;
std::mutex m_mutex;
};

View file

@ -1,4 +1,5 @@
#include "hyprlock.hpp"
#include "DBusManager.hpp"
#include "../helpers/Log.hpp"
#include "../config/ConfigManager.hpp"
#include "../renderer/Renderer.hpp"
@ -18,7 +19,6 @@
#include <filesystem>
#include <fstream>
#include <algorithm>
#include <sdbus-c++/sdbus-c++.h>
#include <hyprutils/os/Process.hpp>
using namespace Hyprutils::OS;
@ -411,7 +411,6 @@ void CHyprlock::run() {
}
acquireSessionLock();
setupDBus();
// Recieved finished
if (m_bTerminate) {
@ -423,8 +422,14 @@ void CHyprlock::run() {
exit(1);
}
auto& dbusManager = DBusManager::getInstance();
const auto dbusConn = dbusManager.getConnection();
dbusManager.setLockedHint(true);
const auto fingerprintAuth = g_pAuth->getImpl(AUTH_IMPL_FINGERPRINT);
const auto dbusConn = (fingerprintAuth) ? ((CFingerprint*)fingerprintAuth.get())->getConnection() : nullptr;
if (fingerprintAuth){
fingerprintAuth->init();
}
registerSignalAction(SIGUSR1, handleUnlockSignal, SA_RESTART);
registerSignalAction(SIGUSR2, handleForceUpdateSignal);
@ -601,50 +606,6 @@ void CHyprlock::run() {
Debug::log(LOG, "Reached the end, exiting");
}
void CHyprlock::setupDBus() {
try {
m_sDBUSState.connection = sdbus::createSystemBusConnection();
const sdbus::ServiceName destination{"org.freedesktop.login1"};
const sdbus::ObjectPath objectPath{"/org/freedesktop/login1/session/auto"};
m_sDBUSState.proxy = sdbus::createProxy(*m_sDBUSState.connection, destination, objectPath);
Debug::log(LOG, "[dbus] Initialized. Service: {}, Path: {}", std::string(destination), std::string(objectPath));
} catch (const sdbus::Error& e) {
Debug::log(ERR, "[dbus] Init failed: {}", std::string(e.what()));
return;
}
try {
const sdbus::ServiceName interface{"org.freedesktop.login1.Session"};
m_sDBUSState.proxy->callMethod("SetLockedHint").onInterface(interface).withArguments(true);
Debug::log(LOG, "[dbus] Sent 'SetLockedHint(true)' on {}", std::string(interface));
} catch (const sdbus::Error& e) {
Debug::log(WARN, "[dbus] Failed 'SetLockedHint(true)': {}", std::string(e.what()));
}
}
void CHyprlock::sendUnlockSignal() {
if (!m_sDBUSState.proxy) {
Debug::log(WARN, "[dbus] Unlock signal skipped: Proxy is not initialized. Call setupDBus() first.");
return;
}
try {
const sdbus::ServiceName interface{"org.freedesktop.login1.Session"};
m_sDBUSState.proxy->callMethod("Unlock").onInterface(interface);
m_sDBUSState.proxy->callMethod("SetLockedHint").onInterface(interface).withArguments(false);
Debug::log(LOG, "[dbus] Sent 'Unlock' and 'SetLockedHint(false)' on {}", std::string(interface));
} catch (const sdbus::Error& e) {
Debug::log(WARN, "[dbus] Unlock signal failed: {}", std::string(e.what()));
}
}
void CHyprlock::unlock() {
static auto* const PNOFADEOUT = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:no_fade_out");
@ -1040,7 +1001,10 @@ void CHyprlock::releaseSessionLock() {
ext_session_lock_v1_unlock_and_destroy(m_sLockState.lock);
m_sLockState.lock = nullptr;
sendUnlockSignal();
// Notify unlock via D-Bus.
auto& dbusManager = DBusManager::getInstance();
dbusManager.sendUnlockSignal();
dbusManager.setLockedHint(false);
Debug::log(LOG, "Unlocked, exiting!");

View file

@ -35,9 +35,6 @@ class CHyprlock {
void unlock();
bool isUnlocked();
void setupDBus();
void sendUnlockSignal();
void onGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
void onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name);
@ -168,11 +165,6 @@ class CHyprlock {
std::mutex timerRequestMutex;
bool timerEvent = false;
} m_sLoopState;
struct SDBUSState {
std::unique_ptr<sdbus::IConnection> connection;
std::unique_ptr<sdbus::IProxy> proxy;
} m_sDBUSState;
std::vector<std::shared_ptr<CTimer>> m_vTimers;