From 343d4a8c86ff33c7252abfaaac1fd6befd469a63 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 18 Nov 2021 00:12:05 +0100 Subject: [PATCH] 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). --- libnymea-core/cloud/awsconnector.cpp | 46 --------- libnymea-core/cloud/awsconnector.h | 14 --- libnymea-core/cloud/cloudnotifications.cpp | 112 ++------------------- libnymea-core/cloud/cloudnotifications.h | 16 +-- libnymea-core/nymeacore.cpp | 3 + 5 files changed, 12 insertions(+), 179 deletions(-) diff --git a/libnymea-core/cloud/awsconnector.cpp b/libnymea-core/cloud/awsconnector.cpp index 0f9be5db..c85d6291 100644 --- a/libnymea-core/cloud/awsconnector.cpp +++ b/libnymea-core/cloud/awsconnector.cpp @@ -45,7 +45,6 @@ AWSConnector::AWSConnector(QObject *parent) : QObject(parent) { - qRegisterMetaType(); 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 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; } diff --git a/libnymea-core/cloud/awsconnector.h b/libnymea-core/cloud/awsconnector.h index 205df0da..d7bbf77d 100644 --- a/libnymea-core/cloud/awsconnector.h +++ b/libnymea-core/cloud/awsconnector.h @@ -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 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 m_cachedTURNCredentials; }; -Q_DECLARE_METATYPE(AWSConnector::PushNotificationsEndpoint) #endif // AWSCONNECTOR_H diff --git a/libnymea-core/cloud/cloudnotifications.cpp b/libnymea-core/cloud/cloudnotifications.cpp index 678fc4e1..50523208 100644 --- a/libnymea-core/cloud/cloudnotifications.cpp +++ b/libnymea-core/cloud/cloudnotifications.cpp @@ -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 &endpoints) -{ - qCDebug(dcCloud()) << "Push Notification endpoint update"; - QList 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()); } diff --git a/libnymea-core/cloud/cloudnotifications.h b/libnymea-core/cloud/cloudnotifications.h index b2ad2e7d..19e45b67 100644 --- a/libnymea-core/cloud/cloudnotifications.h +++ b/libnymea-core/cloud/cloudnotifications.h @@ -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 &endpoints); - void pushNotificationEndpointAdded(const AWSConnector::PushNotificationsEndpoint &endpoint); - void pushNotificationSent(int id, int status); - -private: - AWSConnector *m_awsConnector = nullptr; - QHash m_pendingPushNotifications; + void postSetupThing(Thing *thing) override; }; #endif // CLOUDNOTIFICATIONS_H diff --git a/libnymea-core/nymeacore.cpp b/libnymea-core/nymeacore.cpp index 7e6f7d3d..2f3770ed 100644 --- a/libnymea-core/nymeacore.cpp +++ b/libnymea-core/nymeacore.cpp @@ -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);