diff --git a/app/qml/main.qml b/app/qml/main.qml index c2db4314b..929a7f39d 100644 --- a/app/qml/main.qml +++ b/app/qml/main.qml @@ -130,8 +130,11 @@ ApplicationWindow } ); } Button { - text: i18n("Remote touch and keyboard") - enabled: false + property var lockIface: LockDeviceDbusInterfaceFactory.create(deviceView.currentDevice.id()) + text: lockIface.isLocked ? i18n("Unlock") : i18n("Lock") + onClicked: { + lockIface.isLocked = !lockIface.isLocked; + } } Item { Layout.fillHeight: true } diff --git a/cli/kdeconnect-cli.cpp b/cli/kdeconnect-cli.cpp index 3aa49e599..536c7549f 100644 --- a/cli/kdeconnect-cli.cpp +++ b/cli/kdeconnect-cli.cpp @@ -55,6 +55,7 @@ int main(int argc, char** argv) parser.addOption(QCommandLineOption("ping-msg", i18n("Same as ping but you can set the message to display"), i18n("message"))); parser.addOption(QCommandLineOption("share", i18n("Share a file to a said device"), "path")); parser.addOption(QCommandLineOption("list-notifications", i18n("Display the notifications on a said device"))); + parser.addOption(QCommandLineOption("lock", i18n("Lock the specified device"))); parser.addOption(QCommandLineOption(QStringList("device") << "d", i18n("Device ID"), "dev")); about.setupCommandLine(&parser); diff --git a/interfaces/CMakeLists.txt b/interfaces/CMakeLists.txt index d3ca36325..f44b605b3 100644 --- a/interfaces/CMakeLists.txt +++ b/interfaces/CMakeLists.txt @@ -41,6 +41,7 @@ geninterface(${CMAKE_SOURCE_DIR}/plugins/notifications/notificationsdbusinterfac geninterface(${CMAKE_SOURCE_DIR}/plugins/notifications/notification.h notificationinterface) geninterface(${CMAKE_SOURCE_DIR}/plugins/mprisremote/mprisremoteplugin.h mprisremoteinterface) geninterface(${CMAKE_SOURCE_DIR}/plugins/remotecontrol/remotecontrolplugin.h remotecontrolinterface) +geninterface(${CMAKE_SOURCE_DIR}/plugins/lockdevice/lockdeviceplugin.h lockdeviceinterface) add_library(kdeconnectinterfaces SHARED ${libkdeconnect_SRC}) set_target_properties(kdeconnectinterfaces PROPERTIES diff --git a/interfaces/dbusinterfaces.cpp b/interfaces/dbusinterfaces.cpp index 5f5479a0e..db3ce5a80 100644 --- a/interfaces/dbusinterfaces.cpp +++ b/interfaces/dbusinterfaces.cpp @@ -122,3 +122,16 @@ RemoteControlDbusInterface::RemoteControlDbusInterface(const QString& id, QObjec RemoteControlDbusInterface::~RemoteControlDbusInterface() { } + +LockDeviceDbusInterface::LockDeviceDbusInterface(const QString& id, QObject* parent) + : OrgKdeKdeconnectDeviceLockdeviceInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + id + "/lockdevice", QDBusConnection::sessionBus(), parent) +{ + connect(this, &OrgKdeKdeconnectDeviceLockdeviceInterface::lockedChanged, this, &LockDeviceDbusInterface::lockedChangedProxy); + Q_ASSERT(isValid()); +} + +LockDeviceDbusInterface::~LockDeviceDbusInterface() +{ +} + +#include "dbusinterfaces.moc" diff --git a/interfaces/dbusinterfaces.h b/interfaces/dbusinterfaces.h index a2befb494..2f51599f3 100644 --- a/interfaces/dbusinterfaces.h +++ b/interfaces/dbusinterfaces.h @@ -31,6 +31,7 @@ #include "interfaces/notificationinterface.h" #include "interfaces/mprisremoteinterface.h" #include "interfaces/remotecontrolinterface.h" +#include "interfaces/lockdeviceinterface.h" /** * Using these "proxy" classes just in case we need to rename the @@ -134,4 +135,17 @@ public: ~RemoteControlDbusInterface() override; }; +class KDECONNECTINTERFACES_EXPORT LockDeviceDbusInterface + : public OrgKdeKdeconnectDeviceLockdeviceInterface +{ + Q_OBJECT + Q_PROPERTY(bool isLocked READ isLocked WRITE setIsLocked NOTIFY lockedChangedProxy) +public: + LockDeviceDbusInterface(const QString& deviceId, QObject* parent = 0); + virtual ~LockDeviceDbusInterface(); + +Q_SIGNALS: + void lockedChangedProxy(bool isLocked); +}; + #endif diff --git a/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.cpp b/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.cpp index dfa92e9af..269b7ef00 100644 --- a/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.cpp +++ b/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.cpp @@ -59,6 +59,12 @@ QObject* createMprisInterface(QVariant deviceId) return new MprisDbusInterface(deviceId.toString()); } +QObject* createDeviceLockInterface(QVariant deviceId) +{ + Q_ASSERT(!deviceId.toString().isEmpty()); + return new LockDeviceDbusInterface(deviceId.toString()); +} + QObject* createDBusResponse() { return new DBusAsyncResponse(); @@ -72,6 +78,7 @@ void KdeConnectDeclarativePlugin::registerTypes(const char* uri) qmlRegisterType(uri, 1, 0, "ProcessRunner"); qmlRegisterType(uri, 1, 0, "DevicesSortProxyModel"); qmlRegisterUncreatableType(uri, 1, 0, "MprisDbusInterface", QStringLiteral("You're not supposed to instantiate interfacess")); + qmlRegisterUncreatableType(uri, 1, 0, "LockDeviceDbusInterface", QStringLiteral("You're not supposed to instantiate interfacess")); qmlRegisterUncreatableType(uri, 1, 0, "DeviceDbusInterface", QStringLiteral("You're not supposed to instantiate interfacess")); } @@ -93,6 +100,9 @@ void KdeConnectDeclarativePlugin::initializeEngine(QQmlEngine* engine, const cha engine->rootContext()->setContextProperty("RemoteControlDbusInterfaceFactory" , new ObjectFactory(engine, createRemoteControlInterface)); + + engine->rootContext()->setContextProperty("LockDeviceDbusInterfaceFactory" + , new ObjectFactory(engine, createDeviceLockInterface)); engine->rootContext()->setContextProperty("DBusResponseFactory" , new ObjectFactory(engine, createDBusResponse)); diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 10d26e6b0..176ba174b 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory(screensaver-inhibit) if(EXPERIMENTALAPP_ENABLED) add_subdirectory(mprisremote) add_subdirectory(remotecontrol) + add_subdirectory(lockdevice) endif() #FIXME: If we split notifications in several files, they won't appear in the same group in the Notifications KCM diff --git a/plugins/lockdevice/CMakeLists.txt b/plugins/lockdevice/CMakeLists.txt new file mode 100644 index 000000000..2e7a96577 --- /dev/null +++ b/plugins/lockdevice/CMakeLists.txt @@ -0,0 +1,9 @@ +qt5_add_dbus_interface(lockdevice_SRCS org.freedesktop.ScreenSaver.xml screensaverdbusinterface) + +kdeconnect_add_plugin(kdeconnect_lockdevice JSON kdeconnect_lockdevice.json SOURCES lockdeviceplugin.cpp ${lockdevice_SRCS}) + +target_link_libraries(kdeconnect_lockdevice + kdeconnectcore + Qt5::DBus + KF5::I18n +) diff --git a/plugins/lockdevice/kdeconnect_lockdevice.json b/plugins/lockdevice/kdeconnect_lockdevice.json new file mode 100644 index 000000000..43ea901e2 --- /dev/null +++ b/plugins/lockdevice/kdeconnect_lockdevice.json @@ -0,0 +1,24 @@ +{ + "Encoding": "UTF-8", + "KPlugin": { + "Authors": [ + { + "Email": "aleixpol@kde.org", + "Name": "Aleix Pol" + } + ], + "Description": "Locks your systems", + "EnabledByDefault": true, + "Icon": "applications-miscelaneaous", + "Id": "kdeconnect_lockdevice", + "License": "GPL", + "Name": "LockDevice", + "ServiceTypes": [ + "KdeConnect/Plugin" + ], + "Version": "0.1", + "Website": "https://kde.org" + }, + "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.lock" ], + "X-KdeConnect-SupportedPackageType": [ "kdeconnect.lock" ] +} diff --git a/plugins/lockdevice/lockdeviceplugin.cpp b/plugins/lockdevice/lockdeviceplugin.cpp new file mode 100644 index 000000000..a24b66b9f --- /dev/null +++ b/plugins/lockdevice/lockdeviceplugin.cpp @@ -0,0 +1,108 @@ +/** + * Copyright 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "lockdeviceplugin.h" + +#include +#include + +#include +#include +#include +#include "screensaverdbusinterface.h" + +#include + +K_PLUGIN_FACTORY_WITH_JSON( KdeConnectLockPluginFactory, "kdeconnect_lockdevice.json", registerPlugin(); ) + +Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_LOCKREMOTE, "kdeconnect.plugin.lock") + +LockDevicePlugin::LockDevicePlugin(QObject* parent, const QVariantList& args) + : KdeConnectPlugin(parent, args) + , m_remoteLocked(false) + , m_iface(nullptr) +{ +} + +LockDevicePlugin::~LockDevicePlugin() +{ + delete m_iface; +} + +bool LockDevicePlugin::isLocked() const +{ + return m_remoteLocked; +} +void LockDevicePlugin::setLocked(bool locked) +{ + NetworkPackage np(PACKAGE_TYPE_LOCK); + np.set("setLocked", locked); + sendPackage(np); +} + +bool LockDevicePlugin::receivePackage(const NetworkPackage & np) +{ + if (np.has("isLocked")) { + bool locked = np.get("isLocked"); + if (m_remoteLocked != locked) { + m_remoteLocked = locked; + Q_EMIT lockedChanged(locked); + } + } + + bool sendState = np.has("requestLocked"); + if (np.has("setLocked")) { + iface()->SetActive(np.get("setLocked")); + sendState = true; + } + if (sendState) { + NetworkPackage np(PACKAGE_TYPE_LOCK); + np.set("isLocked", iface()->GetActive()); + sendPackage(np); + } + + return true; +} + +OrgFreedesktopScreenSaverInterface* LockDevicePlugin::iface() +{ + if (!m_iface) { + m_iface = new OrgFreedesktopScreenSaverInterface("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", QDBusConnection::sessionBus()); + if(!m_iface->isValid()) + qCWarning(KDECONNECT_PLUGIN_LOCKREMOTE) << "Couldn't connect to the ScreenSaver interface"; + } + return m_iface; +} + +void LockDevicePlugin::connected() +{ + QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportAllContents); + + NetworkPackage np(PACKAGE_TYPE_LOCK); + np.set("requestLocked", QVariant()); + sendPackage(np); +} + +QString LockDevicePlugin::dbusPath() const +{ + return "/modules/kdeconnect/devices/" + device()->id() + "/lockdevice"; +} + +#include "lockdeviceplugin.moc" diff --git a/plugins/lockdevice/lockdeviceplugin.h b/plugins/lockdevice/lockdeviceplugin.h new file mode 100644 index 000000000..834ae3a13 --- /dev/null +++ b/plugins/lockdevice/lockdeviceplugin.h @@ -0,0 +1,61 @@ +/** + * Copyright 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LOCKDEVICEPLUGIN_H +#define LOCKDEVICEPLUGIN_H + +#include + +#include + +class OrgFreedesktopScreenSaverInterface; + +#define PACKAGE_TYPE_LOCK QLatin1String("kdeconnect.lock") + +class Q_DECL_EXPORT LockDevicePlugin + : public KdeConnectPlugin +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.lockdevice") + Q_PROPERTY(bool isLocked READ isLocked WRITE setLocked NOTIFY lockedChanged) + +public: + explicit LockDevicePlugin(QObject *parent, const QVariantList &args); + virtual ~LockDevicePlugin(); + + bool isLocked() const; + void setLocked(bool b); + + void connected() override; + bool receivePackage(const NetworkPackage & np) override; + +Q_SIGNALS: + void lockedChanged(bool locked); + +private: + QString dbusPath() const; + bool m_remoteLocked; + + OrgFreedesktopScreenSaverInterface* iface(); + + OrgFreedesktopScreenSaverInterface* m_iface; +}; + +#endif diff --git a/plugins/lockdevice/org.freedesktop.ScreenSaver.xml b/plugins/lockdevice/org.freedesktop.ScreenSaver.xml new file mode 100644 index 000000000..5efd9433c --- /dev/null +++ b/plugins/lockdevice/org.freedesktop.ScreenSaver.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +