ukui-notification/libukui-notification/notification-client.cpp

185 lines
7.0 KiB
C++

//
// Created by zpf on 23-2-2.
//
#include "notification-client.h"
#include "notification-client-private.h"
#include <QDBusConnection>
#include "notificationclientadaptor.h"
using namespace UkuiNotification;
NotificationClientPrivate::NotificationClientPrivate(NotificationClient *q, QObject *parent) : QObject(parent), q(q)
{
}
NotificationClientPrivate::~NotificationClientPrivate()
{
if(m_notificationsInterface) {
m_notificationsInterface->call(QDBus::NoBlock, QStringLiteral("UnRegisterClient"));
delete m_notificationsInterface;
m_notificationsInterface = nullptr;
}
}
bool NotificationClientPrivate::init()
{
new NotificationClientAdaptor(this);
QDBusConnection conn = QDBusConnection::sessionBus();
if(!conn.registerObject(clientServicePath(), clientServiceInterface(), this)) {
qWarning() << "Failed to register NotificationClient DBus object!" << conn.lastError();
return false;
}
auto *watcher = new QDBusServiceWatcher(QStringLiteral("org.freedesktop.Notifications"),
conn,
QDBusServiceWatcher::WatchForOwnerChange,
this);
connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, [](const QString &service, const QString &oldOwner, const QString &newOwner){
qDebug() << "serviceOwnerChanged" << service << oldOwner << newOwner;
});
return registerClient();
}
bool NotificationClientPrivate::registerClient()
{
QDBusConnection conn = QDBusConnection::sessionBus();
m_notificationsInterface = new OrgFreedesktopNotificationsInterface(QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("/org/freedesktop/Notifications"),
conn);
if(!m_notificationsInterface->isValid()) {
qWarning() << "Failed to creat dbus interface for notification server!" << conn.lastError();
return false;
}
connect(m_notificationsInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed,
this, &NotificationClientPrivate::notificationClosed);
if(!m_serverInterface) {
m_serverInterface = new QDBusInterface(QStringLiteral("org.freedesktop.Notifications"),
QStringLiteral("/org/freedesktop/Notifications"),
QStringLiteral("org.ukui.NotificationServer"),
conn,
this);
if(!m_serverInterface->isValid()) {
qWarning() << "Failed to create notification server interface! " << conn.lastError();
return false;
}
}
QDBusMessage reply = m_serverInterface->call(QStringLiteral("RegisterClient"));
if (reply.type() == QDBusMessage::ErrorMessage || reply.type() == QDBusMessage::InvalidMessage) {
qWarning() << "Failed to call RegisterClient!" << conn.lastError() << reply.type();
return false;
}
return true;
}
void NotificationClientPrivate::unRegisterClient()
{
disconnect(m_notificationsInterface, &OrgFreedesktopNotificationsInterface::NotificationClosed,
this, &NotificationClientPrivate::notificationClosed);
if(m_notificationsInterface) {
delete m_notificationsInterface;
m_notificationsInterface = nullptr;
}
}
QString NotificationClientPrivate::clientServicePath()
{
return QStringLiteral("/NotificationClient");
}
QString NotificationClientPrivate::clientServiceInterface()
{
return QStringLiteral("org.ukui.NotificationClient");
}
void NotificationClientPrivate::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)
{
PopupNotification notification(replaces_id);
notification.setSummary(summary);
notification.setBody(body);
notification.setApplicationName(app_name);
notification.setAplicationIconName(app_icon);
notification.setActions(actions);
notification.setTimeout(timeout);
notification.setHints(hints);
Q_EMIT q->newNotification(notification);
}
void NotificationClientPrivate::notificationClosed(uint id, uint reason)
{
NotificationClient::CloseReason closeReason = NotificationClient::Undefined;
switch (reason) {
case 1:
closeReason = NotificationClient::Expired;
break;
case 2:
closeReason = NotificationClient::DismissedByUser;
break;
case 3:
closeReason = NotificationClient::Revoked;
break;
}
Q_EMIT q->notificationClosed(id, closeReason);
}
void NotificationClientPrivate::closeNotification(uint id, NotificationClient::CloseReason reason)
{
if(!m_notificationsInterface) {
return;
}
QDBusMessage reply = m_notificationsInterface->callWithArgumentList(QDBus::NoBlock, QStringLiteral("CloseNotification"), {id, reason});
if (reply.type() == QDBusMessage::ErrorMessage) {
qWarning() << "Failed to call CloseNotification!" << QDBusConnection::sessionBus().lastError();
}
}
void NotificationClientPrivate::serviceChange(const QString &service, const QString &oldOwner, const QString &newOwner)
{
qDebug() << "Notification Service" << service << "status change, old owner:" << oldOwner << "new:" << newOwner;
if(newOwner.isEmpty()) {
unRegisterClient();
} else if (oldOwner.isEmpty()) {
registerClient();
}
}
void NotificationClientPrivate::invokeAction(uint id, const QString &action_key, const QString &action,
const QString &display)
{
if(!m_notificationsInterface) {
return;
}
QDBusMessage reply = m_notificationsInterface->callWithArgumentList(QDBus::NoBlock,
QStringLiteral("InvokedAction"),
{id, action_key, action, display});
if (reply.type() == QDBusMessage::ErrorMessage) {
qWarning() << "Failed to call InvokedAction!" << QDBusConnection::sessionBus().lastError();
}
}
NotificationClient::NotificationClient(QObject *parent) : QObject(parent), d(new NotificationClientPrivate(this))
{
qRegisterMetaType<PopupNotification>("PopupNotification");
}
NotificationClient::~NotificationClient() = default;
bool NotificationClient::registerClient()
{
return d->init();
}
void NotificationClient::closeNotification(uint id, NotificationClient::CloseReason reason)
{
d->closeNotification(id, reason);
}
void NotificationClient::invokeAction(uint id, const QString &action_key, const QString &action, const QString &display)
{
d->invokeAction(id, action_key, action, display);
}