216 lines
6.9 KiB
C++
216 lines
6.9 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
|
*
|
|
* This file is part of nymea-app.
|
|
*
|
|
* nymea-app 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.
|
|
*
|
|
* nymea-app 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 nymea-app. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#include "pushclient.h"
|
|
#include <QtDBus/QDBusConnection>
|
|
#include <QtDBus/QDBusMessage>
|
|
#include <QtDBus/QDBusPendingCall>
|
|
#include <QtDBus/QDBusPendingReply>
|
|
#include <QTimer>
|
|
|
|
#define PUSH_SERVICE "com.ubuntu.PushNotifications"
|
|
#define POSTAL_SERVICE "com.ubuntu.Postal"
|
|
#define PUSH_PATH "/com/ubuntu/PushNotifications"
|
|
#define POSTAL_PATH "/com/ubuntu/Postal"
|
|
#define PUSH_IFACE "com.ubuntu.PushNotifications"
|
|
#define POSTAL_IFACE "com.ubuntu.Postal"
|
|
|
|
PushClient::PushClient(QObject *parent) :
|
|
QObject(parent),
|
|
ns(new connectivityqt::Connectivity(QDBusConnection::sessionBus(), this))
|
|
{
|
|
}
|
|
|
|
void PushClient::setAppId(const QString &appId) {
|
|
if (appId == this->appId || appId.isEmpty())
|
|
return;
|
|
|
|
this->appId = appId;
|
|
emit appIdChanged(appId);
|
|
|
|
if (ns->online()) {
|
|
registerApp();
|
|
} else {
|
|
disconnect(ns.data(), 0, this, 0);
|
|
connect(ns.data(), &connectivityqt::Connectivity::onlineUpdated, this, &PushClient::connectionStatusChanged);
|
|
}
|
|
}
|
|
|
|
void PushClient::connectionStatusChanged(bool status)
|
|
{
|
|
if (status) {
|
|
disconnect(ns.data(), 0, this, 0);
|
|
registerApp();
|
|
}
|
|
}
|
|
|
|
void PushClient::registerApp()
|
|
{
|
|
if (appId.isEmpty())
|
|
return;
|
|
|
|
pkgname = appId.split("_").at(0);
|
|
pkgname = pkgname.replace(".","_2e").replace("-","_2d");
|
|
|
|
QString register_path(PUSH_PATH);
|
|
register_path += "/" + pkgname;
|
|
|
|
QDBusConnection bus = QDBusConnection::sessionBus();
|
|
|
|
// Register to the push client
|
|
QDBusMessage message = QDBusMessage::createMethodCall(PUSH_SERVICE, register_path , PUSH_IFACE, "Register");
|
|
message << appId;
|
|
QDBusPendingCall pcall = bus.asyncCall(message);
|
|
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
|
|
connect(watcher, &QDBusPendingCallWatcher::finished, this, &PushClient::registerFinished);
|
|
|
|
// Connect to the notification signal
|
|
QString postal_path(POSTAL_PATH);
|
|
postal_path += "/" + pkgname;
|
|
bus.connect(POSTAL_SERVICE, postal_path, POSTAL_IFACE, "Post", "s", this, SLOT(notified(QString)));
|
|
}
|
|
|
|
void PushClient::registerFinished(QDBusPendingCallWatcher *watcher) {
|
|
QDBusPendingReply<QString> reply = *watcher;
|
|
if (reply.isError()) {
|
|
status = reply.error().message();
|
|
emit statusChanged(status);
|
|
// This has to be delayed because the error signal is not connected yet
|
|
QTimer::singleShot(200, this, &PushClient::emitError);
|
|
}
|
|
else {
|
|
this->token = reply.value();
|
|
// Do an initial fetch
|
|
QTimer::singleShot(200, this, &PushClient::getNotifications);
|
|
emit tokenChanged(this->token);
|
|
}
|
|
watcher->deleteLater();
|
|
}
|
|
|
|
QString PushClient::getAppId() {
|
|
return appId;
|
|
}
|
|
|
|
QString PushClient::getToken() {
|
|
return token;
|
|
}
|
|
|
|
void PushClient::emitError()
|
|
{
|
|
emit error(status);
|
|
}
|
|
|
|
void PushClient::notified(const QString &)
|
|
{
|
|
this->getNotifications();
|
|
}
|
|
|
|
void PushClient::getNotifications() {
|
|
QDBusConnection bus = QDBusConnection::sessionBus();
|
|
QString path(POSTAL_PATH);
|
|
path += "/" + pkgname;
|
|
QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "PopAll");
|
|
message << this->appId;
|
|
QDBusPendingCall pcall = bus.asyncCall(message);
|
|
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
|
|
connect(watcher, &QDBusPendingCallWatcher::finished,this, &PushClient::popAllFinished);
|
|
}
|
|
|
|
void PushClient::popAllFinished(QDBusPendingCallWatcher *watcher) {
|
|
QDBusPendingReply<QStringList> reply = *watcher;
|
|
if (reply.isError()) {
|
|
emit error(reply.error().message());
|
|
}
|
|
else {
|
|
emit notificationsChanged(reply.value());
|
|
}
|
|
watcher->deleteLater();
|
|
}
|
|
|
|
QStringList PushClient::getPersistent() {
|
|
// FIXME: this is blocking, but making it async would change the API
|
|
QDBusConnection bus = QDBusConnection::sessionBus();
|
|
QString path(POSTAL_PATH);
|
|
path += "/" + pkgname;
|
|
QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "ListPersistent");
|
|
message << this->appId;
|
|
QDBusMessage reply = bus.call(message);
|
|
if (reply.type() == QDBusMessage::ErrorMessage) {
|
|
emit error(reply.errorMessage());
|
|
}
|
|
return reply.arguments()[0].toStringList();
|
|
}
|
|
|
|
void PushClient::clearPersistent(const QStringList &tags) {
|
|
QDBusConnection bus = QDBusConnection::sessionBus();
|
|
QString path(POSTAL_PATH);
|
|
path += "/" + pkgname;
|
|
QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "ClearPersistent");
|
|
message << this->appId;
|
|
for (int i = 0; i < tags.size(); ++i) {
|
|
message << tags.at(i);
|
|
}
|
|
QDBusPendingCall pcall = bus.asyncCall(message);
|
|
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
|
|
connect(watcher, &QDBusPendingCallWatcher::finished, this, &PushClient::clearPersistentFinished);
|
|
}
|
|
|
|
void PushClient::clearPersistentFinished(QDBusPendingCallWatcher *watcher) {
|
|
QDBusPendingReply<void> reply = *watcher;
|
|
|
|
if (reply.isError()) {
|
|
emit error(reply.error().message());
|
|
} else {
|
|
// FIXME: this is blocking
|
|
emit persistentChanged(getPersistent());
|
|
}
|
|
}
|
|
|
|
void PushClient::setCount(int count) {
|
|
QDBusConnection bus = QDBusConnection::sessionBus();
|
|
QString path(POSTAL_PATH);
|
|
bool visible = count != 0;
|
|
counter = count;
|
|
path += "/" + pkgname;
|
|
QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "SetCounter");
|
|
message << this->appId << count << visible;
|
|
QDBusPendingCall pcall = bus.asyncCall(message);
|
|
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
|
|
connect(watcher, &QDBusPendingCallWatcher::finished, this, &PushClient::setCounterFinished);
|
|
}
|
|
|
|
void PushClient::setCounterFinished(QDBusPendingCallWatcher *watcher) {
|
|
QDBusPendingReply<void> reply = *watcher;
|
|
if (reply.isError()) {
|
|
emit error(reply.error().message());
|
|
}
|
|
else {
|
|
emit countChanged(counter);
|
|
}
|
|
}
|
|
|
|
int PushClient::getCount() {
|
|
return counter;
|
|
}
|