2023-04-17 11:31:17 +08:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2023, KylinSoft Co., Ltd.
|
|
|
|
|
*
|
|
|
|
|
* 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 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
*
|
|
|
|
|
* Authors: iaom <zhangpengfei@kylinos.cn>
|
|
|
|
|
*/
|
|
|
|
|
|
2023-01-31 17:39:14 +08:00
|
|
|
|
#include <QDBusServiceWatcher>
|
|
|
|
|
#include <QDBusConnection>
|
|
|
|
|
#include "server.h"
|
|
|
|
|
#include "server-private.h"
|
|
|
|
|
#include "notificationsadaptor.h"
|
2023-02-09 13:54:53 +08:00
|
|
|
|
#include "notificationserveradaptor.h"
|
|
|
|
|
#include "notification-server-config.h"
|
2023-02-13 17:10:55 +08:00
|
|
|
|
#include "utils.h"
|
2023-03-08 16:57:51 +08:00
|
|
|
|
#include "notification-close-reason.h"
|
2023-03-15 14:42:54 +08:00
|
|
|
|
#include "notification-settings/settings-manager.h"
|
2023-01-31 17:39:14 +08:00
|
|
|
|
|
2023-02-03 18:01:06 +08:00
|
|
|
|
using namespace NotificationServer;
|
2023-02-17 16:54:45 +08:00
|
|
|
|
|
2023-01-31 17:39:14 +08:00
|
|
|
|
ServerPrivate::ServerPrivate(QObject *parent) : QObject(parent), m_notificationWatchers(new QDBusServiceWatcher(this))
|
|
|
|
|
{
|
|
|
|
|
m_notificationWatchers->setConnection(QDBusConnection::sessionBus());
|
|
|
|
|
m_notificationWatchers->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
|
2023-02-03 18:01:06 +08:00
|
|
|
|
connect(m_notificationWatchers, &QDBusServiceWatcher::serviceUnregistered,
|
|
|
|
|
m_notificationWatchers, &QDBusServiceWatcher::removeWatchedService);
|
2023-01-31 17:39:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2023-02-03 18:01:06 +08:00
|
|
|
|
uint id = 0;
|
|
|
|
|
if(replaces_id > 0) {
|
|
|
|
|
id = replaces_id;
|
|
|
|
|
} else {
|
|
|
|
|
id = m_increasedNotificationId++;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-17 16:54:45 +08:00
|
|
|
|
QVariantMap newHints = hints;
|
2023-04-28 11:16:14 +08:00
|
|
|
|
newHints.insert(QStringLiteral("x-ukui-createdTime"), QDateTime::currentDateTime().toString());
|
2023-02-17 16:54:45 +08:00
|
|
|
|
|
2023-02-13 17:10:55 +08:00
|
|
|
|
uint pid = 0;
|
|
|
|
|
QDBusReply<uint> 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));
|
|
|
|
|
}
|
2023-04-18 10:52:18 +08:00
|
|
|
|
//如果desktop-entry只有文件名,需要获取全路径
|
|
|
|
|
QString desktopEntry = newHints.value(QStringLiteral("desktop-entry")).toString();
|
|
|
|
|
if(!desktopEntry.isEmpty()) {
|
|
|
|
|
desktopEntry = UkuiNotification::Utils::desktopEntryFromName(desktopEntry);
|
2023-02-13 17:10:55 +08:00
|
|
|
|
}
|
2023-04-18 10:52:18 +08:00
|
|
|
|
if(desktopEntry.isEmpty() && pid > 0) {
|
|
|
|
|
desktopEntry = UkuiNotification::Utils::desktopEntryFromPid(pid);
|
|
|
|
|
}
|
|
|
|
|
newHints.insert(QStringLiteral("desktop-entry"), desktopEntry);
|
2023-02-03 18:01:06 +08:00
|
|
|
|
|
2023-02-17 16:54:45 +08:00
|
|
|
|
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;
|
2023-05-30 11:25:05 +08:00
|
|
|
|
m_notificationsCache.insert(id, notification);
|
2023-02-17 16:54:45 +08:00
|
|
|
|
return id;
|
|
|
|
|
}
|
2023-02-03 18:01:06 +08:00
|
|
|
|
for(const QString &service : m_notificationWatchers->watchedServices()) {
|
|
|
|
|
QDBusMessage msg = QDBusMessage::createMethodCall(service,
|
|
|
|
|
QStringLiteral("/NotificationClient"),
|
|
|
|
|
QStringLiteral("org.ukui.NotificationClient"),
|
|
|
|
|
QStringLiteral("Notify"));
|
2023-02-13 17:10:55 +08:00
|
|
|
|
msg.setArguments({app_name, id, app_icon, summary, body, actions, newHints, timeout});
|
2023-02-03 18:01:06 +08:00
|
|
|
|
QDBusConnection::sessionBus().call(msg, QDBus::NoBlock);
|
|
|
|
|
}
|
|
|
|
|
return id;
|
2023-01-31 17:39:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-06 17:03:12 +08:00
|
|
|
|
QString ServerPrivate::GetServerInformation(QString &vendor, QString &version, QString &spec_version) const
|
2023-01-31 17:39:14 +08:00
|
|
|
|
{
|
2023-02-09 13:54:53 +08:00
|
|
|
|
vendor = QStringLiteral("Kylin");
|
|
|
|
|
version = QLatin1String(NOTIFICATION_SERVER_VERSION);
|
|
|
|
|
spec_version = QStringLiteral("1.2");
|
|
|
|
|
return QStringLiteral("UKUI");
|
2023-01-31 17:39:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ServerPrivate::CloseNotification(uint id)
|
|
|
|
|
{
|
2023-11-20 14:54:05 +08:00
|
|
|
|
if(m_notificationsCache.contains(id)) {
|
|
|
|
|
m_notificationsCache.remove(id);
|
2023-02-03 18:01:06 +08:00
|
|
|
|
}
|
2023-11-20 14:54:05 +08:00
|
|
|
|
qDebug() << "CloseNotification(Revoked)" << id;
|
|
|
|
|
Q_EMIT NotificationClosed(id, UkuiNotification::NotificationCloseReason::Revoked);
|
2023-01-31 17:39:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ServerPrivate::init()
|
|
|
|
|
{
|
|
|
|
|
new NotificationsAdaptor(this);
|
2023-02-09 13:54:53 +08:00
|
|
|
|
new NotificationServerAdaptor(this);
|
2023-02-01 18:08:11 +08:00
|
|
|
|
QDBusConnection conn = QDBusConnection::sessionBus();
|
|
|
|
|
auto registration = conn.interface()->registerService(notificationServiceName(),
|
|
|
|
|
QDBusConnectionInterface::ReplaceExistingService,
|
|
|
|
|
QDBusConnectionInterface::DontAllowReplacement);
|
2023-01-31 17:39:14 +08:00
|
|
|
|
if (registration.value() != QDBusConnectionInterface::ServiceRegistered) {
|
|
|
|
|
qWarning() << "Failed to register Notification service on DBus!";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2023-02-01 18:08:11 +08:00
|
|
|
|
if(!conn.registerObject(notificationServicePath(), this)) {
|
2023-02-09 13:54:53 +08:00
|
|
|
|
qWarning() << "Failed to register Notification DBus object!" << conn.lastError().message();
|
2023-02-01 18:08:11 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2023-03-15 14:42:54 +08:00
|
|
|
|
UkuiNotification::SettingsManager::self();
|
2023-01-31 17:39:14 +08:00
|
|
|
|
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());
|
2023-02-09 13:54:53 +08:00
|
|
|
|
qDebug() << "Watched services:" << m_notificationWatchers->watchedServices();
|
2023-02-17 16:54:45 +08:00
|
|
|
|
sendCache();
|
2023-01-31 17:39:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ServerPrivate::UnRegisterClient()
|
|
|
|
|
{
|
|
|
|
|
m_notificationWatchers->removeWatchedService(message().service());
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-06 17:03:12 +08:00
|
|
|
|
void ServerPrivate::CloseNotification(uint id, uint reason)
|
2023-02-03 18:01:06 +08:00
|
|
|
|
{
|
2023-05-30 11:25:05 +08:00
|
|
|
|
if(m_notificationsCache.contains(id)) {
|
|
|
|
|
m_notificationsCache.remove(id);
|
|
|
|
|
}
|
2023-11-14 16:37:11 +08:00
|
|
|
|
qDebug() << "CloseNotification" << id << reason;
|
2023-02-06 17:03:12 +08:00
|
|
|
|
Q_EMIT NotificationClosed(id, reason);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-17 16:54:45 +08:00
|
|
|
|
void ServerPrivate::InvokeAction(uint id, const QString &action_key)
|
2023-02-06 17:03:12 +08:00
|
|
|
|
{
|
2023-02-17 16:54:45 +08:00
|
|
|
|
qDebug() << "InvokeAction" << id << action_key;
|
2023-02-06 17:03:12 +08:00
|
|
|
|
Q_EMIT ActionInvoked(id, action_key);
|
2023-02-03 18:01:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-17 16:54:45 +08:00
|
|
|
|
void ServerPrivate::sendCache()
|
|
|
|
|
{
|
2023-05-30 11:25:05 +08:00
|
|
|
|
for(const uint &id : m_notificationsCache.keys()) {
|
|
|
|
|
auto notification = m_notificationsCache.take(id);
|
2023-02-17 16:54:45 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-20 18:08:44 +08:00
|
|
|
|
void ServerPrivate::UpdateUnreadMessagesNumber(const QString &desktopEntry, uint number)
|
|
|
|
|
{
|
|
|
|
|
Q_EMIT UnreadMessageNumberUpdated(desktopEntry, number);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-31 17:39:14 +08:00
|
|
|
|
Server::Server(QObject *parent): QObject(parent), d(new ServerPrivate(this))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Server &Server::self()
|
|
|
|
|
{
|
|
|
|
|
static Server self;
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Server::init()
|
|
|
|
|
{
|
|
|
|
|
return d->init();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-15 14:42:54 +08:00
|
|
|
|
Server::~Server() = default;
|