// // Created by zpf on 23-1-31. // #include #include #include "server.h" #include "server-private.h" #include "notificationsadaptor.h" #include "notificationserveradaptor.h" #include "notification-server-config.h" #include "utils.h" #include "notification-close-reason.h" #include "notification-settings/settings-manager.h" using namespace NotificationServer; ServerPrivate::ServerPrivate(QObject *parent) : QObject(parent), m_notificationWatchers(new QDBusServiceWatcher(this)) { m_notificationWatchers->setConnection(QDBusConnection::sessionBus()); m_notificationWatchers->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); connect(m_notificationWatchers, &QDBusServiceWatcher::serviceUnregistered, m_notificationWatchers, &QDBusServiceWatcher::removeWatchedService); } ServerPrivate::~ServerPrivate() = default; QStringList ServerPrivate::GetCapabilities() const { return QStringList(); } uint ServerPrivate::Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantMap &hints, int timeout) { uint id = 0; if(replaces_id > 0) { id = replaces_id; } else { id = m_increasedNotificationId++; } QVariantMap newHints = hints; newHints.insert(QStringLiteral("x-ukui-createdTime"), QDateTime::currentDateTimeUtc()); uint pid = 0; QDBusReply pidReply = connection().interface()->servicePid(message().service()); if(pidReply.isValid()) { pid = pidReply.value(); } if(newHints.value(QStringLiteral("x-ukui-display")).toString().isEmpty() && pid > 0) { newHints.insert(QStringLiteral("x-ukui-display"), UkuiNotification::Utils::displayFromPid(pid)); } if(newHints.value(QStringLiteral("desktop-entry")).toString().isEmpty() && pid > 0) { newHints.insert(QStringLiteral("desktop-entry"), UkuiNotification::Utils::desktopEntryFromPid(pid)); } qDebug() << "New message received:" << app_name << id << app_icon << summary << body << actions << hints << timeout << "new hints" << newHints; if(m_notificationWatchers->watchedServices().isEmpty()) { Notification notification; notification.m_appName = app_name; notification.m_id = id; notification.m_appIcon = app_icon; notification.m_summary = summary; notification.m_body = body; notification.m_actions = actions; notification.m_hints = newHints; m_notificationsCache.append(notification); return id; } for(const QString &service : m_notificationWatchers->watchedServices()) { QDBusMessage msg = QDBusMessage::createMethodCall(service, QStringLiteral("/NotificationClient"), QStringLiteral("org.ukui.NotificationClient"), QStringLiteral("Notify")); msg.setArguments({app_name, id, app_icon, summary, body, actions, newHints, timeout}); QDBusConnection::sessionBus().call(msg, QDBus::NoBlock); } return id; } QString ServerPrivate::GetServerInformation(QString &vendor, QString &version, QString &spec_version) const { vendor = QStringLiteral("Kylin"); version = QLatin1String(NOTIFICATION_SERVER_VERSION); spec_version = QStringLiteral("1.2"); return QStringLiteral("UKUI"); } void ServerPrivate::CloseNotification(uint id) { for(const QString &service : m_notificationWatchers->watchedServices()) { QDBusMessage msg = QDBusMessage::createMethodCall(service, QStringLiteral("/NotificationClient"), QStringLiteral("org.ukui.NotificationClient"), QStringLiteral("CloseNotification")); msg.setArguments({id, UkuiNotification::NotificationCloseReason::Revoked}); QDBusConnection::sessionBus().call(msg, QDBus::NoBlock); } } bool ServerPrivate::init() { new NotificationsAdaptor(this); new NotificationServerAdaptor(this); QDBusConnection conn = QDBusConnection::sessionBus(); auto registration = conn.interface()->registerService(notificationServiceName(), QDBusConnectionInterface::ReplaceExistingService, QDBusConnectionInterface::DontAllowReplacement); if (registration.value() != QDBusConnectionInterface::ServiceRegistered) { qWarning() << "Failed to register Notification service on DBus!"; return false; } if(!conn.registerObject(notificationServicePath(), this)) { qWarning() << "Failed to register Notification DBus object!" << conn.lastError().message(); return false; } UkuiNotification::SettingsManager::self(); return true; } QString ServerPrivate::notificationServiceName() { return QStringLiteral("org.freedesktop.Notifications"); } QString ServerPrivate::notificationServicePath() { return QStringLiteral("/org/freedesktop/Notifications"); } QString ServerPrivate::notificationServiceInterface() { return QStringLiteral("org.freedesktop.Notifications");; } void ServerPrivate::RegisterClient() { m_notificationWatchers->addWatchedService(message().service()); qDebug() << "Watched services:" << m_notificationWatchers->watchedServices(); sendCache(); } void ServerPrivate::UnRegisterClient() { m_notificationWatchers->removeWatchedService(message().service()); } void ServerPrivate::CloseNotification(uint id, uint reason) { Q_EMIT NotificationClosed(id, reason); } void ServerPrivate::InvokeAction(uint id, const QString &action_key) { qDebug() << "InvokeAction" << id << action_key; Q_EMIT ActionInvoked(id, action_key); } void ServerPrivate::sendCache() { while(!m_notificationsCache.isEmpty()) { auto notification = m_notificationsCache.takeFirst(); for(const QString &service : m_notificationWatchers->watchedServices()) { QDBusMessage msg = QDBusMessage::createMethodCall(service, QStringLiteral("/NotificationClient"), QStringLiteral("org.ukui.NotificationClient"), QStringLiteral("Notify")); msg.setArguments({notification.m_appName, notification.m_id, notification.m_appIcon, notification.m_summary, notification.m_body, notification.m_actions, notification.m_hints, notification.m_timeout}); QDBusConnection::sessionBus().call(msg, QDBus::NoBlock); } } } Server::Server(QObject *parent): QObject(parent), d(new ServerPrivate(this)) { } Server &Server::self() { static Server self; return self; } bool Server::init() { return d->init(); } Server::~Server() = default;