Remove cloud push notifications

Note: This doesn't remove 100% of the related code yet, just keeps
the minimum required to emit autoThingDisappeared() for all the
things and clean up users setups.

The rest of the CloudNotifications class code shall be removed
with 0.31 (or soonish after that).
pull/484/head
Michael Zanetti 2021-11-18 00:12:05 +01:00
parent 249393241c
commit 343d4a8c86
5 changed files with 12 additions and 179 deletions

View File

@ -45,7 +45,6 @@
AWSConnector::AWSConnector(QObject *parent) : QObject(parent)
{
qRegisterMetaType<AWSConnector::PushNotificationsEndpoint>();
m_clientName = readSyncedNameCache();
m_reconnectTimer.setSingleShot(true);
@ -217,29 +216,10 @@ void AWSConnector::onPairingsRetrieved(const QVariantMap &pairings)
}
qCDebug(dcAWS) << pairings.value("users").toList().count() << "devices paired in cloud.";
qCDebug(dcAWS) << pairings.value("pushNotificationsEndpoints").toList().count() << "push notification enabled users paired in cloud.";
QList<PushNotificationsEndpoint> pushNotificationEndpoints;
if (pairings.value("pushNotificationsEndpoints").toList().count() > 0) {
foreach (const QVariant &pairing, pairings.value("pushNotificationsEndpoints").toList()) {
foreach (const QString &cognitoUserId, pairing.toMap().keys()) {
qCDebug(dcAWS()) << "User:" << cognitoUserId << "has" << pairing.toMap().value(cognitoUserId).toList().count() << "push notifications enabled devices.";
foreach (const QVariant &endpoint, pairing.toMap().value(cognitoUserId).toList()) {
PushNotificationsEndpoint ep;
ep.userId = cognitoUserId;
ep.endpointId = endpoint.toMap().value("endpointId").toString();
ep.displayName = endpoint.toMap().value("displayName").toString();
pushNotificationEndpoints.append(ep);
qCDebug(dcAWS) << "Device:" << ep.displayName << "endpoint:" << ep.endpointId << "user:" << ep.userId;
}
}
}
}
if (readSyncedNameCache() != m_clientName) {
setName();
}
emit pushNotificationEndpointsUpdated(pushNotificationEndpoints);
}
void AWSConnector::disconnectAWS()
@ -278,18 +258,6 @@ void AWSConnector::pairDevice(const QString &idToken, const QString &userId)
m_pairingRequests.insert(m_transactionId, userId);
}
int AWSConnector::sendPushNotification(const QString &userId, const QString &endpointId, const QString &title, const QString &text)
{
QVariantMap params;
params.insert("id", ++m_transactionId);
params.insert("command", "sendPushNotification");
params.insert("title", title);
params.insert("body", text);
params.insert("timestamp", QDateTime::currentMSecsSinceEpoch());
publish(QString("%1/notify/user/%2/%3").arg(m_clientId, userId, endpointId), params);
return m_transactionId;
}
quint16 AWSConnector::publish(const QString &topic, const QVariantMap &message)
{
if (!m_setupInProgress && !isConnected()) {
@ -471,20 +439,6 @@ void AWSConnector::onPublishReceived(const QString &topic, const QByteArray &pay
}
qCDebug(dcAWS) << "Proxy remote connection request received";
proxyConnectionRequestReceived(token, nonce, serverUrl);
} else if (topic == QString("%1/notify/response").arg(m_clientId)) {
int transactionId = jsonDoc.toVariant().toMap().value("id").toInt();
int status = jsonDoc.toVariant().toMap().value("status").toInt();
qCDebug(dcAWS()) << "Push notification reply for transaction" << transactionId << " Status:" << status << jsonDoc.toVariant().toMap().value("message").toString();
emit pushNotificationSent(transactionId, status);
} else if (topic == QString("%1/notify/info/endpoint").arg(m_clientId)) {
QVariantMap endpoint = jsonDoc.toVariant().toMap().value("newPushNotificationsEndpoint").toMap();
Q_ASSERT(endpoint.keys().count() == 1);
QString cognitoId = endpoint.keys().first();
PushNotificationsEndpoint ep;
ep.userId = cognitoId;
ep.endpointId = endpoint.value(cognitoId).toMap().value("endpointId").toString();
ep.displayName = endpoint.value(cognitoId).toMap().value("displayName").toString();
emit pushNotificationEndpointAdded(ep);
} else {
qCWarning(dcAWS()) << "Unhandled subscription received!" << topic << payload;
}

View File

@ -45,13 +45,6 @@ public:
explicit AWSConnector(QObject *parent = nullptr);
~AWSConnector();
class PushNotificationsEndpoint {
public:
QString userId;
QString endpointId;
QString displayName;
};
void connect2AWS(const QString &endpoint, const QString &clientId, const QString &clientName, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile);
void disconnectAWS();
bool isConnected() const;
@ -59,16 +52,10 @@ public:
void setDeviceName(const QString &deviceName);
void pairDevice(const QString &idToken, const QString &userId);
public slots:
int sendPushNotification(const QString &userId, const QString &endpointId, const QString &title, const QString &text);
signals:
void connected();
void disconnected();
void devicePaired(const QString &cognritoUserId, int errorCode, const QString &message);
void pushNotificationEndpointsUpdated(const QList<AWSConnector::PushNotificationsEndpoint> pushNotificationEndpoints);
void pushNotificationEndpointAdded(const AWSConnector::PushNotificationsEndpoint &pushNotificationEndpoint);
void pushNotificationSent(int id, int status);
void proxyConnectionRequestReceived(const QString &token, const QString &nonce, const QString &serverUrl);
@ -126,6 +113,5 @@ private:
QPair<QVariantMap, QDateTime> m_cachedTURNCredentials;
};
Q_DECLARE_METATYPE(AWSConnector::PushNotificationsEndpoint)
#endif // AWSCONNECTOR_H

View File

@ -46,14 +46,11 @@ ParamTypeId notifyActionParamBodyId = ParamTypeId("4bd0fa87-c663-4621-8040-99b6d
StateTypeId connectedStateTypeId = StateTypeId("518e27b6-c3bf-49d7-be24-05ae978c00f7");
CloudNotifications::CloudNotifications(AWSConnector* awsConnector, QObject *parent):
IntegrationPlugin(parent),
m_awsConnector(awsConnector)
CloudNotifications::CloudNotifications(QObject *parent):
IntegrationPlugin(parent)
{
connect(m_awsConnector, &AWSConnector::pushNotificationEndpointsUpdated, this, &CloudNotifications::pushNotificationEndpointsUpdated);
connect(m_awsConnector, &AWSConnector::pushNotificationEndpointAdded, this, &CloudNotifications::pushNotificationEndpointAdded);
connect(m_awsConnector, &AWSConnector::pushNotificationSent, this, &CloudNotifications::pushNotificationSent);
// Metadata is just kept for now to not cause any dead things in the system. To be removed in 0.31 or so
QVariantMap pluginMetaData;
pluginMetaData.insert("id", "ccc6dbc8-e352-48a1-8e87-3c89a4669fc2");
pluginMetaData.insert("name", "CloudNotifications");
@ -148,107 +145,12 @@ CloudNotifications::CloudNotifications(AWSConnector* awsConnector, QObject *pare
void CloudNotifications::setupThing(ThingSetupInfo *info)
{
Thing *thing = info->thing();
thing->setStateValue(connectedStateTypeId, m_awsConnector->isConnected());
qCDebug(dcCloud) << "Cloud Notifications thing setup:" << thing->name() << "Connected:" << m_awsConnector->isConnected();
connect(m_awsConnector, &AWSConnector::connected, info->thing(), [thing]() {
thing->setStateValue(connectedStateTypeId, true);
});
connect(m_awsConnector, &AWSConnector::disconnected, thing, [thing]() {
thing->setStateValue(connectedStateTypeId, false);
});
// Just finishing the setup for any old existing things to not throw any errors
info->finish(Thing::ThingErrorNoError);
}
void CloudNotifications::startMonitoringAutoThings()
void CloudNotifications::postSetupThing(Thing *thing)
{
}
void CloudNotifications::executeAction(ThingActionInfo *info)
{
qCDebug(dcCloud()) << "executeAction" << info->thing() << info->action().params();
QString userId = info->thing()->paramValue(cloudNotificationsThingClassUserParamId).toString();
QString endpointId = info->thing()->paramValue(cloudNotificationsThingClassEndpointParamId).toString();
int id = m_awsConnector->sendPushNotification(userId, endpointId, info->action().param(notifyActionParamTitleId).value().toString(), info->action().param(notifyActionParamBodyId).value().toString());
m_pendingPushNotifications.insert(id, info);
}
void CloudNotifications::pushNotificationEndpointsUpdated(const QList<AWSConnector::PushNotificationsEndpoint> &endpoints)
{
qCDebug(dcCloud()) << "Push Notification endpoint update";
QList<Thing*> thingsToRemove;
foreach (Thing *configuredThing, myThings()) {
bool found = false;
foreach (const AWSConnector::PushNotificationsEndpoint &ep, endpoints) {
if (configuredThing->paramValue(cloudNotificationsThingClassUserParamId).toString() == ep.userId
&& configuredThing->paramValue(cloudNotificationsThingClassEndpointParamId).toString() == ep.endpointId) {
found = true;
break;
}
}
if (!found) {
thingsToRemove.append(configuredThing);
}
}
foreach (Thing *d, thingsToRemove) {
emit autoThingDisappeared(d->id());
}
ThingDescriptors thingsToAdd;
foreach (const AWSConnector::PushNotificationsEndpoint &ep, endpoints) {
bool found = false;
qCDebug(dcCloud) << "Checking endoint:" << ep.endpointId;
foreach (Thing *d, myThings()) {
qCDebug(dcCloud) << "Have existing thing:" << d->name() << d->paramValue(cloudNotificationsThingClassEndpointParamId);
if (d->paramValue(cloudNotificationsThingClassUserParamId).toString() == ep.userId
&& d->paramValue(cloudNotificationsThingClassEndpointParamId).toString() == ep.endpointId) {
found = true;
break;
}
}
if (!found) {
qCDebug(dcCloud) << "Adding new notification thing" << ep.displayName;
ThingDescriptor descriptor(cloudNotificationsThingClassId, ep.displayName, QString("Send notifications to %1").arg(ep.displayName));
ParamList params;
Param userIdParam(cloudNotificationsThingClassUserParamId, ep.userId);
params.append(userIdParam);
Param endpointIdParam(cloudNotificationsThingClassEndpointParamId, ep.endpointId);
params.append(endpointIdParam);
descriptor.setParams(params);
thingsToAdd.append(descriptor);
}
}
emit autoThingsAppeared(thingsToAdd);
}
void CloudNotifications::pushNotificationEndpointAdded(const AWSConnector::PushNotificationsEndpoint &endpoint)
{
// Could be just an update, don't add it in that case...
foreach (Thing *d, myThings()) {
if (d->paramValue(cloudNotificationsThingClassUserParamId).toString() == endpoint.userId
&& d->paramValue(cloudNotificationsThingClassEndpointParamId).toString() == endpoint.endpointId) {
return;
}
}
qCDebug(dcCloud) << "Push notification endpoint added:" << endpoint.displayName;
ThingDescriptor descriptor(cloudNotificationsThingClassId, endpoint.displayName, QString("Send notifications to %1").arg(endpoint.displayName));
ParamList params;
Param userIdParam(cloudNotificationsThingClassUserParamId, endpoint.userId);
params.append(userIdParam);
Param endpointIdParam(cloudNotificationsThingClassEndpointParamId, endpoint.endpointId);
params.append(endpointIdParam);
descriptor.setParams(params);
emit autoThingsAppeared({descriptor});
}
void CloudNotifications::pushNotificationSent(int id, int status)
{
qCDebug(dcCloud()) << "Push notification sent" << id << status;
ThingActionInfo *info = m_pendingPushNotifications.take(id);
if (!info) {
qCWarning(dcCloud()) << "Received a push notification send reponse for a request we're not waiting for.";
return;
}
info->finish(status == 200 ? Thing::ThingErrorNoError : Thing::ThingErrorHardwareNotAvailable);
// And make it go away...
emit autoThingDisappeared(thing->id());
}

View File

@ -32,32 +32,20 @@
#define CLOUDNOTIFICATIONS_H
#include "integrations/integrationplugin.h"
#include "awsconnector.h"
class CloudNotifications : public IntegrationPlugin
{
Q_OBJECT
// Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "deviceplugincloudnotifications.json")
Q_INTERFACES(IntegrationPlugin)
public:
CloudNotifications(AWSConnector *awsConnector, QObject* parent = nullptr);
CloudNotifications(QObject* parent = nullptr);
PluginMetadata metaData() const;
void setupThing(ThingSetupInfo *info) override;
void startMonitoringAutoThings() override;
void executeAction(ThingActionInfo *info) override;
private slots:
void pushNotificationEndpointsUpdated(const QList<AWSConnector::PushNotificationsEndpoint> &endpoints);
void pushNotificationEndpointAdded(const AWSConnector::PushNotificationsEndpoint &endpoint);
void pushNotificationSent(int id, int status);
private:
AWSConnector *m_awsConnector = nullptr;
QHash<int, ThingActionInfo*> m_pendingPushNotifications;
void postSetupThing(Thing *thing) override;
};
#endif // CLOUDNOTIFICATIONS_H

View File

@ -151,6 +151,9 @@ void NymeaCore::init(const QStringList &additionalInterfaces) {
m_experienceManager = new ExperienceManager(m_thingManager, m_serverManager->jsonServer(), this);
// To be removed with 0.31 or later.
// Most of the cloud push notifications code has been removed with 0.30, this is just kept for a release or two
// to auto-remove all the cloud based push notification things users might have in their systems
CloudNotifications *cloudNotifications = m_cloudManager->createNotificationsPlugin();
m_thingManager->registerStaticPlugin(cloudNotifications);