[plugins/lockdevice] Port to use logind interface

KScreenLocker does not allow unlocking the screen via the screensaver interface by design (https://bugs.kde.org/show_bug.cgi?id=425616).

However it allows to do it via the logind interface, so let's use that here.

While at it also refactor the code and properly track and send the state, so the other device can show an appropriate label.
This commit is contained in:
Nicolas Fella 2020-08-20 00:47:29 +02:00
parent f778fc932c
commit ed91dfb1ec
5 changed files with 99 additions and 23 deletions

View file

@ -1,4 +1,5 @@
qt5_add_dbus_interface(lockdevice_SRCS org.freedesktop.ScreenSaver.xml screensaverdbusinterface)
qt5_add_dbus_interface(lockdevice_SRCS org.freedesktop.login1.xml login1dbusinterface)
qt5_add_dbus_interface(lockdevice_SRCS org.freedesktop.DBus.Properties.xml propertiesdbusinterface)
set(debug_file_SRCS)
ecm_qt_declare_logging_category(

View file

@ -10,7 +10,6 @@
#include <KPluginFactory>
#include <QDebug>
#include "screensaverdbusinterface.h"
#include "plugin_lock_debug.h"
#include <core/device.h>
@ -21,19 +20,48 @@ K_PLUGIN_CLASS_WITH_JSON(LockDevicePlugin, "kdeconnect_lockdevice.json")
LockDevicePlugin::LockDevicePlugin(QObject* parent, const QVariantList& args)
: KdeConnectPlugin(parent, args)
, m_remoteLocked(false)
, m_iface(nullptr)
, m_login1Interface(QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1/session/auto"), QDBusConnection::systemBus())
// Connect on all paths since the PropertiesChanged signal is only emitted
// from /org/freedesktop/login1/session/<sessionId> and not /org/freedesktop/login1/session/auto
, m_propertiesInterface(QStringLiteral("org.freedesktop.login1"), QString(), QDBusConnection::systemBus())
{
if (!m_login1Interface.isValid()) {
qCWarning(KDECONNECT_PLUGIN_LOCKREMOTE) << "Could not connect to logind interface" << m_login1Interface.lastError();
}
if (!m_propertiesInterface.isValid()) {
qCWarning(KDECONNECT_PLUGIN_LOCKREMOTE) << "Could not connect to logind properties interface" << m_propertiesInterface.lastError();
}
connect(&m_propertiesInterface, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged, this, [this](const QString& interface, const QVariantMap& properties, QStringList invalidatedProperties ) {
Q_UNUSED(invalidatedProperties);
if (interface != QLatin1String("org.freedesktop.login1.Session")) {
return;
}
if (!properties.contains(QStringLiteral("LockedHint"))) {
return;
}
m_localLocked = properties.value(QStringLiteral("LockedHint")).toBool();
sendState();
});
m_localLocked = m_login1Interface.lockedHint();
}
LockDevicePlugin::~LockDevicePlugin()
{
delete m_iface;
}
bool LockDevicePlugin::isLocked() const
{
return m_remoteLocked;
}
void LockDevicePlugin::setLocked(bool locked)
{
NetworkPacket np(PACKET_TYPE_LOCK_REQUEST, {{QStringLiteral("setLocked"), locked}});
@ -50,27 +78,29 @@ bool LockDevicePlugin::receivePacket(const NetworkPacket & np)
}
}
bool sendState = np.has(QStringLiteral("requestLocked"));
if (np.has(QStringLiteral("setLocked"))) {
iface()->SetActive(np.get<bool>(QStringLiteral("setLocked")));
sendState = true;
if (np.has(QStringLiteral("requestLocked"))) {
sendState();
}
if (sendState) {
NetworkPacket np(PACKET_TYPE_LOCK, QVariantMap {{QStringLiteral("isLocked"), QVariant::fromValue<bool>(iface()->GetActive())}});
sendPacket(np);
if (np.has(QStringLiteral("setLocked"))) {
const bool lock = np.get<bool>(QStringLiteral("setLocked"));
if (lock) {
m_login1Interface.Lock();
} else {
m_login1Interface.Unlock();
}
sendState();
}
return true;
}
OrgFreedesktopScreenSaverInterface* LockDevicePlugin::iface()
void LockDevicePlugin::sendState()
{
if (!m_iface) {
m_iface = new OrgFreedesktopScreenSaverInterface(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/org/freedesktop/ScreenSaver"), DBusHelper::sessionBus());
if(!m_iface->isValid())
qCWarning(KDECONNECT_PLUGIN_LOCKREMOTE) << "Couldn't connect to the ScreenSaver interface";
}
return m_iface;
NetworkPacket np(PACKET_TYPE_LOCK, {{QStringLiteral("isLocked"), m_localLocked}});
sendPacket(np);
}
void LockDevicePlugin::connected()

View file

@ -11,7 +11,8 @@
#include <core/kdeconnectplugin.h>
class OrgFreedesktopScreenSaverInterface;
#include "login1dbusinterface.h"
#include "propertiesdbusinterface.h"
#define PACKET_TYPE_LOCK QStringLiteral("kdeconnect.lock")
#define PACKET_TYPE_LOCK_REQUEST QStringLiteral("kdeconnect.lock.request")
@ -35,14 +36,17 @@ public:
bool receivePacket(const NetworkPacket & np) override;
Q_SIGNALS:
void lockedChanged(bool locked);
Q_SCRIPTABLE void lockedChanged(bool locked);
private:
void sendState();
bool m_remoteLocked;
bool m_localLocked = false;
OrgFreedesktopScreenSaverInterface* iface();
OrgFreedesktopScreenSaverInterface* m_iface;
OrgFreedesktopLogin1SessionInterface m_login1Interface;
OrgFreedesktopDBusPropertiesInterface m_propertiesInterface;
};
#endif

View file

@ -0,0 +1,26 @@
<?xml version="1.0" ?>
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="GetAll">
<arg type="s" name="interface_name" direction="in"/>
<arg type="a{sv}" name="properties" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
</method>
<method name="Set">
<arg type="s" name="interface_name" direction="in"/>
<arg type="s" name="property_name" direction="in"/>
<arg type="v" name="value" direction="in"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/>
</signal>
</interface>
</node>

View file

@ -0,0 +1,15 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.Session">
<property name="LockedHint" type="b" access="read">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</property>
<property name="Name" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<method name="Lock"/>
<method name="Unlock"/>
</interface>
</node>