notifications: add initial support for desktop-to-xxx notifications
Eavesdrop on the Notify call of the org.freedesktop.Notifications dbus-interface, proxy all caught notifications to our peer device and track them in the internal notifications-list. Also fix "cancel" requests from peer devices, by cutting of kdeconnect-android's id-prefix.
This commit is contained in:
parent
2ca1d9720e
commit
2a74eb68f8
7 changed files with 171 additions and 3 deletions
|
@ -4,6 +4,7 @@ set(kdeconnect_notifications_SRCS
|
|||
notification.cpp
|
||||
notificationsplugin.cpp
|
||||
notificationsdbusinterface.cpp
|
||||
notificationslistener.cpp
|
||||
)
|
||||
|
||||
kdeconnect_add_plugin(kdeconnect_notifications JSON kdeconnect_notifications.json SOURCES ${kdeconnect_notifications_SRCS})
|
||||
|
|
|
@ -45,6 +45,7 @@ NotificationsDbusInterface::NotificationsDbusInterface(KdeConnectPlugin* plugin)
|
|||
|
||||
NotificationsDbusInterface::~NotificationsDbusInterface()
|
||||
{
|
||||
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Destroying NotificationsDbusInterface";
|
||||
}
|
||||
|
||||
void NotificationsDbusInterface::clearNotifications()
|
||||
|
@ -60,7 +61,21 @@ QStringList NotificationsDbusInterface::activeNotifications()
|
|||
void NotificationsDbusInterface::processPackage(const NetworkPackage& np)
|
||||
{
|
||||
if (np.get<bool>("isCancel")) {
|
||||
removeNotification(np.get<QString>("id"));
|
||||
QString id = np.get<QString>("id");
|
||||
// cut off kdeconnect-android's prefix if there:
|
||||
if (id.startsWith("org.kde.kdeconnect_tp::"))
|
||||
id = id.mid(id.indexOf("::") + 2);
|
||||
removeNotification(id);
|
||||
} else if (np.get<bool>("isRequest")) {
|
||||
for (const auto& n: mNotifications) {
|
||||
NetworkPackage np(PACKAGE_TYPE_NOTIFICATION);
|
||||
np.set("id", n->internalId());
|
||||
np.set("appName", n->appName());
|
||||
np.set("ticker", n->ticker());
|
||||
np.set("isClearable", n->dismissable());
|
||||
np.set("requestAnswer", true);
|
||||
mPlugin->sendPackage(np);
|
||||
}
|
||||
} else {
|
||||
|
||||
//TODO: Uncoment when we are able to display app icon on plasmoid
|
||||
|
@ -114,7 +129,7 @@ void NotificationsDbusInterface::removeNotification(const QString& internalId)
|
|||
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "removeNotification" << internalId;
|
||||
|
||||
if (!mInternalIdToPublicId.contains(internalId)) {
|
||||
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Not found";
|
||||
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Not found: " << internalId;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
void processPackage(const NetworkPackage& np);
|
||||
void clearNotifications();
|
||||
void dismissRequested(const QString& notification);
|
||||
void addNotification(Notification* noti);
|
||||
|
||||
public Q_SLOTS:
|
||||
Q_SCRIPTABLE QStringList activeNotifications();
|
||||
|
@ -54,7 +55,6 @@ Q_SIGNALS:
|
|||
Q_SCRIPTABLE void notificationRemoved(const QString& publicId);
|
||||
|
||||
private /*methods*/:
|
||||
void addNotification(Notification* noti);
|
||||
void removeNotification(const QString& internalId);
|
||||
QString newId(); //Generates successive identifitiers to use as public ids
|
||||
|
||||
|
|
101
plugins/notifications/notificationslistener.cpp
Normal file
101
plugins/notifications/notificationslistener.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* Copyright 2015 Holger Kaelberer <holger.k@elberer.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QtDBus/QDBusConnection>
|
||||
#include <QtDBus/QDBusInterface>
|
||||
#include <QtDebug>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include <core/device.h>
|
||||
#include <core/kdeconnectplugin.h>
|
||||
|
||||
#include "notificationslistener.h"
|
||||
#include "notificationsplugin.h"
|
||||
#include "notification_debug.h"
|
||||
#include "notificationsdbusinterface.h"
|
||||
|
||||
NotificationsListener::NotificationsListener(KdeConnectPlugin* aPlugin,
|
||||
NotificationsDbusInterface* aDbusInterface)
|
||||
: QDBusAbstractAdaptor(aPlugin),
|
||||
mPlugin(aPlugin),
|
||||
dbusInterface(aDbusInterface)
|
||||
{
|
||||
bool ret = QDBusConnection::sessionBus()
|
||||
.registerObject("/org/freedesktop/Notifications",
|
||||
this,
|
||||
QDBusConnection::ExportScriptableContents);
|
||||
if (!ret)
|
||||
qCWarning(KDECONNECT_PLUGIN_NOTIFICATION)
|
||||
<< "Error registering notifications listener for device"
|
||||
<< mPlugin->device()->name() << ":"
|
||||
<< QDBusConnection::sessionBus().lastError();
|
||||
else
|
||||
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION)
|
||||
<< "Registered notifications listener for device"
|
||||
<< mPlugin->device()->name();
|
||||
|
||||
QDBusInterface iface("org.freedesktop.DBus", "/org/freedesktop/DBus",
|
||||
"org.freedesktop.DBus");
|
||||
iface.call("AddMatch",
|
||||
"interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'");
|
||||
}
|
||||
|
||||
NotificationsListener::~NotificationsListener()
|
||||
{
|
||||
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Destroying NotificationsListener";
|
||||
QDBusInterface iface("org.freedesktop.DBus", "/org/freedesktop/DBus",
|
||||
"org.freedesktop.DBus");
|
||||
QDBusMessage res = iface.call("RemoveMatch",
|
||||
"interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'");
|
||||
QDBusConnection::sessionBus().unregisterObject("/org/freedesktop/Notifications");
|
||||
}
|
||||
|
||||
uint NotificationsListener::Notify(const QString &appName, uint replacesId,
|
||||
const QString &appIcon,
|
||||
const QString &summary, const QString &body,
|
||||
const QStringList &actions,
|
||||
const QVariantMap &hints, int timeout)
|
||||
{
|
||||
static int id = 0;
|
||||
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Got notification appName=" << appName << "replacesId=" << replacesId << "appIcon=" << appIcon << "summary=" << summary << "body=" << body << "actions=" << actions << "hints=" << hints << "timeout=" << timeout;
|
||||
Q_UNUSED(hints);
|
||||
Q_UNUSED(actions);
|
||||
Q_UNUSED(appIcon);
|
||||
Q_UNUSED(body);
|
||||
|
||||
// skip our own notifications
|
||||
if (appName == QLatin1String("KDE Connect"))
|
||||
return 0;
|
||||
|
||||
NetworkPackage np(PACKAGE_TYPE_NOTIFICATION);
|
||||
np.set("id", QString::number(replacesId > 0 ? replacesId : ++id));
|
||||
np.set("appName", appName);
|
||||
np.set("ticker", summary);
|
||||
np.set("isClearable", timeout == 0); // KNotifications are persistent if
|
||||
// timeout == 0, for other notifications
|
||||
// clearability is pointless
|
||||
|
||||
Notification *notification = new Notification(np, QString(), this);
|
||||
dbusInterface->addNotification(notification);
|
||||
|
||||
mPlugin->sendPackage(np);
|
||||
|
||||
return (replacesId > 0 ? replacesId : id);
|
||||
}
|
46
plugins/notifications/notificationslistener.h
Normal file
46
plugins/notifications/notificationslistener.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Copyright 2015 Holger Kaelberer <holger.k@elberer.de>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QtDBus/QDBusAbstractAdaptor>
|
||||
#include <core/device.h>
|
||||
|
||||
class KdeConnectPlugin;
|
||||
class NotificationsDbusInterface;
|
||||
class Notification;
|
||||
|
||||
class NotificationsListener : public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Notifications")
|
||||
|
||||
public:
|
||||
explicit NotificationsListener(KdeConnectPlugin* aPlugin,
|
||||
NotificationsDbusInterface* aDbusInterface);
|
||||
virtual ~NotificationsListener();
|
||||
|
||||
private:
|
||||
KdeConnectPlugin* mPlugin;
|
||||
NotificationsDbusInterface* dbusInterface;
|
||||
|
||||
public Q_SLOTS:
|
||||
Q_SCRIPTABLE uint Notify(const QString&, uint, const QString&,
|
||||
const QString&, const QString&,
|
||||
const QStringList&, const QVariantMap&, int);
|
||||
};
|
|
@ -21,6 +21,7 @@
|
|||
#include "notificationsplugin.h"
|
||||
|
||||
#include "notificationsdbusinterface.h"
|
||||
#include "notificationslistener.h"
|
||||
#include "notification_debug.h"
|
||||
|
||||
#include <KPluginFactory>
|
||||
|
@ -33,6 +34,7 @@ NotificationsPlugin::NotificationsPlugin(QObject* parent, const QVariantList& ar
|
|||
: KdeConnectPlugin(parent, args)
|
||||
{
|
||||
notificationsDbusInterface = new NotificationsDbusInterface(this);
|
||||
notificationsListener = new NotificationsListener(this, notificationsDbusInterface);
|
||||
}
|
||||
|
||||
void NotificationsPlugin::connected()
|
||||
|
@ -44,6 +46,7 @@ void NotificationsPlugin::connected()
|
|||
|
||||
NotificationsPlugin::~NotificationsPlugin()
|
||||
{
|
||||
qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Destroying NotificationsPlugin";
|
||||
//FIXME: Qt dbus does not allow to remove an adaptor! (it causes a crash in
|
||||
// the next dbus access to its parent). The implication of not deleting this
|
||||
// is that disabling the plugin leaks the interface. As a mitigation we are
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
* KdeConnectPlugin at the same time (both are QObject)
|
||||
*/
|
||||
class NotificationsDbusInterface;
|
||||
class NotificationsListener;
|
||||
|
||||
class NotificationsPlugin
|
||||
: public KdeConnectPlugin
|
||||
|
@ -48,6 +49,7 @@ public Q_SLOTS:
|
|||
|
||||
private:
|
||||
NotificationsDbusInterface* notificationsDbusInterface;
|
||||
NotificationsListener* notificationsListener;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue