Changeset View
Changeset View
Standalone View
Standalone View
libnotificationmanager/server_p.cpp
Show All 17 Lines | |||||
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | 18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | #include "server_p.h" | 21 | #include "server_p.h" | ||
22 | 22 | | |||
23 | #include "debug.h" | 23 | #include "debug.h" | ||
24 | 24 | | |||
25 | #include "notificationsadaptor.h" | 25 | #include "notificationsadaptor.h" | ||
26 | #include "notificationmanageradaptor.h" | ||||
26 | 27 | | |||
27 | #include "notification.h" | 28 | #include "notification.h" | ||
28 | #include "notification_p.h" | 29 | #include "notification_p.h" | ||
29 | 30 | | |||
30 | #include "server.h" | 31 | #include "server.h" | ||
31 | #include "serverinfo.h" | 32 | #include "serverinfo.h" | ||
32 | 33 | | |||
33 | #include "utils_p.h" | 34 | #include "utils_p.h" | ||
34 | 35 | | |||
35 | #include <QDBusConnection> | 36 | #include <QDBusConnection> | ||
36 | #include <QDBusServiceWatcher> | 37 | #include <QDBusServiceWatcher> | ||
37 | 38 | | |||
38 | #include <KConfigGroup> | 39 | #include <KConfigGroup> | ||
39 | #include <KService> | 40 | #include <KService> | ||
40 | #include <KSharedConfig> | 41 | #include <KSharedConfig> | ||
41 | #include <KUser> | 42 | #include <KUser> | ||
42 | 43 | | |||
43 | using namespace NotificationManager; | 44 | using namespace NotificationManager; | ||
44 | 45 | | |||
45 | ServerPrivate::ServerPrivate(QObject *parent) | 46 | ServerPrivate::ServerPrivate(QObject *parent) | ||
46 | : QObject(parent) | 47 | : QObject(parent) | ||
47 | , m_inhibitionWatcher(new QDBusServiceWatcher(this)) | 48 | , m_inhibitionWatcher(new QDBusServiceWatcher(this)) | ||
49 | , m_notificationWatchers (new QDBusServiceWatcher(this)) | ||||
48 | { | 50 | { | ||
49 | m_inhibitionWatcher->setConnection(QDBusConnection::sessionBus()); | 51 | m_inhibitionWatcher->setConnection(QDBusConnection::sessionBus()); | ||
50 | m_inhibitionWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); | 52 | m_inhibitionWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); | ||
51 | connect(m_inhibitionWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &ServerPrivate::onInhibitionServiceUnregistered); | 53 | connect(m_inhibitionWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &ServerPrivate::onInhibitionServiceUnregistered); | ||
54 | | ||||
55 | m_notificationWatchers->setConnection(QDBusConnection::sessionBus()); | ||||
56 | m_notificationWatchers->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); | ||||
57 | connect(m_notificationWatchers, &QDBusServiceWatcher::serviceUnregistered, [=](const QString &service) { | ||||
58 | m_notificationWatchers->removeWatchedService(service); | ||||
59 | }); | ||||
52 | } | 60 | } | ||
53 | 61 | | |||
54 | ServerPrivate::~ServerPrivate() = default; | 62 | ServerPrivate::~ServerPrivate() = default; | ||
55 | 63 | | |||
56 | QString ServerPrivate::notificationServiceName() | 64 | QString ServerPrivate::notificationServiceName() | ||
57 | { | 65 | { | ||
58 | return QStringLiteral("org.freedesktop.Notifications"); | 66 | return QStringLiteral("org.freedesktop.Notifications"); | ||
59 | } | 67 | } | ||
Show All 19 Lines | |||||
79 | 87 | | |||
80 | bool ServerPrivate::init() | 88 | bool ServerPrivate::init() | ||
81 | { | 89 | { | ||
82 | if (m_valid) { | 90 | if (m_valid) { | ||
83 | return true; | 91 | return true; | ||
84 | } | 92 | } | ||
85 | 93 | | |||
86 | new NotificationsAdaptor(this); | 94 | new NotificationsAdaptor(this); | ||
95 | new NotificationManagerAdaptor(this); | ||||
87 | 96 | | |||
88 | if (!m_dbusObjectValid) { // if already registered, don't fail here | 97 | if (!m_dbusObjectValid) { // if already registered, don't fail here | ||
89 | m_dbusObjectValid = QDBusConnection::sessionBus().registerObject(notificationServicePath(), this); | 98 | m_dbusObjectValid = QDBusConnection::sessionBus().registerObject(notificationServicePath(), this); | ||
90 | } | 99 | } | ||
91 | 100 | | |||
92 | if (!m_dbusObjectValid) { | 101 | if (!m_dbusObjectValid) { | ||
93 | qCWarning(NOTIFICATIONMANAGER) << "Failed to register Notification DBus object"; | 102 | qCWarning(NOTIFICATIONMANAGER) << "Failed to register Notification DBus object"; | ||
94 | return false; | 103 | return false; | ||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Line(s) | 149 | { | |||
218 | 227 | | |||
219 | if (wasReplaced) { | 228 | if (wasReplaced) { | ||
220 | notification.resetUpdated(); | 229 | notification.resetUpdated(); | ||
221 | emit static_cast<Server*>(parent())->notificationReplaced(replaces_id, notification); | 230 | emit static_cast<Server*>(parent())->notificationReplaced(replaces_id, notification); | ||
222 | } else { | 231 | } else { | ||
223 | emit static_cast<Server*>(parent())->notificationAdded(notification); | 232 | emit static_cast<Server*>(parent())->notificationAdded(notification); | ||
224 | } | 233 | } | ||
225 | 234 | | |||
235 | // currently we dispatch all notification, this is ugly | ||||
236 | // TODO: come up with proper authentication/user selection | ||||
237 | for (const QString &service : m_notificationWatchers->watchedServices()) { | ||||
broulik: `const QString &service : qAsConst(m_notificationWatchers)` | |||||
238 | QDBusMessage msg = QDBusMessage::createMethodCall( | ||||
broulik: Remove, or use categorized logging | |||||
239 | service, | ||||
broulik: Can you use generated XML interface for this, maybe? | |||||
bshah: It would introduce weird dependency loop so I'd rather not. | |||||
240 | QStringLiteral("/NotificationWatcher"), | ||||
241 | QStringLiteral("org.kde.NotificationWatcher"), | ||||
242 | QStringLiteral("Notify") | ||||
243 | ); | ||||
244 | msg.setArguments({ | ||||
245 | notificationId, | ||||
246 | notification.applicationName(), | ||||
247 | replaces_id, | ||||
248 | notification.applicationIconName(), | ||||
249 | notification.summary(), | ||||
250 | // we pass raw body data since this data goes through another sanitization | ||||
251 | // in WatchedNotificationsModel when notification object is created. | ||||
252 | notification.rawBody(), | ||||
253 | notification.actionNames(), | ||||
254 | hints, | ||||
255 | notification.timeout() | ||||
256 | }); | ||||
broulik: Don't block | |||||
257 | QDBusConnection::sessionBus().call(msg, QDBus::NoBlock); | ||||
258 | } | ||||
259 | | ||||
226 | return notificationId; | 260 | return notificationId; | ||
227 | } | 261 | } | ||
228 | 262 | | |||
229 | void ServerPrivate::CloseNotification(uint id) | 263 | void ServerPrivate::CloseNotification(uint id) | ||
230 | { | 264 | { | ||
265 | for (const QString &service : m_notificationWatchers->watchedServices()) { | ||||
266 | QDBusMessage msg = QDBusMessage::createMethodCall( | ||||
267 | service, | ||||
268 | QStringLiteral("/NotificationWatcher"), | ||||
269 | QStringLiteral("org.kde.NotificationWatcher"), | ||||
270 | QStringLiteral("CloseNotification") | ||||
271 | ); | ||||
272 | msg.setArguments({ | ||||
273 | id | ||||
274 | }); | ||||
275 | QDBusConnection::sessionBus().call(msg, QDBus::NoBlock); | ||||
276 | } | ||||
231 | // spec says "If the notification no longer exists, an empty D-BUS Error message is sent back." | 277 | // spec says "If the notification no longer exists, an empty D-BUS Error message is sent back." | ||
232 | static_cast<Server*>(parent())->closeNotification(id, Server::CloseReason::Revoked); | 278 | static_cast<Server*>(parent())->closeNotification(id, Server::CloseReason::Revoked); | ||
broulik: Same as above | |||||
233 | } | 279 | } | ||
234 | 280 | | |||
235 | QStringList ServerPrivate::GetCapabilities() const | 281 | QStringList ServerPrivate::GetCapabilities() const | ||
236 | { | 282 | { | ||
237 | // should this be configurable somehow so the UI can tell what it implements? | 283 | // should this be configurable somehow so the UI can tell what it implements? | ||
broulik: Don't we want to adhere to an interface? | |||||
238 | return QStringList{ | 284 | return QStringList{ | ||
239 | QStringLiteral("body"), | 285 | QStringLiteral("body"), | ||
240 | QStringLiteral("body-hyperlinks"), | 286 | QStringLiteral("body-hyperlinks"), | ||
241 | QStringLiteral("body-markup"), | 287 | QStringLiteral("body-markup"), | ||
242 | QStringLiteral("body-images"), | 288 | QStringLiteral("body-images"), | ||
243 | QStringLiteral("icon-static"), | 289 | QStringLiteral("icon-static"), | ||
244 | QStringLiteral("actions"), | 290 | QStringLiteral("actions"), | ||
245 | QStringLiteral("inline-reply"), | 291 | QStringLiteral("inline-reply"), | ||
▲ Show 20 Lines • Show All 231 Lines • ▼ Show 20 Line(s) | 519 | { | |||
477 | 523 | | |||
478 | m_inhibitionWatcher->setWatchedServices(QStringList()); // remove all watches | 524 | m_inhibitionWatcher->setWatchedServices(QStringList()); // remove all watches | ||
479 | m_inhibitionServices.clear(); | 525 | m_inhibitionServices.clear(); | ||
480 | m_externalInhibitions.clear(); | 526 | m_externalInhibitions.clear(); | ||
481 | 527 | | |||
482 | emit externalInhibitedChanged(); | 528 | emit externalInhibitedChanged(); | ||
483 | emit externalInhibitionsChanged(); | 529 | emit externalInhibitionsChanged(); | ||
484 | } | 530 | } | ||
531 | | ||||
532 | void ServerPrivate::RegisterWatcher() | ||||
533 | { | ||||
534 | m_notificationWatchers->addWatchedService(message().service()); | ||||
535 | } | ||||
536 | | ||||
Then you can probably also use the watcher's "watched services" list rather than storing it in a member broulik: Then you can probably also use the watcher's "watched services" list rather than storing it in… | |||||
broulik: Yes, please do. | |||||
537 | void ServerPrivate::UnRegisterWatcher() | ||||
538 | { | ||||
539 | m_notificationWatchers->removeWatchedService(message().service()); | ||||
540 | } | ||||
541 | | ||||
542 | void ServerPrivate::InvokeAction(uint id, const QString& actionKey) | ||||
543 | { | ||||
544 | ActionInvoked(id, actionKey); | ||||
545 | } |
const QString &service : qAsConst(m_notificationWatchers)