#include "Systemd.hpp" #include #include #include #include #include #include Systemd::Systemd(QObject* parent) : QObject(parent) { this->systemdManager = new DBusSystemdManager( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", QDBusConnection::sessionBus(), this ); this->logindManager = new DBusLogindManager( "org.freedesktop.login1", "/org/freedesktop/login1", QDBusConnection::systemBus(), this ); QDBusReply sessionPath = this->logindManager->GetSession("auto"); qDebug() << sessionPath; this->logindSession = new DBusLogindSession( "org.freedesktop.login1", sessionPath.value().path(), QDBusConnection::systemBus(), this ); this->logindSessionProperties = new DBusProperties( "org.freedesktop.login1", sessionPath.value().path(), QDBusConnection::systemBus(), this ); QObject::connect(this->logindManager, &DBusLogindManager::PrepareForShutdown, this, &Systemd::shutdown); QObject::connect(this->logindManager, &DBusLogindManager::PrepareForSleep, this, &Systemd::sleep); QObject::connect(this->logindSession, &DBusLogindSession::Lock, this, &Systemd::lock); QObject::connect(this->logindSession, &DBusLogindSession::Unlock, this, &Systemd::unlock); QObject::connect(this->logindSessionProperties, &DBusProperties::PropertiesChanged, this, &Systemd::onLogindSessionPropertiesChanged); } void Systemd::onLogindSessionPropertiesChanged(const QString& interface_name, const QVariantMap& changed_properties, const QStringList& invalidated_properties) { if (changed_properties.contains("IdleHint") || invalidated_properties.contains("IdleHint")) emit this->idleHintChanged(); if (changed_properties.contains("LockedHint") || invalidated_properties.contains("LockedHint")) emit this->lockedHintChanged(); } void Systemd::stopUserUnit(const QString& unit, const QString& mode) { this->systemdManager->StopUnit(unit, mode); } void Systemd::setBrightness(const QString& subsystem, const QString& name, quint32 brightness) { this->logindSession->SetBrightness(subsystem, name, brightness); } bool Systemd::idleHint() { return this->logindSession->idleHint(); } void Systemd::setIdleHint(bool idle) { this->logindSession->SetIdleHint(idle); } bool Systemd::lockedHint() { return this->logindSession->lockedHint(); } void Systemd::setLockedHint(bool locked) { this->logindSession->SetLockedHint(locked); } std::string SystemdInhibitorParams::toString(SystemdInhibitorParams::WhatItem what) { if (what == SystemdInhibitorParams::Shutdown) return "shutdown"; else if (what == SystemdInhibitorParams::Sleep) return "sleep"; else if (what == SystemdInhibitorParams::Idle) return "idle"; else if (what == SystemdInhibitorParams::HandlePowerKey) return "handle-power-key"; else if (what == SystemdInhibitorParams::HandleSuspendKey) return "handle-suspend-key"; else if (what == SystemdInhibitorParams::HandleHibernateKey) return "handle-hibernate-key"; else if (what == SystemdInhibitorParams::HandleLidSwitch) return "handle-lid-switch"; return ""; } std::string SystemdInhibitorParams::toString(SystemdInhibitorParams::What what) { std::ostringstream res; bool first = true; for (const WhatItem& item: SystemdInhibitorParams::allWhatItems) { if (!(what & item)) continue; if (!first) res << ":"; else first = false; res << SystemdInhibitorParams::toString(item); } return res.str(); } std::string SystemdInhibitorParams::toString(SystemdInhibitorParams::Mode mode) { if (mode == SystemdInhibitorParams::Block) return "block"; else if (mode == SystemdInhibitorParams::BlockWeak) return "block-weak"; else if (mode == SystemdInhibitorParams::Delay) return "delay"; return ""; } bool SystemdInhibitor::enabled() const { return static_cast(this->activeInhibitor); } void SystemdInhibitor::setEnabled(bool enabled) { this->mEnabled = enabled; if (enabled) this->update(); else this->release(); } SystemdInhibitorParams::What SystemdInhibitor::what() const { return this->mWhat; } void SystemdInhibitor::setWhat(SystemdInhibitorParams::What what) { this->mWhat = what; this->update(); } QString SystemdInhibitor::who() const { return this->mWho; } void SystemdInhibitor::setWho(QString who) { this->mWho = who; this->update(); } QString SystemdInhibitor::why() const { return this->mWhy; } void SystemdInhibitor::setWhy(QString why) { this->mWhy = why; this->update(); } SystemdInhibitorParams::Mode SystemdInhibitor::mode() const { return this->mMode; } void SystemdInhibitor::setMode(SystemdInhibitorParams::Mode mode) { this->mMode = mode; this->update(); } SystemdInhibitor::ActiveSystemdInhibitor::ActiveSystemdInhibitor(SystemdInhibitorParams::What what_, QString who_, QString why_, SystemdInhibitorParams::Mode mode_): what(what_), who(who_), why(why_), mode(mode_) { DBusLogindManager logindManager( "org.freedesktop.login1", "/org/freedesktop/login1", QDBusConnection::systemBus() ); QDBusReply fd_ = logindManager.Inhibit(QString::fromStdString(SystemdInhibitorParams::toString(what)), who, why, QString::fromStdString(SystemdInhibitorParams::toString(mode))); if (fd_.error().isValid()) throw fd_.error(); this->fd = ::dup(fd_.value().fileDescriptor()); } SystemdInhibitor::ActiveSystemdInhibitor::~ActiveSystemdInhibitor() { if (this->fd != -1) ::close(this->fd); } void SystemdInhibitor::release() { if (!this->activeInhibitor) return; this->activeInhibitor.reset(); emit this->enabledChanged(); } void SystemdInhibitor::update() { if (!this->mWhat || this->mWho.isEmpty() || this->mWhy.isEmpty() || !this->mMode || !this->mEnabled) if (this->activeInhibitor) this->release(); else return; if (this->activeInhibitor && this->mWhat == this->activeInhibitor->what && this->mWho == this->activeInhibitor->who && this->mWhy == this->activeInhibitor->why && this->mMode == this->activeInhibitor->mode) return; std::unique_ptr otherInhibitor; try { otherInhibitor.reset(new SystemdInhibitor::ActiveSystemdInhibitor(this->mWhat, this->mWho, this->mWhy, this->mMode)); } catch (const QDBusError& err) { qCritical().noquote() << err.name().toStdString() << " " << err.message().toStdString(); return; } this->activeInhibitor.swap(otherInhibitor); if (!otherInhibitor && this->activeInhibitor) emit this->enabledChanged(); if (otherInhibitor && otherInhibitor->what != this->activeInhibitor->what) emit this->whatChanged(); if (otherInhibitor && otherInhibitor->who != this->activeInhibitor->who) emit this->whoChanged(); if (otherInhibitor && otherInhibitor->why != this->activeInhibitor->why) emit this->whyChanged(); if (otherInhibitor && otherInhibitor->mode != this->activeInhibitor->mode) emit this->modeChanged(); }