diff options
| author | Linus Jahn <lnj@kaidan.im> | 2022-08-16 21:00:15 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2023-01-03 22:05:54 +0100 |
| commit | b17284ee7d674416e0d11f1699f73fcc606262d4 (patch) | |
| tree | 86597f2bc2a1ed2d257e0cbf8e7de1ca54080c08 /src/omemo | |
| parent | 3271c6642439d4d3c0d8c634e2b3f4cf17b908a0 (diff) | |
| download | qxmpp-b17284ee7d674416e0d11f1699f73fcc606262d4.tar.gz | |
Introduce QXmppTask & QXmppPromise
Closes #502.
Co-authored-by: Jonah BrĂ¼chert <jbb@kaidan.im>
Diffstat (limited to 'src/omemo')
| -rw-r--r-- | src/omemo/QXmppOmemoManager.cpp | 164 | ||||
| -rw-r--r-- | src/omemo/QXmppOmemoManager.h | 47 | ||||
| -rw-r--r-- | src/omemo/QXmppOmemoManager_p.cpp | 367 | ||||
| -rw-r--r-- | src/omemo/QXmppOmemoManager_p.h | 77 | ||||
| -rw-r--r-- | src/omemo/QXmppOmemoMemoryStorage.cpp | 46 | ||||
| -rw-r--r-- | src/omemo/QXmppOmemoMemoryStorage.h | 21 | ||||
| -rw-r--r-- | src/omemo/QXmppOmemoStorage.h | 21 |
7 files changed, 374 insertions, 369 deletions
diff --git a/src/omemo/QXmppOmemoManager.cpp b/src/omemo/QXmppOmemoManager.cpp index dc2cd5a2..a90e3f53 100644 --- a/src/omemo/QXmppOmemoManager.cpp +++ b/src/omemo/QXmppOmemoManager.cpp @@ -350,25 +350,25 @@ QXmppOmemoManager::~QXmppOmemoManager() = default; /// /// \return whether everything is loaded successfully /// -QFuture<bool> Manager::load() +QXmppTask<bool> Manager::load() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; auto future = d->omemoStorage->allData(); - await(future, this, [=](QXmppOmemoStorage::OmemoData omemoData) mutable { + future.then(this, [=](QXmppOmemoStorage::OmemoData omemoData) mutable { const auto &optionalOwnDevice = omemoData.ownDevice; if (optionalOwnDevice) { d->ownDevice = *optionalOwnDevice; } else { debug("Device could not be loaded because it is not stored"); - reportFinishedResult(interface, false); + interface.finish(false); return; } const auto &signedPreKeyPairs = omemoData.signedPreKeyPairs; if (signedPreKeyPairs.isEmpty()) { warning("Signed Pre keys could not be loaded because none is stored"); - reportFinishedResult(interface, false); + interface.finish(false); return; } else { d->signedPreKeyPairs = signedPreKeyPairs; @@ -378,7 +378,7 @@ QFuture<bool> Manager::load() const auto &preKeyPairs = omemoData.preKeyPairs; if (preKeyPairs.isEmpty()) { warning("Pre keys could not be loaded because none is stored"); - reportFinishedResult(interface, false); + interface.finish(false); return; } else { d->preKeyPairs = preKeyPairs; @@ -387,10 +387,11 @@ QFuture<bool> Manager::load() d->devices = omemoData.devices; d->removeDevicesRemovedFromServer(); - reportFinishedResult(interface, d->isStarted = true); + d->isStarted = true; + interface.finish(true); }); - return interface.future(); + return interface.task(); } /// @@ -400,12 +401,12 @@ QFuture<bool> Manager::load() /// /// \return whether everything is set up successfully /// -QFuture<bool> Manager::setUp() +QXmppTask<bool> Manager::setUp() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; auto future = d->setUpDeviceId(); - await(future, this, [=](bool isDeviceIdSetUp) mutable { + future.then(this, [=](bool isDeviceIdSetUp) mutable { if (isDeviceIdSetUp) { // The identity key pair in its deserialized form is not stored as a // member variable because it is only needed by @@ -416,21 +417,22 @@ QFuture<bool> Manager::setUp() d->updateSignedPreKeyPair(identityKeyPair.get()) && d->updatePreKeyPairs(PRE_KEY_INITIAL_CREATION_COUNT)) { auto future = d->omemoStorage->setOwnDevice(d->ownDevice); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = d->publishOmemoData(); - await(future, this, [=](bool isPublished) mutable { - reportFinishedResult(interface, d->isStarted = isPublished); + future.then(this, [=](bool isPublished) mutable { + d->isStarted = isPublished; + interface.finish(std::move(isPublished)); }); }); } else { - reportFinishedResult(interface, false); + interface.finish(false); } } else { - reportFinishedResult(interface, false); + interface.finish(false); } }); - return interface.future(); + return interface.task(); } /// @@ -438,7 +440,7 @@ QFuture<bool> Manager::setUp() /// /// \return the own key /// -QFuture<QByteArray> Manager::ownKey() +QXmppTask<QByteArray> Manager::ownKey() { return d->trustManager->ownKey(ns_omemo_2); } @@ -457,7 +459,7 @@ QFuture<QByteArray> Manager::ownKey() /// /// \return the key owner JIDs mapped to their keys with specific trust levels /// -QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> Manager::keys(QXmpp::TrustLevels trustLevels) +QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> Manager::keys(QXmpp::TrustLevels trustLevels) { return d->trustManager->keys(ns_omemo_2, trustLevels); } @@ -477,7 +479,7 @@ QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> Manager::keys /// /// \return the key IDs mapped to their trust levels for specific key owners /// -QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> Manager::keys(const QList<QString> &jids, QXmpp::TrustLevels trustLevels) +QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> Manager::keys(const QList<QString> &jids, QXmpp::TrustLevels trustLevels) { return d->trustManager->keys(ns_omemo_2, jids, trustLevels); } @@ -496,7 +498,7 @@ QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> Manager::keys(cons /// /// \return whether the action was successful /// -QFuture<bool> Manager::changeDeviceLabel(const QString &deviceLabel) +QXmppTask<bool> Manager::changeDeviceLabel(const QString &deviceLabel) { return d->changeDeviceLabel(deviceLabel); } @@ -564,13 +566,14 @@ void Manager::setMaximumDevicesPerStanza(int maximum) /// /// \return the results of the requests for each JID /// -QFuture<QVector<Manager::DevicesResult>> Manager::requestDeviceLists(const QList<QString> &jids) +QXmppTask<QVector<Manager::DevicesResult>> Manager::requestDeviceLists(const QList<QString> &jids) { if (const auto jidsCount = jids.size()) { - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface<QVector<Manager::DevicesResult>> interface; + QXmppPromise<QVector<Manager::DevicesResult>> interface; QVector<Manager::DevicesResult> devicesResults; }; @@ -581,21 +584,20 @@ QFuture<QVector<Manager::DevicesResult>> Manager::requestDeviceLists(const QList Q_ASSERT_X(jid != d->ownBareJid(), "Requesting contact's device list", "Own JID passed"); auto future = d->requestDeviceList(jid); - await(future, this, [jid, state](auto result) mutable { + future.then(this, [jid, state](auto result) mutable { state->devicesResults << DevicesResult { jid, mapSuccess(std::move(result), [](QXmppOmemoDeviceListItem) { return Success(); }) }; if (++(state->processed) == state->jidsCount) { - state->interface.reportResult(state->devicesResults); - state->interface.reportFinished(); + state->interface.finish(std::move(state->devicesResults)); } }); } - return state->interface.future(); + return state->interface.task(); } - return makeReadyFuture(QVector<Manager::DevicesResult>()); + return makeReadyTask(QVector<Manager::DevicesResult>()); } /// @@ -612,13 +614,14 @@ QFuture<QVector<Manager::DevicesResult>> Manager::requestDeviceLists(const QList /// /// \return the results of the subscription for each JID /// -QFuture<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const QList<QString> &jids) +QXmppTask<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const QList<QString> &jids) { if (const auto jidsCount = jids.size()) { - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface<QVector<Manager::DevicesResult>> interface; + QXmppPromise<QVector<Manager::DevicesResult>> interface; QVector<Manager::DevicesResult> devicesResults; }; @@ -627,21 +630,20 @@ QFuture<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const Q for (const auto &jid : jids) { auto future = d->subscribeToDeviceList(jid); - await(future, this, [state, jid](QXmppPubSubManager::Result result) mutable { + future.then(this, [state, jid](QXmppPubSubManager::Result result) mutable { Manager::DevicesResult devicesResult; devicesResult.jid = jid; devicesResult.result = result; state->devicesResults << devicesResult; if (++(state->processed) == state->jidsCount) { - state->interface.reportResult(state->devicesResults); - state->interface.reportFinished(); + state->interface.finish(std::move(state->devicesResults)); } }); } - return state->interface.future(); + return state->interface.task(); } - return makeReadyFuture(QVector<Manager::DevicesResult>()); + return makeReadyTask(QVector<Manager::DevicesResult>()); } /// @@ -653,7 +655,7 @@ QFuture<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const Q /// /// \return the results of the unsubscription for each JID /// -QFuture<QVector<Manager::DevicesResult>> Manager::unsubscribeFromDeviceLists() +QXmppTask<QVector<Manager::DevicesResult>> Manager::unsubscribeFromDeviceLists() { return d->unsubscribeFromDeviceLists(d->jidsOfManuallySubscribedDevices); } @@ -684,7 +686,7 @@ QXmppOmemoOwnDevice Manager::ownDevice() /// /// /\return all devices except the own device /// -QFuture<QVector<QXmppOmemoDevice>> Manager::devices() +QXmppTask<QVector<QXmppOmemoDevice>> Manager::devices() { return devices(d->devices.keys()); } @@ -702,12 +704,12 @@ QFuture<QVector<QXmppOmemoDevice>> Manager::devices() /// /// \return all devices of the passed JIDs /// -QFuture<QVector<QXmppOmemoDevice>> Manager::devices(const QList<QString> &jids) +QXmppTask<QVector<QXmppOmemoDevice>> Manager::devices(const QList<QString> &jids) { - QFutureInterface<QVector<QXmppOmemoDevice>> interface(QFutureInterfaceBase::Started); + QXmppPromise<QVector<QXmppOmemoDevice>> interface; auto future = keys(jids); - await(future, this, [=](QHash<QString, QHash<QByteArray, TrustLevel>> keys) mutable { + future.then(this, [=](QHash<QString, QHash<QByteArray, TrustLevel>> keys) mutable { QVector<QXmppOmemoDevice> devices; for (const auto &jid : jids) { @@ -730,10 +732,10 @@ QFuture<QVector<QXmppOmemoDevice>> Manager::devices(const QList<QString> &jids) } } - reportFinishedResult(interface, devices); + interface.finish(std::move(devices)); }); - return interface.future(); + return interface.task(); } /// @@ -749,32 +751,32 @@ QFuture<QVector<QXmppOmemoDevice>> Manager::devices(const QList<QString> &jids) /// /// \return the result of the contact device removals /// -QFuture<QXmppPubSubManager::Result> Manager::removeContactDevices(const QString &jid) +QXmppTask<QXmppPubSubManager::Result> Manager::removeContactDevices(const QString &jid) { - QFutureInterface<QXmppPubSubManager::Result> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppPubSubManager::Result> interface; Q_ASSERT_X(jid != d->ownBareJid(), "Removing contact device", "Own JID passed"); auto future = d->unsubscribeFromDeviceList(jid); - await(future, this, [=](QXmppPubSubManager::Result result) mutable { + future.then(this, [=](QXmppPubSubManager::Result result) mutable { if (std::holds_alternative<QXmppStanza::Error>(result)) { warning("Contact '" % jid % "' could not be removed because the device list subscription could not be removed"); - reportFinishedResult(interface, result); + interface.finish(std::move(result)); } else { d->devices.remove(jid); auto future = d->omemoStorage->removeDevices(jid); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = d->trustManager->removeKeys(ns_omemo_2, jid); - await(future, this, [=]() mutable { - reportFinishedResult(interface, result); + future.then(this, [=]() mutable { + interface.finish(std::move(result)); Q_EMIT devicesRemoved(jid); }); }); } }); - return interface.future(); + return interface.task(); } /// @@ -851,9 +853,9 @@ bool Manager::isNewDeviceAutoSessionBuildingEnabled() /// /// \param jids JIDs of the device owners for whom the sessions are built /// -QFuture<void> Manager::buildMissingSessions(const QList<QString> &jids) +QXmppTask<void> Manager::buildMissingSessions(const QList<QString> &jids) { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> interface; auto &devices = d->devices; auto devicesCount = 0; @@ -883,21 +885,18 @@ QFuture<void> Manager::buildMissingSessions(const QList<QString> &jids) if (device.session.isEmpty()) { auto future = d->buildSessionWithDeviceBundle(jid, deviceId, device); - await(future, this, [=](auto) mutable { + future.then(this, [=](auto) mutable { if (++(*processedDevicesCount) == devicesCount) { - interface.reportFinished(); } }); } else if (++(*processedDevicesCount) == devicesCount) { - interface.reportFinished(); } } } } else { - interface.reportFinished(); } - return interface.future(); + return interface.task(); } /// @@ -916,7 +915,7 @@ QFuture<void> Manager::buildMissingSessions(const QList<QString> &jids) /// Existing sessions are reset, which might lead to undecryptable incoming /// stanzas until everything is set up again. /// -QFuture<bool> Manager::resetOwnDevice() +QXmppTask<bool> Manager::resetOwnDevice() { return d->resetOwnDevice(); } @@ -938,7 +937,7 @@ QFuture<bool> Manager::resetOwnDevice() /// Existing sessions are reset, which might lead to undecryptable incoming /// stanzas until everything is set up again. /// -QFuture<bool> Manager::resetAll() +QXmppTask<bool> Manager::resetAll() { return d->resetAll(); } @@ -948,7 +947,7 @@ QFuture<bool> Manager::resetAll() /// /// \param securityPolicy security policy being set /// -QFuture<void> Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy) +QXmppTask<void> Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy) { return d->trustManager->setSecurityPolicy(ns_omemo_2, securityPolicy); } @@ -958,7 +957,7 @@ QFuture<void> Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPoli /// /// \return the used security policy /// -QFuture<QXmpp::TrustSecurityPolicy> Manager::securityPolicy() +QXmppTask<QXmpp::TrustSecurityPolicy> Manager::securityPolicy() { return d->trustManager->securityPolicy(ns_omemo_2); } @@ -971,7 +970,7 @@ QFuture<QXmpp::TrustSecurityPolicy> Manager::securityPolicy() /// \param keyIds key owners' bare JIDs mapped to the IDs of their keys /// \param trustLevel trust level being set /// -QFuture<void> Manager::setTrustLevel(const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel) +QXmppTask<void> Manager::setTrustLevel(const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel) { return d->trustManager->setTrustLevel(ns_omemo_2, keyIds, trustLevel); } @@ -986,13 +985,13 @@ QFuture<void> Manager::setTrustLevel(const QMultiHash<QString, QByteArray> &keyI /// /// \return the key's trust level /// -QFuture<QXmpp::TrustLevel> Manager::trustLevel(const QString &keyOwnerJid, const QByteArray &keyId) +QXmppTask<QXmpp::TrustLevel> Manager::trustLevel(const QString &keyOwnerJid, const QByteArray &keyId) { return d->trustManager->trustLevel(ns_omemo_2, keyOwnerJid, keyId); } /// \cond -QFuture<QXmppE2eeExtension::MessageEncryptResult> Manager::encryptMessage(QXmppMessage &&message, const std::optional<QXmppSendStanzaParams> ¶ms) +QXmppTask<QXmppE2eeExtension::MessageEncryptResult> Manager::encryptMessage(QXmppMessage &&message, const std::optional<QXmppSendStanzaParams> ¶ms) { QVector<QString> recipientJids; std::optional<TrustLevels> acceptedTrustLevels; @@ -1013,17 +1012,17 @@ QFuture<QXmppE2eeExtension::MessageEncryptResult> Manager::encryptMessage(QXmppM return d->encryptMessageForRecipients(std::move(message), recipientJids, *acceptedTrustLevels); } -QFuture<QXmppE2eeExtension::MessageDecryptResult> QXmppOmemoManager::decryptMessage(QXmppMessage &&message) +QXmppTask<QXmppE2eeExtension::MessageDecryptResult> QXmppOmemoManager::decryptMessage(QXmppMessage &&message) { if (!d->isStarted) { - return makeReadyFuture<MessageDecryptResult>(QXmppError { + return makeReadyTask<MessageDecryptResult>(QXmppError { QStringLiteral("OMEMO manager must be started before decrypting"), SendError::EncryptionError }); } auto omemoElement = message.omemoElement(); if (!omemoElement) { - return makeReadyFuture<MessageDecryptResult>(NotEncrypted()); + return makeReadyTask<MessageDecryptResult>(NotEncrypted()); } return chain<MessageDecryptResult>(d->decryptMessage(message), this, [](std::optional<QXmppMessage> message) -> MessageDecryptResult { @@ -1037,15 +1036,14 @@ QFuture<QXmppE2eeExtension::MessageDecryptResult> QXmppOmemoManager::decryptMess }); } -QFuture<QXmppE2eeExtension::IqEncryptResult> Manager::encryptIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) +QXmppTask<QXmppE2eeExtension::IqEncryptResult> Manager::encryptIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) { - QFutureInterface<QXmppE2eeExtension::IqEncryptResult> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppE2eeExtension::IqEncryptResult> interface; if (!d->isStarted) { - interface.reportResult(QXmppError { + interface.finish(QXmppError { QStringLiteral("OMEMO manager must be started before encrypting"), SendError::EncryptionError }); - interface.reportFinished(); } else { std::optional<TrustLevels> acceptedTrustLevels; @@ -1058,12 +1056,12 @@ QFuture<QXmppE2eeExtension::IqEncryptResult> Manager::encryptIq(QXmppIq &&iq, co } auto future = d->encryptStanza(iq, { QXmppUtils::jidToBareJid(iq.to()) }, *acceptedTrustLevels); - await(future, this, [=, iq = std::move(iq)](std::optional<QXmppOmemoElement> omemoElement) mutable { + future.then(this, [=, iq = std::move(iq)](std::optional<QXmppOmemoElement> omemoElement) mutable { if (!omemoElement) { - interface.reportResult(QXmppError { + interface.finish(QXmppError { QStringLiteral("OMEMO element could not be created"), SendError::EncryptionError }); - interface.reportFinished(); + } else { QXmppOmemoIq omemoIq; omemoIq.setId(iq.id()); @@ -1077,19 +1075,19 @@ QFuture<QXmppE2eeExtension::IqEncryptResult> Manager::encryptIq(QXmppIq &&iq, co QXmlStreamWriter writer(&serializedEncryptedIq); omemoIq.toXml(&writer); - reportFinishedResult(interface, { serializedEncryptedIq }); + interface.finish(serializedEncryptedIq); } }); } - return interface.future(); + return interface.task(); } -QFuture<QXmppE2eeExtension::IqDecryptResult> Manager::decryptIq(const QDomElement &element) +QXmppTask<QXmppE2eeExtension::IqDecryptResult> Manager::decryptIq(const QDomElement &element) { if (!d->isStarted) { // TODO: Add decryption queue to avoid this error - return makeReadyFuture<IqDecryptResult>(QXmppError { + return makeReadyTask<IqDecryptResult>(QXmppError { QStringLiteral("OMEMO manager must be started before decrypting"), SendError::EncryptionError }); } @@ -1107,7 +1105,7 @@ QFuture<QXmppE2eeExtension::IqDecryptResult> Manager::decryptIq(const QDomElemen }); } - return makeReadyFuture<IqDecryptResult>(NotEncrypted()); + return makeReadyTask<IqDecryptResult>(NotEncrypted()); } bool QXmppOmemoManager::isEncrypted(const QDomElement &el) @@ -1152,7 +1150,7 @@ bool Manager::handleStanza(const QDomElement &stanza) return false; } - await(d->decryptIq(stanza), this, [=](auto result) { + d->decryptIq(stanza).then(this, [=](auto result) { if (result) { injectIq(result->iq, result->e2eeMetadata); } else { @@ -1166,7 +1164,7 @@ bool Manager::handleMessage(const QXmppMessage &message) { if (d->isStarted && message.omemoElement()) { auto future = d->decryptMessage(message); - await(future, this, [=](std::optional<QXmppMessage> optionalDecryptedMessage) mutable { + future.then(this, [=](std::optional<QXmppMessage> optionalDecryptedMessage) mutable { if (optionalDecryptedMessage) { injectMessage(std::move(*optionalDecryptedMessage)); } diff --git a/src/omemo/QXmppOmemoManager.h b/src/omemo/QXmppOmemoManager.h index 5852b950..d7b34a9c 100644 --- a/src/omemo/QXmppOmemoManager.h +++ b/src/omemo/QXmppOmemoManager.h @@ -9,7 +9,6 @@ #include "QXmppE2eeExtension.h" #include "QXmppMessageHandler.h" #include "QXmppPubSubEventHandler.h" -#include "QXmppPubSubManager.h" #include "QXmppTrustSecurityPolicy.h" #include "qxmppomemo_export.h" @@ -82,14 +81,14 @@ public: explicit QXmppOmemoManager(QXmppOmemoStorage *omemoStorage); ~QXmppOmemoManager() override; - QFuture<bool> load(); - QFuture<bool> setUp(); + QXmppTask<bool> load(); + QXmppTask<bool> setUp(); - QFuture<QByteArray> ownKey(); - QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(QXmpp::TrustLevels trustLevels = {}); - QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QList<QString> &jids, QXmpp::TrustLevels trustLevels = {}); + QXmppTask<QByteArray> ownKey(); + QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(QXmpp::TrustLevels trustLevels = {}); + QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QList<QString> &jids, QXmpp::TrustLevels trustLevels = {}); - QFuture<bool> changeDeviceLabel(const QString &deviceLabel = {}); + QXmppTask<bool> changeDeviceLabel(const QString &deviceLabel = {}); int maximumDevicesPerJid() const; void setMaximumDevicesPerJid(int maximum); @@ -97,14 +96,14 @@ public: int maximumDevicesPerStanza() const; void setMaximumDevicesPerStanza(int maximum); - QFuture<QVector<DevicesResult>> requestDeviceLists(const QList<QString> &jids); - QFuture<QVector<DevicesResult>> subscribeToDeviceLists(const QList<QString> &jids); - QFuture<QVector<DevicesResult>> unsubscribeFromDeviceLists(); + QXmppTask<QVector<DevicesResult>> requestDeviceLists(const QList<QString> &jids); + QXmppTask<QVector<DevicesResult>> subscribeToDeviceLists(const QList<QString> &jids); + QXmppTask<QVector<DevicesResult>> unsubscribeFromDeviceLists(); QXmppOmemoOwnDevice ownDevice(); - QFuture<QVector<QXmppOmemoDevice>> devices(); - QFuture<QVector<QXmppOmemoDevice>> devices(const QList<QString> &jids); - QFuture<QXmppPubSubManager::Result> removeContactDevices(const QString &jid); + QXmppTask<QVector<QXmppOmemoDevice>> devices(); + QXmppTask<QVector<QXmppOmemoDevice>> devices(const QList<QString> &jids); + QXmppTask<Result> removeContactDevices(const QString &jid); void setAcceptedSessionBuildingTrustLevels(QXmpp::TrustLevels trustLevels); QXmpp::TrustLevels acceptedSessionBuildingTrustLevels(); @@ -112,23 +111,23 @@ public: void setNewDeviceAutoSessionBuildingEnabled(bool isNewDeviceAutoSessionBuildingEnabled); bool isNewDeviceAutoSessionBuildingEnabled(); - QFuture<void> buildMissingSessions(const QList<QString> &jids); + QXmppTask<void> buildMissingSessions(const QList<QString> &jids); - QFuture<bool> resetOwnDevice(); - QFuture<bool> resetAll(); + QXmppTask<bool> resetOwnDevice(); + QXmppTask<bool> resetAll(); - QFuture<void> setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy); - QFuture<QXmpp::TrustSecurityPolicy> securityPolicy(); + QXmppTask<void> setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy); + QXmppTask<QXmpp::TrustSecurityPolicy> securityPolicy(); - QFuture<void> setTrustLevel(const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel); - QFuture<QXmpp::TrustLevel> trustLevel(const QString &keyOwnerJid, const QByteArray &keyId); + QXmppTask<void> setTrustLevel(const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel); + QXmppTask<QXmpp::TrustLevel> trustLevel(const QString &keyOwnerJid, const QByteArray &keyId); /// \cond - QFuture<MessageEncryptResult> encryptMessage(QXmppMessage &&message, const std::optional<QXmppSendStanzaParams> ¶ms) override; - QFuture<MessageDecryptResult> decryptMessage(QXmppMessage &&message) override; + QXmppTask<MessageEncryptResult> encryptMessage(QXmppMessage &&message, const std::optional<QXmppSendStanzaParams> ¶ms) override; + QXmppTask<MessageDecryptResult> decryptMessage(QXmppMessage &&message) override; - QFuture<IqEncryptResult> encryptIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) override; - QFuture<IqDecryptResult> decryptIq(const QDomElement &element) override; + QXmppTask<IqEncryptResult> encryptIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) override; + QXmppTask<IqDecryptResult> decryptIq(const QDomElement &element) override; bool isEncrypted(const QDomElement &) override; bool isEncrypted(const QXmppMessage &) override; diff --git a/src/omemo/QXmppOmemoManager_p.cpp b/src/omemo/QXmppOmemoManager_p.cpp index 722211a8..b5ccac90 100644 --- a/src/omemo/QXmppOmemoManager_p.cpp +++ b/src/omemo/QXmppOmemoManager_p.cpp @@ -614,10 +614,10 @@ signal_protocol_session_store ManagerPrivate::createSessionStore() const // // \return whether it succeeded // -QFuture<bool> ManagerPrivate::setUpDeviceId() +QXmppTask<bool> ManagerPrivate::setUpDeviceId() { auto future = pubSubManager->requestOwnPepItemIds(ns_omemo_2_bundles); - return chain<bool>(future, q, [this](QXmppPubSubManager::ItemIdsResult result) mutable { + return chain<bool>(std::move(future), q, [this](QXmppPubSubManager::ItemIdsResult result) mutable { // There can be the following cases: // 1. There is no PubSub node for device bundles: XEP-0030 states that a server must // respond with an error (at least ejabberd 22.05 responds with an empty node instead). @@ -1026,27 +1026,27 @@ bool ManagerPrivate::generateIdentityKeyPair(ratchet_identity_key_pair **identit // // \return the result of the encryption // -QFuture<QXmppE2eeExtension::MessageEncryptResult> ManagerPrivate::encryptMessageForRecipients(QXmppMessage &&message, QVector<QString> recipientJids, TrustLevels acceptedTrustLevels) +QXmppTask<QXmppE2eeExtension::MessageEncryptResult> ManagerPrivate::encryptMessageForRecipients(QXmppMessage &&message, QVector<QString> recipientJids, TrustLevels acceptedTrustLevels) { - QFutureInterface<QXmppE2eeExtension::MessageEncryptResult> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppE2eeExtension::MessageEncryptResult> interface; if (!isStarted) { QXmppError error { QStringLiteral("OMEMO manager must be started before encrypting"), SendError::EncryptionError }; - reportFinishedResult(interface, { error }); + interface.finish(error); } else { recipientJids.append(ownBareJid()); auto future = encryptStanza(message, recipientJids, acceptedTrustLevels); - await(future, q, [=, message = std::move(message)](std::optional<QXmppOmemoElement> omemoElement) mutable { + future.then(q, [=, message = std::move(message)](std::optional<QXmppOmemoElement> omemoElement) mutable { if (!omemoElement) { QXmppError error { QStringLiteral("OMEMO element could not be created"), QXmpp::SendError::EncryptionError, }; - reportFinishedResult(interface, { error }); + interface.finish(error); } else { const auto areDeliveryReceiptsUsed = message.isReceiptRequested() || !message.receiptId().isEmpty(); @@ -1080,12 +1080,12 @@ QFuture<QXmppE2eeExtension::MessageEncryptResult> ManagerPrivate::encryptMessage QXmlStreamWriter writer(&serializedEncryptedMessage); message.toXml(&writer, QXmpp::ScePublic); - reportFinishedResult(interface, { serializedEncryptedMessage }); + interface.finish(serializedEncryptedMessage); } }); } - return interface.future(); + return interface.task(); } // @@ -1100,11 +1100,11 @@ QFuture<QXmppE2eeExtension::MessageEncryptResult> ManagerPrivate::encryptMessage // successful, otherwise none // template<typename T> -QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T &stanza, const QVector<QString> &recipientJids, TrustLevels acceptedTrustLevels) +QXmppTask<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T &stanza, const QVector<QString> &recipientJids, TrustLevels acceptedTrustLevels) { Q_ASSERT_X(!recipientJids.isEmpty(), "Creating OMEMO envelope", "OMEMO element could not be created because no recipient JIDs are passed"); - QFutureInterface<std::optional<QXmppOmemoElement>> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<QXmppOmemoElement>> interface; if (const auto optionalPayloadEncryptionResult = encryptPayload(createSceEnvelope(stanza))) { const auto &payloadEncryptionResult = *optionalPayloadEncryptionResult; @@ -1141,7 +1141,7 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T if (++(*skippedDevicesCount) == devicesCount) { warning("OMEMO element could not be created because no recipient device responded to " % QString::number(unrespondedSentStanzasCount) % " sent stanzas"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } continue; @@ -1156,11 +1156,11 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T if (*successfullyProcessedDevicesCount == 0) { warning("OMEMO element could not be created because no recipient " "devices with keys having accepted trust levels could be found"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { omemoElement->setSenderDeviceId(ownDevice.id); omemoElement->setPayload(payloadEncryptionResult.encryptedPayload); - reportFinishedResult(interface, { *omemoElement }); + interface.finish(*omemoElement); } } }; @@ -1217,7 +1217,7 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T // determined and the session built. if (device.keyId.isEmpty()) { auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { + future.then(q, [=](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { // Process the device bundle only if one could be fetched and the // corresponding device has not been removed by another method in // the meantime. @@ -1228,12 +1228,12 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T deviceBeingModified.keyId = createKeyId(key); auto future = q->trustLevel(jid, deviceBeingModified.keyId); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { // Store the retrieved key's trust level if it is not stored // yet. if (trustLevel == TrustLevel::Undecided) { auto future = storeKeyDependingOnSecurityPolicy(jid, key); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { omemoStorage->addDevice(jid, deviceId, deviceBeingModified); Q_EMIT q->deviceChanged(jid, deviceId); buildSessionDependingOnTrustLevel(deviceBundle, trustLevel); @@ -1251,7 +1251,7 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T }); } else { auto future = q->trustLevel(jid, device.keyId); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { // Create only OMEMO envelopes for devices that have keys with // specific trust levels. if (acceptedTrustLevels.testFlag(trustLevel)) { @@ -1259,7 +1259,7 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T // Otherwise, use the existing session. if (device.session.isEmpty()) { auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { + future.then(q, [=](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { if (optionalDeviceBundle) { const auto &deviceBundle = *optionalDeviceBundle; buildSessionDependingOnTrustLevel(deviceBundle, trustLevel); @@ -1284,18 +1284,18 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T } } else { warning("OMEMO element could not be created because no recipient devices could be found"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } } else { warning("OMEMO payload could not be encrypted"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } - return interface.future(); + return interface.task(); } -template QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza<QXmppIq>(const QXmppIq &, const QVector<QString> &, TrustLevels); -template QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza<QXmppMessage>(const QXmppMessage &, const QVector<QString> &, TrustLevels); +template QXmppTask<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza<QXmppIq>(const QXmppIq &, const QVector<QString> &, TrustLevels); +template QXmppTask<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza<QXmppMessage>(const QXmppMessage &, const QVector<QString> &, TrustLevels); // // Encrypts a payload symmetrically. @@ -1440,9 +1440,9 @@ QByteArray ManagerPrivate::createOmemoEnvelopeData(const signal_protocol_address // // \return the decrypted stanza if it could be decrypted // -QFuture<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage stanza) +QXmppTask<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage stanza) { - QFutureInterface<std::optional<QXmppMessage>> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<QXmppMessage>> interface; // At this point, the stanza has always an OMEMO element. const auto omemoElement = *stanza.omemoElement(); @@ -1460,18 +1460,20 @@ QFuture<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage // with this device. if (omemoPayload.isEmpty()) { auto future = extractPayloadDecryptionData(senderJid, senderDeviceId, omemoEnvelope); - await(future, q, [=](QCA::SecureArray payloadDecryptionData) mutable { - if (payloadDecryptionData.isEmpty()) { + future.then(q, [=](std::optional<QCA::SecureArray> payloadDecryptionData) mutable { + if (!payloadDecryptionData) { + warning("Empty OMEMO message could not be successfully processed"); + } else if (payloadDecryptionData->isEmpty()) { warning("Empty OMEMO message could not be successfully processed"); } else { q->debug("Successfully processed empty OMEMO message"); } - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); }); } else { auto future = decryptStanza(stanza, senderJid, senderDeviceId, omemoEnvelope, omemoPayload); - await(future, q, [=](std::optional<DecryptionResult> optionalDecryptionResult) mutable { + future.then(q, [=](std::optional<DecryptionResult> optionalDecryptionResult) mutable { if (optionalDecryptionResult) { const auto decryptionResult = std::move(*optionalDecryptionResult); stanza.parseExtensions(decryptionResult.sceContent, SceSensitive); @@ -1482,15 +1484,15 @@ QFuture<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage stanza.setE2eeMetadata(decryptionResult.e2eeMetadata); - reportFinishedResult(interface, { stanza }); + interface.finish(stanza); } else { - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } }); } } - return interface.future(); + return interface.task(); } // @@ -1503,7 +1505,7 @@ QFuture<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage // // \return the serialized decrypted stanza if it could be decrypted // -QFuture<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomElement &iqElement) +QXmppTask<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomElement &iqElement) { using Result = std::optional<IqDecryptionResult>; @@ -1518,7 +1520,7 @@ QFuture<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomE subscribeToNewDeviceLists(senderJid, senderDeviceId); auto future = decryptStanza(iq, senderJid, senderDeviceId, *envelope, omemoElement.payload(), false); - return chain<Result>(future, q, [iqElement](auto result) -> Result { + return chain<Result>(std::move(future), q, [iqElement](auto result) -> Result { if (result) { auto decryptedElement = iqElement.cloneNode(true).toElement(); replaceChildElements(decryptedElement, result->sceContent); @@ -1528,7 +1530,7 @@ QFuture<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomE return {}; }); } - return makeReadyFuture<Result>(std::nullopt); + return makeReadyTask<Result>(std::nullopt); } // @@ -1549,15 +1551,15 @@ QFuture<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomE // \return the result of the decryption if it succeeded // template<typename T> -QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) +QXmppTask<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) { - QFutureInterface<std::optional<DecryptionResult>> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<DecryptionResult>> interface; auto future = extractSceEnvelope(senderJid, senderDeviceId, omemoEnvelope, omemoPayload, isMessageStanza); - await(future, q, [=](QByteArray serializedSceEnvelope) mutable { + future.then(q, [=](QByteArray serializedSceEnvelope) mutable { if (serializedSceEnvelope.isEmpty()) { warning("SCE envelope could not be extracted"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { QDomDocument document; document.setContent(serializedSceEnvelope, true); @@ -1565,7 +1567,7 @@ QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, if (sceEnvelopeReader.from() != senderJid) { warning("Sender '" % senderJid % "' of stanza does not match SCE 'from' affix element '" % sceEnvelopeReader.from() % "'"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { const auto recipientJid = QXmppUtils::jidToBareJid(stanza.to()); auto isSceAffixElementValid = true; @@ -1583,7 +1585,7 @@ QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, } if (!isSceAffixElementValid) { - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { auto &device = devices[senderJid][senderDeviceId]; device.unrespondedSentStanzasCount = 0; @@ -1603,13 +1605,13 @@ QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, const auto &senderDevice = devices.value(senderJid).value(senderDeviceId); e2eeMetadata.setSenderKey(senderDevice.keyId); - reportFinishedResult(interface, { { sceEnvelopeReader.contentElement(), e2eeMetadata } }); + interface.finish(DecryptionResult { sceEnvelopeReader.contentElement(), e2eeMetadata }); } } } }); - return interface.future(); + return interface.task(); } // @@ -1627,21 +1629,24 @@ QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, // \return the serialized SCE envelope if it could be extracted, otherwise a // default-constructed byte array // -QFuture<QByteArray> ManagerPrivate::extractSceEnvelope(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) +QXmppTask<QByteArray> ManagerPrivate::extractSceEnvelope(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) { - QFutureInterface<QByteArray> interface(QFutureInterfaceBase::Started); + QXmppPromise<QByteArray> interface; auto future = extractPayloadDecryptionData(senderJid, senderDeviceId, omemoEnvelope, isMessageStanza); - await(future, q, [=](QCA::SecureArray payloadDecryptionData) mutable { - if (payloadDecryptionData.isEmpty()) { + future.then(q, [=](std::optional<QCA::SecureArray> payloadDecryptionData) mutable { + if (!payloadDecryptionData) { + warning("Data for decrypting OMEMO payload could not be extracted"); + interface.finish(QByteArray()); + } else if (payloadDecryptionData->isEmpty()) { warning("Data for decrypting OMEMO payload could not be extracted"); - reportFinishedResult(interface, {}); + interface.finish(QByteArray()); } else { - reportFinishedResult(interface, decryptPayload(payloadDecryptionData, omemoPayload)); + interface.finish(decryptPayload(*payloadDecryptionData, omemoPayload)); } }); - return interface.future(); + return interface.task(); } // @@ -1657,9 +1662,9 @@ QFuture<QByteArray> ManagerPrivate::extractSceEnvelope(const QString &senderJid, // \return the serialized payload decryption data if it could be extracted, otherwise a // default-constructed secure array // -QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, bool isMessageStanza) +QXmppTask<std::optional<QCA::SecureArray>> ManagerPrivate::extractPayloadDecryptionData(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, bool isMessageStanza) { - QFutureInterface<QCA::SecureArray> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<QCA::SecureArray>> interface; SessionCipherPtr sessionCipher; const auto address = Address(senderJid, senderDeviceId); @@ -1667,7 +1672,7 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt if (session_cipher_create(sessionCipher.ptrRef(), storeContext.get(), &addressData, globalContext.get()) < 0) { warning("Session cipher could not be created"); - return {}; + return makeReadyTask<std::optional<QCA::SecureArray>>(std::nullopt); } session_cipher_set_version(sessionCipher.get(), CIPHERTEXT_OMEMO_VERSION); @@ -1682,7 +1687,7 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt auto payloadDecryptionData = QCA::SecureArray(payloadDecryptionDataBufferSize); std::copy_n(payloadDecryptionDataPointer, payloadDecryptionDataBufferSize, payloadDecryptionData.data()); - reportFinishedResult(interface, payloadDecryptionData); + interface.finish(std::move(payloadDecryptionData)); }; // There are three cases: @@ -1702,13 +1707,13 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt senderDeviceId, globalContext.get()) < 0) { warning("OMEMO envelope data could not be deserialized"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { BufferPtr publicIdentityKeyBuffer; if (ec_public_key_serialize(publicIdentityKeyBuffer.ptrRef(), pre_key_signal_message_get_identity_key(omemoEnvelopeData.get())) < 0) { warning("Public Identity key could not be retrieved"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { const auto key = publicIdentityKeyBuffer.toByteArray(); auto &device = devices[senderJid][senderDeviceId]; @@ -1726,30 +1731,30 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt switch (session_cipher_decrypt_pre_key_signal_message(sessionCipher.get(), omemoEnvelopeData.get(), nullptr, payloadDecryptionDataBuffer.ptrRef())) { case SG_ERR_INVALID_MESSAGE: warning("OMEMO envelope data for key exchange is not valid"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_DUPLICATE_MESSAGE: warning("OMEMO envelope data for key exchange is already received"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_LEGACY_MESSAGE: warning("OMEMO envelope data for key exchange format is deprecated"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_INVALID_KEY_ID: { const auto preKeyId = QString::number(pre_key_signal_message_get_pre_key_id(omemoEnvelopeData.get())); warning("Pre key with ID '" % preKeyId % "' of OMEMO envelope data for key exchange could not be found locally"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; } case SG_ERR_INVALID_KEY: warning("OMEMO envelope data for key exchange is incorrectly formatted"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_UNTRUSTED_IDENTITY: warning("Identity key of OMEMO envelope data for key exchange is not trusted by OMEMO library"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_SUCCESS: reportResult(payloadDecryptionDataBuffer); @@ -1764,14 +1769,14 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt // Store the key's trust level if it is not stored yet. auto future = q->trustLevel(senderJid, storedKeyId); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { if (trustLevel == TrustLevel::Undecided) { auto future = storeKeyDependingOnSecurityPolicy(senderJid, key); - await(future, q, [=](auto) mutable { - interface.reportFinished(); + future.then(q, [=](auto) mutable { + interface.finish(std::nullopt); }); } else { - interface.reportFinished(); + interface.finish(std::nullopt); } }); } @@ -1782,8 +1787,8 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt "sending device, new session is being built"); auto future = buildSessionWithDeviceBundle(senderJid, senderDeviceId, device); - await(future, q, [=](auto) mutable { - reportFinishedResult(interface, {}); + future.then(q, [=](auto) mutable { + interface.finish(std::nullopt); }); } else { RefCountedPtr<signal_message> omemoEnvelopeData; @@ -1791,32 +1796,32 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt if (signal_message_deserialize_omemo(omemoEnvelopeData.ptrRef(), reinterpret_cast<const uint8_t *>(serializedOmemoEnvelopeData.data()), serializedOmemoEnvelopeData.size(), globalContext.get()) < 0) { warning("OMEMO envelope data could not be deserialized"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { // Decrypt the OMEMO envelope data. switch (session_cipher_decrypt_signal_message(sessionCipher.get(), omemoEnvelopeData.get(), nullptr, payloadDecryptionDataBuffer.ptrRef())) { case SG_ERR_INVALID_MESSAGE: warning("OMEMO envelope data is not valid"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_DUPLICATE_MESSAGE: warning("OMEMO envelope data is already received"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_LEGACY_MESSAGE: warning("OMEMO envelope data format is deprecated"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_NO_SESSION: warning("Session for OMEMO envelope data could not be found"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); case SG_SUCCESS: reportResult(payloadDecryptionDataBuffer); } } } - return interface.future(); + return interface.task(); } // @@ -1881,16 +1886,16 @@ QByteArray ManagerPrivate::decryptPayload(const QCA::SecureArray &payloadDecrypt // // \return whether it succeeded // -QFuture<bool> ManagerPrivate::publishOmemoData() +QXmppTask<bool> ManagerPrivate::publishOmemoData() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; auto future = pubSubManager->requestOwnPepFeatures(); - await(future, q, [=](QXmppPubSubManager::FeaturesResult result) mutable { + future.then(q, [=](QXmppPubSubManager::FeaturesResult result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Features of PEP service '" % ownBareJid() % "' could not be retrieved: " % errorToString(*error)); warning("Device bundle and device list could not be published"); - reportFinishedResult(interface, false); + interface.finish(false); } else { const auto &pepServiceFeatures = std::get<QVector<QString>>(result); @@ -1904,13 +1909,13 @@ QFuture<bool> ManagerPrivate::publishOmemoData() // if (pepServiceFeatures.contains(ns_pubsub_publish) && pepServiceFeatures.contains(ns_pubsub_multi_items)) { if (pepServiceFeatures.contains(ns_pubsub_publish)) { auto future = pubSubManager->requestOwnPepNodes(); - await(future, q, [=](QXmppPubSubManager::NodesResult result) mutable { + future.then(q, [=](QXmppPubSubManager::NodesResult result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Nodes of JID '" % ownBareJid() % "' could not be fetched to check if nodes '" % QString(ns_omemo_2_bundles) % "' and '" % QString(ns_omemo_2_devices) % "' exist: " % errorToString(*error)); warning("Device bundle and device list could not be published"); - reportFinishedResult(interface, false); + interface.finish(false); } else { const auto &nodes = std::get<QVector<QString>>(result); @@ -1943,11 +1948,11 @@ QFuture<bool> ManagerPrivate::publishOmemoData() if (!isPublished) { warning("Device element could not be published"); } - reportFinishedResult(interface, isPublished); + interface.finish(std::move(isPublished)); }); } else { warning("Device bundle could not be published"); - reportFinishedResult(interface, false); + interface.finish(false); } }; publishDeviceBundle(nodes.contains(ns_omemo_2_bundles), @@ -1963,12 +1968,12 @@ QFuture<bool> ManagerPrivate::publishOmemoData() } else { warning("Publishing (multiple) items to PEP node '" % ownBareJid() % "' is not supported"); warning("Device bundle and device list could not be published"); - reportFinishedResult(interface, false); + interface.finish(false); } } }); - return interface.future(); + return interface.task(); } // @@ -2310,23 +2315,23 @@ QXmppOmemoDeviceBundleItem ManagerPrivate::deviceBundleItem() const // // \return the device bundle on success, otherwise a nullptr // -QFuture<std::optional<QXmppOmemoDeviceBundle>> ManagerPrivate::requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const +QXmppTask<std::optional<QXmppOmemoDeviceBundle>> ManagerPrivate::requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const { - QFutureInterface<std::optional<QXmppOmemoDeviceBundle>> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<QXmppOmemoDeviceBundle>> interface; auto future = pubSubManager->requestItem<QXmppOmemoDeviceBundleItem>(deviceOwnerJid, ns_omemo_2_bundles, QString::number(deviceId)); - await(future, q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceBundleItem> result) mutable { + future.then(q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceBundleItem> result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device bundle for JID '" % deviceOwnerJid % "' and device ID '" % QString::number(deviceId) % "' could not be retrieved: " % errorToString(*error)); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { const auto &item = std::get<QXmppOmemoDeviceBundleItem>(result); - reportFinishedResult(interface, { item.deviceBundle() }); + interface.finish(item.deviceBundle()); } }); - return interface.future(); + return interface.task(); } // @@ -2620,7 +2625,7 @@ void ManagerPrivate::updateOwnDevicesLocally(bool isDeviceListNodeExistent, Func { if (isDeviceListNodeExistent && otherOwnDevices().isEmpty()) { auto future = pubSubManager->requestOwnPepItem<QXmppOmemoDeviceListItem>(ns_omemo_2_devices, QXmppPubSubManager::Current); - await(future, q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable { + future.then(q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device list for JID '" % ownBareJid() % "' could not be retrieved and thus not updated: " % @@ -2656,9 +2661,9 @@ void ManagerPrivate::updateOwnDevicesLocally(bool isDeviceListNodeExistent, Func device.label = deviceElement.label(); auto future = omemoStorage->addDevice(jid, deviceId, device); - await(future, q, [=, &device]() mutable { + future.then(q, [=, &device]() mutable { auto future = buildSessionForNewDevice(jid, deviceId, device); - await(future, q, [=](auto) mutable { + future.then(q, [=](auto) mutable { Q_EMIT q->deviceAdded(jid, deviceId); if (++(*processedDevicesCount) == devicesCount) { @@ -2805,7 +2810,7 @@ void ManagerPrivate::updateDevices(const QString &deviceOwnerJid, const QXmppOme omemoStorage->addDevice(deviceOwnerJid, deviceId, device); auto future = buildSessionForNewDevice(deviceOwnerJid, deviceId, device); - await(future, q, [=](auto) { + future.then(q, [=](auto) { Q_EMIT q->deviceAdded(deviceOwnerJid, deviceId); }); } @@ -2839,14 +2844,14 @@ void ManagerPrivate::handleIrregularDeviceListChanges(const QString &deviceOwner // item is removed, if their device list node is removed or if all // the node's items are removed. auto future = pubSubManager->deleteOwnPepNode(ns_omemo_2_devices); - await(future, q, [=](QXmppPubSubManager::Result result) { + future.then(q, [=](QXmppPubSubManager::Result result) { if (const auto error = std::get_if<Error>(&result)) { warning("Node '" % QString(ns_omemo_2_devices) % "' of JID '" % deviceOwnerJid % "' could not be deleted in order to recover from an inconsistent node: " % errorToString(*error)); } else { auto future = pubSubManager->requestOwnPepFeatures(); - await(future, q, [=](QXmppPubSubManager::FeaturesResult result) { + future.then(q, [=](QXmppPubSubManager::FeaturesResult result) { if (const auto error = std::get_if<Error>(&result)) { warning("Features of PEP service '" % deviceOwnerJid % "' could not be retrieved: " % errorToString(*error)); @@ -2979,7 +2984,7 @@ template<typename Function> void ManagerPrivate::deleteNode(const QString &node, Function continuation) { auto future = pubSubManager->deleteOwnPepNode(node); - await(future, q, [=, continuation = std::move(continuation)](QXmppPubSubManager::Result result) mutable { + future.then(q, [=, continuation = std::move(continuation)](QXmppPubSubManager::Result result) mutable { const auto error = std::get_if<Error>(&result); if (error) { const auto errorType = error->type(); @@ -3040,9 +3045,9 @@ void ManagerPrivate::publishItem(const QString &node, const T &item, const QXmpp // \param continuation function to be called after the PubSub query // template<typename T, typename Function> -void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QFuture<T> future, const QString &errorMessage, Function continuation) +void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QXmppTask<T> future, const QString &errorMessage, Function continuation) { - await(future, q, [this, errorMessage, continuation = std::move(continuation)](auto result) mutable { + future.then(q, [this, errorMessage, continuation = std::move(continuation)](auto result) mutable { if (auto error = std::get_if<Error>(&result)) { warning(errorMessage % u": " % errorToString(*error)); continuation(false); @@ -3053,24 +3058,24 @@ void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QFuture<T> future, } // See QXmppOmemoManager for documentation -QFuture<bool> ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) +QXmppTask<bool> ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; ownDevice.label = deviceLabel; if (isStarted) { auto future = omemoStorage->setOwnDevice(ownDevice); - await(future, q, [=]() mutable { + future.then(q, [=]() mutable { publishDeviceListItem(true, [=](bool isPublished) mutable { - reportFinishedResult(interface, isPublished); + interface.finish(std::move(isPublished)); }); }); } else { - reportFinishedResult(interface, true); + interface.finish(true); } - return interface.future(); + return interface.task(); } // @@ -3084,10 +3089,10 @@ QFuture<bool> ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) // // \return the result of the request // -QFuture<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> ManagerPrivate::requestDeviceList(const QString &jid) +QXmppTask<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> ManagerPrivate::requestDeviceList(const QString &jid) { auto future = pubSubManager->requestItem<QXmppOmemoDeviceListItem>(jid, ns_omemo_2_devices, QXmppPubSubManager::Current); - await(future, q, [this, jid](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable { + future.then(q, [this, jid](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device list for JID '" % jid % "' could not be retrieved: " % errorToString(*error)); } else { @@ -3122,26 +3127,26 @@ void ManagerPrivate::subscribeToNewDeviceLists(const QString &jid, uint32_t devi // // \return the result of the subscription and manual request // -QFuture<QXmppPubSubManager::Result> ManagerPrivate::subscribeToDeviceList(const QString &jid) +QXmppTask<QXmppPubSubManager::Result> ManagerPrivate::subscribeToDeviceList(const QString &jid) { - QFutureInterface<QXmppPubSubManager::Result> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppPubSubManager::Result> interface; auto future = pubSubManager->subscribeToNode(jid, ns_omemo_2_devices, ownFullJid()); - await(future, q, [=](QXmppPubSubManager::Result result) mutable { + future.then(q, [=](QXmppPubSubManager::Result result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device list for JID '" % jid % "' could not be subscribed: " % errorToString(*error)); - reportFinishedResult(interface, { *error }); + interface.finish(*error); } else { jidsOfManuallySubscribedDevices.append(jid); auto future = requestDeviceList(jid); - await(future, q, [=](auto result) mutable { - reportFinishedResult(interface, mapToSuccess(std::move(result))); + future.then(q, [=](auto result) mutable { + interface.finish(mapToSuccess(std::move(result))); }); } }); - return interface.future(); + return interface.task(); } // @@ -3154,16 +3159,17 @@ QFuture<QXmppPubSubManager::Result> ManagerPrivate::subscribeToDeviceList(const // // \return the results of each unsubscribe request // -QFuture<QVector<Manager::DevicesResult>> ManagerPrivate::unsubscribeFromDeviceLists(const QList<QString> &jids) +QXmppTask<QVector<Manager::DevicesResult>> ManagerPrivate::unsubscribeFromDeviceLists(const QList<QString> &jids) { if (jids.isEmpty()) { - return makeReadyFuture(QVector<Manager::DevicesResult>()); + return makeReadyTask(QVector<Manager::DevicesResult>()); } - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface<QVector<Manager::DevicesResult>> interface; + QXmppPromise<QVector<Manager::DevicesResult>> interface; QVector<Manager::DevicesResult> devicesResults; }; @@ -3171,19 +3177,18 @@ QFuture<QVector<Manager::DevicesResult>> ManagerPrivate::unsubscribeFromDeviceLi state->jidsCount = jids.count(); for (const auto &jid : jids) { - await(unsubscribeFromDeviceList(jid), q, [jid, state](QXmppPubSubManager::Result result) mutable { + unsubscribeFromDeviceList(jid).then(q, [jid, state](QXmppPubSubManager::Result result) mutable { state->devicesResults << Manager::DevicesResult { jid, result }; if (++(state->processed) == state->jidsCount) { - state->interface.reportResult(state->devicesResults); - state->interface.reportFinished(); + state->interface.finish(std::move(state->devicesResults)); } }); } - return state->interface.future(); + return state->interface.task(); } // @@ -3195,35 +3200,35 @@ QFuture<QVector<Manager::DevicesResult>> ManagerPrivate::unsubscribeFromDeviceLi // // \return the result of the unsubscription // -QFuture<QXmppPubSubManager::Result> ManagerPrivate::unsubscribeFromDeviceList(const QString &jid) +QXmppTask<QXmppPubSubManager::Result> ManagerPrivate::unsubscribeFromDeviceList(const QString &jid) { - QFutureInterface<QXmppPubSubManager::Result> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppPubSubManager::Result> interface; auto future = pubSubManager->unsubscribeFromNode(jid, ns_omemo_2_devices, ownFullJid()); - await(future, q, [=](QXmppPubSubManager::Result result) mutable { + future.then(q, [=](QXmppPubSubManager::Result result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device list for JID '" % jid % "' could not be unsubscribed: " % errorToString(*error)); } else { jidsOfManuallySubscribedDevices.removeAll(jid); } - reportFinishedResult(interface, result); + interface.finish(std::move(result)); }); - return interface.future(); + return interface.task(); } // See QXmppOmemoManager for documentation -QFuture<bool> ManagerPrivate::resetOwnDevice() +QXmppTask<bool> ManagerPrivate::resetOwnDevice() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; isStarted = false; auto future = trustManager->resetAll(ns_omemo_2); - await(future, q, [=]() mutable { + future.then(q, [=]() mutable { auto future = omemoStorage->resetAll(); - await(future, q, [=]() mutable { + future.then(q, [=]() mutable { deleteDeviceElement([=](bool isDeviceElementDeleted) mutable { if (isDeviceElementDeleted) { deleteDeviceBundle([=](bool isDeviceBundleDeleted) mutable { @@ -3237,29 +3242,29 @@ QFuture<bool> ManagerPrivate::resetOwnDevice() Q_EMIT q->allDevicesRemoved(); } - reportFinishedResult(interface, isDeviceBundleDeleted); + interface.finish(std::move(isDeviceBundleDeleted)); }); } else { - reportFinishedResult(interface, false); + interface.finish(false); } }); }); }); - return interface.future(); + return interface.task(); } // See QXmppOmemoManager for documentation -QFuture<bool> ManagerPrivate::resetAll() +QXmppTask<bool> ManagerPrivate::resetAll() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; isStarted = false; auto future = trustManager->resetAll(ns_omemo_2); - await(future, q, [this, interface]() mutable { + future.then(q, [this, interface]() mutable { auto future = omemoStorage->resetAll(); - await(future, q, [this, interface]() mutable { + future.then(q, [this, interface]() mutable { deleteNode(ns_omemo_2_devices, [this, interface](bool isDevicesNodeDeleted) mutable { if (isDevicesNodeDeleted) { deleteNode(ns_omemo_2_bundles, [this, interface](bool isBundlesNodeDeleted) mutable { @@ -3273,16 +3278,16 @@ QFuture<bool> ManagerPrivate::resetAll() Q_EMIT q->allDevicesRemoved(); } - reportFinishedResult(interface, isBundlesNodeDeleted); + interface.finish(std::move(isBundlesNodeDeleted)); }); } else { - reportFinishedResult(interface, false); + interface.finish(false); } }); }); }); - return interface.future(); + return interface.task(); } // @@ -3297,12 +3302,12 @@ QFuture<bool> ManagerPrivate::resetAll() // \return true if a session could be built or it is not enabled, otherwise // false // -QFuture<bool> ManagerPrivate::buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) +QXmppTask<bool> ManagerPrivate::buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) { if (isNewDeviceAutoSessionBuildingEnabled) { return buildSessionWithDeviceBundle(jid, deviceId, device); } else { - return makeReadyFuture(true); + return makeReadyTask(true); } } @@ -3315,19 +3320,19 @@ QFuture<bool> ManagerPrivate::buildSessionForNewDevice(const QString &jid, uint3 // // \return whether a session could be built // -QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) +QXmppTask<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=, &device](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { + future.then(q, [=, &device](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { if (optionalDeviceBundle) { const auto &deviceBundle = *optionalDeviceBundle; const auto key = deviceBundle.publicIdentityKey(); device.keyId = createKeyId(key); auto future = q->trustLevel(jid, device.keyId); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { auto buildSessionDependingOnTrustLevel = [=](TrustLevel trustLevel) mutable { // Build a session if the device's key has a specific trust // level and send an empty OMEMO (key exchange) message to @@ -3336,20 +3341,20 @@ QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u warning("Session could not be created for JID '" % jid % "' with device ID '" % QString::number(deviceId) % "' because its key's trust level '" % QString::number(int(trustLevel)) % "' is not accepted"); - reportFinishedResult(interface, false); + interface.finish(false); } else if (const auto address = Address(jid, deviceId); !buildSession(address.data(), deviceBundle)) { warning("Session could not be created for JID '" % jid % "' and device ID '" % QString::number(deviceId) % "'"); - reportFinishedResult(interface, false); + interface.finish(false); } else { auto future = sendEmptyMessage(jid, deviceId, true); - await(future, q, [=](QXmpp::SendResult result) mutable { + future.then(q, [=](QXmpp::SendResult result) mutable { if (std::holds_alternative<QXmppError>(result)) { warning("Session could be created but empty message could not be sent to JID '" % jid % "' and device ID '" % QString::number(deviceId) % "'"); - reportFinishedResult(interface, false); + interface.finish(false); } else { - reportFinishedResult(interface, true); + interface.finish(true); } }); } @@ -3358,7 +3363,7 @@ QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u if (trustLevel == TrustLevel::Undecided) { // Store the key's trust level if it is not stored yet. auto future = storeKeyDependingOnSecurityPolicy(jid, key); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { buildSessionDependingOnTrustLevel(trustLevel); }); } else { @@ -3369,11 +3374,11 @@ QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u warning("Session could not be created because no device bundle could be fetched for " "JID '" % jid % "' and device ID '" % QString::number(deviceId) % "'"); - reportFinishedResult(interface, false); + interface.finish(false); } }); - return interface.future(); + return interface.task(); } // @@ -3388,7 +3393,7 @@ QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u // bool ManagerPrivate::buildSession(signal_protocol_address address, const QXmppOmemoDeviceBundle &deviceBundle) { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; // Choose a pre key randomly. const auto publicPreKeys = deviceBundle.publicPreKeys(); @@ -3577,9 +3582,9 @@ bool ManagerPrivate::deserializePublicPreKey(ec_public_key **publicPreKey, const // // \return the result of the sending // -QFuture<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange) const +QXmppTask<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange) const { - QFutureInterface<QXmpp::SendResult> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmpp::SendResult> interface; const auto address = Address(recipientJid, recipientDeviceId); const auto decryptionData = QCA::SecureArray(EMPTY_MESSAGE_DECRYPTION_DATA_SIZE); @@ -3592,7 +3597,7 @@ QFuture<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recip QStringLiteral("OMEMO envelope could not be created"), SendError::EncryptionError }; - reportFinishedResult(interface, { error }); + interface.finish(error); } else { QXmppOmemoEnvelope omemoEnvelope; omemoEnvelope.setRecipientDeviceId(recipientDeviceId); @@ -3611,12 +3616,12 @@ QFuture<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recip message.setOmemoElement(omemoElement); auto future = q->client()->sendUnencrypted(std::move(message)); - await(future, q, [=](QXmpp::SendResult result) mutable { - reportFinishedResult(interface, result); + future.then(q, [=](QXmpp::SendResult result) mutable { + interface.finish(std::move(result)); }); } - return interface.future(); + return interface.task(); } // @@ -3627,16 +3632,16 @@ QFuture<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recip // It corresponds to the fingerprint shown to users which also does not contain // the first byte. // -QFuture<void> ManagerPrivate::storeOwnKey() const +QXmppTask<void> ManagerPrivate::storeOwnKey() const { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> interface; auto future = trustManager->setOwnKey(ns_omemo_2, createKeyId(ownDevice.publicIdentityKey)); - await(future, q, [=]() mutable { - interface.reportFinished(); + future.then(q, [=]() mutable { + interface.finish(); }); - return interface.future(); + return interface.task(); } // @@ -3648,18 +3653,18 @@ QFuture<void> ManagerPrivate::storeOwnKey() const // // \return the trust level of the stored key // -QFuture<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key) +QXmppTask<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key) { - QFutureInterface<TrustLevel> interface(QFutureInterfaceBase::Started); + QXmppPromise<TrustLevel> interface; - auto awaitStoreKey = [=](const QFuture<TrustLevel> &future) mutable { - await(future, q, [=](TrustLevel trustLevel) mutable { - reportFinishedResult(interface, trustLevel); + auto awaitStoreKey = [=](QXmppTask<TrustLevel> &future) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { + interface.finish(std::move(trustLevel)); }); }; auto future = q->securityPolicy(); - await(future, q, [=](TrustSecurityPolicy securityPolicy) mutable { + future.then(q, [=](TrustSecurityPolicy securityPolicy) mutable { switch (securityPolicy) { case NoSecurityPolicy: { auto future = storeKey(keyOwnerJid, key); @@ -3668,7 +3673,7 @@ QFuture<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QStr } case Toakafa: { auto future = trustManager->hasKey(ns_omemo_2, keyOwnerJid, TrustLevel::Authenticated); - await(future, q, [=](bool hasAuthenticatedKey) mutable { + future.then(q, [=](bool hasAuthenticatedKey) mutable { if (hasAuthenticatedKey) { // If there is at least one authenticated key, add the // new key as an automatically distrusted one. @@ -3688,7 +3693,7 @@ QFuture<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QStr } }); - return interface.future(); + return interface.task(); } // @@ -3700,17 +3705,17 @@ QFuture<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QStr // // \return the trust level of the stored key // -QFuture<TrustLevel> ManagerPrivate::storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel) const +QXmppTask<TrustLevel> ManagerPrivate::storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel) const { - QFutureInterface<TrustLevel> interface(QFutureInterfaceBase::Started); + QXmppPromise<TrustLevel> interface; auto future = trustManager->addKeys(ns_omemo_2, keyOwnerJid, { createKeyId(key) }, trustLevel); - await(future, q, [=]() mutable { + future.then(q, [=]() mutable { Q_EMIT q->trustLevelsChanged({ { keyOwnerJid, key } }); - reportFinishedResult(interface, trustLevel); + interface.finish(std::move(trustLevel)); }); - return interface.future(); + return interface.task(); } // diff --git a/src/omemo/QXmppOmemoManager_p.h b/src/omemo/QXmppOmemoManager_p.h index 78cf482f..bce22042 100644 --- a/src/omemo/QXmppOmemoManager_p.h +++ b/src/omemo/QXmppOmemoManager_p.h @@ -10,6 +10,7 @@ #include "QXmppOmemoDeviceBundle_p.h" #include "QXmppOmemoManager.h" #include "QXmppOmemoStorage.h" +#include "QXmppPubSubManager.h" #include "OmemoLibWrappers.h" #include "QcaInitializer_p.h" @@ -177,7 +178,7 @@ public: signal_protocol_pre_key_store createPreKeyStore() const; signal_protocol_session_store createSessionStore() const; - QFuture<bool> setUpDeviceId(); + QXmppTask<bool> setUpDeviceId(); std::optional<uint32_t> generateDeviceId(); std::optional<uint32_t> generateDeviceId(const QVector<QString> &existingIds); bool setUpIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair); @@ -189,37 +190,37 @@ public: void removeDevicesRemovedFromServer(); bool generateIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair) const; - QFuture<QXmppE2eeExtension::MessageEncryptResult> encryptMessageForRecipients(QXmppMessage &&message, - QVector<QString> recipientJids, - TrustLevels acceptedTrustLevels); + QXmppTask<QXmppE2eeExtension::MessageEncryptResult> encryptMessageForRecipients(QXmppMessage &&message, + QVector<QString> recipientJids, + TrustLevels acceptedTrustLevels); template<typename T> - QFuture<std::optional<QXmppOmemoElement>> encryptStanza(const T &stanza, const QVector<QString> &recipientJids, TrustLevels acceptedTrustLevels); + QXmppTask<std::optional<QXmppOmemoElement>> encryptStanza(const T &stanza, const QVector<QString> &recipientJids, TrustLevels acceptedTrustLevels); std::optional<PayloadEncryptionResult> encryptPayload(const QByteArray &payload) const; template<typename T> QByteArray createSceEnvelope(const T &stanza); QByteArray createOmemoEnvelopeData(const signal_protocol_address &address, const QCA::SecureArray &payloadDecryptionData) const; - QFuture<std::optional<QXmppMessage>> decryptMessage(QXmppMessage stanza); - QFuture<std::optional<IqDecryptionResult>> decryptIq(const QDomElement &iqElement); + QXmppTask<std::optional<QXmppMessage>> decryptMessage(QXmppMessage stanza); + QXmppTask<std::optional<IqDecryptionResult>> decryptIq(const QDomElement &iqElement); template<typename T> - QFuture<std::optional<DecryptionResult>> decryptStanza(T stanza, - const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - const QByteArray &omemoPayload, - bool isMessageStanza = true); - QFuture<QByteArray> extractSceEnvelope(const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - const QByteArray &omemoPayload, - bool isMessageStanza); - QFuture<QCA::SecureArray> extractPayloadDecryptionData(const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - bool isMessageStanza = true); + QXmppTask<std::optional<DecryptionResult>> decryptStanza(T stanza, + const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + const QByteArray &omemoPayload, + bool isMessageStanza = true); + QXmppTask<QByteArray> extractSceEnvelope(const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + const QByteArray &omemoPayload, + bool isMessageStanza); + QXmppTask<std::optional<QCA::SecureArray>> extractPayloadDecryptionData(const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + bool isMessageStanza = true); QByteArray decryptPayload(const QCA::SecureArray &payloadDecryptionData, const QByteArray &payload) const; - QFuture<bool> publishOmemoData(); + QXmppTask<bool> publishOmemoData(); template<typename Function> void publishDeviceBundle(bool isDeviceBundlesNodeExistent, @@ -250,7 +251,7 @@ public: template<typename Function> void publishDeviceBundleItemWithOptions(Function continuation); QXmppOmemoDeviceBundleItem deviceBundleItem() const; - QFuture<std::optional<QXmppOmemoDeviceBundle>> requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const; + QXmppTask<std::optional<QXmppOmemoDeviceBundle>> requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const; template<typename Function> void deleteDeviceBundle(Function continuation); @@ -305,21 +306,21 @@ public: void publishItem(const QString &node, const T &item, const QXmppPubSubPublishOptions &publishOptions, Function continuation); template<typename T, typename Function> - void runPubSubQueryWithContinuation(QFuture<T> future, const QString &errorMessage, Function continuation); + void runPubSubQueryWithContinuation(QXmppTask<T> future, const QString &errorMessage, Function continuation); - QFuture<bool> changeDeviceLabel(const QString &deviceLabel); + QXmppTask<bool> changeDeviceLabel(const QString &deviceLabel); - QFuture<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> requestDeviceList(const QString &jid); + QXmppTask<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> requestDeviceList(const QString &jid); void subscribeToNewDeviceLists(const QString &jid, uint32_t deviceId); - QFuture<Result> subscribeToDeviceList(const QString &jid); - QFuture<QVector<QXmppOmemoManager::DevicesResult>> unsubscribeFromDeviceLists(const QList<QString> &jids); - QFuture<Result> unsubscribeFromDeviceList(const QString &jid); + QXmppTask<Result> subscribeToDeviceList(const QString &jid); + QXmppTask<QVector<QXmppOmemoManager::DevicesResult>> unsubscribeFromDeviceLists(const QList<QString> &jids); + QXmppTask<Result> unsubscribeFromDeviceList(const QString &jid); - QFuture<bool> resetOwnDevice(); - QFuture<bool> resetAll(); + QXmppTask<bool> resetOwnDevice(); + QXmppTask<bool> resetAll(); - QFuture<bool> buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); - QFuture<bool> buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); + QXmppTask<bool> buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); + QXmppTask<bool> buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); bool buildSession(signal_protocol_address address, const QXmppOmemoDeviceBundle &deviceBundle); bool createSessionBundle(session_pre_key_bundle **sessionBundle, const QByteArray &serializedPublicIdentityKey, @@ -332,10 +333,10 @@ public: bool deserializeSignedPublicPreKey(ec_public_key **signedPublicPreKey, const QByteArray &serializedSignedPublicPreKey) const; bool deserializePublicPreKey(ec_public_key **publicPreKey, const QByteArray &serializedPublicPreKey) const; - QFuture<QXmpp::SendResult> sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange = false) const; - QFuture<void> storeOwnKey() const; - QFuture<TrustLevel> storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key); - QFuture<TrustLevel> storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel = TrustLevel::AutomaticallyDistrusted) const; + QXmppTask<QXmpp::SendResult> sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange = false) const; + QXmppTask<void> storeOwnKey() const; + QXmppTask<TrustLevel> storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key); + QXmppTask<TrustLevel> storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel = TrustLevel::AutomaticallyDistrusted) const; QString ownBareJid() const; QString ownFullJid() const; QHash<uint32_t, QXmppOmemoStorage::Device> otherOwnDevices(); diff --git a/src/omemo/QXmppOmemoMemoryStorage.cpp b/src/omemo/QXmppOmemoMemoryStorage.cpp index 6ff81002..6ccf7332 100644 --- a/src/omemo/QXmppOmemoMemoryStorage.cpp +++ b/src/omemo/QXmppOmemoMemoryStorage.cpp @@ -47,51 +47,51 @@ QXmppOmemoMemoryStorage::QXmppOmemoMemoryStorage() QXmppOmemoMemoryStorage::~QXmppOmemoMemoryStorage() = default; /// \cond -QFuture<QXmppOmemoStorage::OmemoData> QXmppOmemoMemoryStorage::allData() +QXmppTask<QXmppOmemoStorage::OmemoData> QXmppOmemoMemoryStorage::allData() { - return makeReadyFuture(std::move(OmemoData { d->ownDevice, - d->signedPreKeyPairs, - d->preKeyPairs, - d->devices })); + return makeReadyTask(std::move(OmemoData { d->ownDevice, + d->signedPreKeyPairs, + d->preKeyPairs, + d->devices })); } -QFuture<void> QXmppOmemoMemoryStorage::setOwnDevice(const std::optional<OwnDevice> &device) +QXmppTask<void> QXmppOmemoMemoryStorage::setOwnDevice(const std::optional<OwnDevice> &device) { d->ownDevice = device; - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::addSignedPreKeyPair(const uint32_t keyId, const SignedPreKeyPair &keyPair) +QXmppTask<void> QXmppOmemoMemoryStorage::addSignedPreKeyPair(const uint32_t keyId, const SignedPreKeyPair &keyPair) { d->signedPreKeyPairs.insert(keyId, keyPair); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::removeSignedPreKeyPair(const uint32_t keyId) +QXmppTask<void> QXmppOmemoMemoryStorage::removeSignedPreKeyPair(const uint32_t keyId) { d->signedPreKeyPairs.remove(keyId); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) +QXmppTask<void> QXmppOmemoMemoryStorage::addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) { d->preKeyPairs.insert(keyPairs); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::removePreKeyPair(const uint32_t keyId) +QXmppTask<void> QXmppOmemoMemoryStorage::removePreKeyPair(const uint32_t keyId) { d->preKeyPairs.remove(keyId); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::addDevice(const QString &jid, const uint32_t deviceId, const QXmppOmemoStorage::Device &device) +QXmppTask<void> QXmppOmemoMemoryStorage::addDevice(const QString &jid, const uint32_t deviceId, const QXmppOmemoStorage::Device &device) { d->devices[jid].insert(deviceId, device); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const uint32_t deviceId) +QXmppTask<void> QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const uint32_t deviceId) { auto &devices = d->devices[jid]; devices.remove(deviceId); @@ -102,18 +102,18 @@ QFuture<void> QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const ui d->devices.remove(jid); } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::removeDevices(const QString &jid) +QXmppTask<void> QXmppOmemoMemoryStorage::removeDevices(const QString &jid) { d->devices.remove(jid); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::resetAll() +QXmppTask<void> QXmppOmemoMemoryStorage::resetAll() { d.reset(new QXmppOmemoMemoryStoragePrivate()); - return makeReadyFuture(); + return makeReadyTask(); } /// \endcond diff --git a/src/omemo/QXmppOmemoMemoryStorage.h b/src/omemo/QXmppOmemoMemoryStorage.h index 9e2c89c6..f9d9b8a1 100644 --- a/src/omemo/QXmppOmemoMemoryStorage.h +++ b/src/omemo/QXmppOmemoMemoryStorage.h @@ -6,6 +6,7 @@ #define QXMPPOMEMOMEMORYSTORAGE_H #include "QXmppOmemoStorage.h" +#include "QXmppTask.h" #include "qxmppomemo_export.h" #include <memory> @@ -19,21 +20,21 @@ public: ~QXmppOmemoMemoryStorage() override; /// \cond - QFuture<OmemoData> allData() override; + QXmppTask<OmemoData> allData() override; - QFuture<void> setOwnDevice(const std::optional<OwnDevice> &device) override; + QXmppTask<void> setOwnDevice(const std::optional<OwnDevice> &device) override; - QFuture<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) override; - QFuture<void> removeSignedPreKeyPair(uint32_t keyId) override; + QXmppTask<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) override; + QXmppTask<void> removeSignedPreKeyPair(uint32_t keyId) override; - QFuture<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) override; - QFuture<void> removePreKeyPair(uint32_t keyId) override; + QXmppTask<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) override; + QXmppTask<void> removePreKeyPair(uint32_t keyId) override; - QFuture<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) override; - QFuture<void> removeDevice(const QString &jid, uint32_t deviceId) override; - QFuture<void> removeDevices(const QString &jid) override; + QXmppTask<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) override; + QXmppTask<void> removeDevice(const QString &jid, uint32_t deviceId) override; + QXmppTask<void> removeDevices(const QString &jid) override; - QFuture<void> resetAll() override; + QXmppTask<void> resetAll() override; /// \endcond private: diff --git a/src/omemo/QXmppOmemoStorage.h b/src/omemo/QXmppOmemoStorage.h index e3139544..3049c0df 100644 --- a/src/omemo/QXmppOmemoStorage.h +++ b/src/omemo/QXmppOmemoStorage.h @@ -5,6 +5,7 @@ #ifndef QXMPPOMEMOSTORAGE_H #define QXMPPOMEMOSTORAGE_H +#include "QXmppTask.h" #include "qxmppomemo_export.h" #include <optional> @@ -154,21 +155,21 @@ public: virtual ~QXmppOmemoStorage() = default; - virtual QFuture<OmemoData> allData() = 0; + virtual QXmppTask<OmemoData> allData() = 0; - virtual QFuture<void> setOwnDevice(const std::optional<OwnDevice> &device) = 0; + virtual QXmppTask<void> setOwnDevice(const std::optional<OwnDevice> &device) = 0; - virtual QFuture<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) = 0; - virtual QFuture<void> removeSignedPreKeyPair(uint32_t keyId) = 0; + virtual QXmppTask<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) = 0; + virtual QXmppTask<void> removeSignedPreKeyPair(uint32_t keyId) = 0; - virtual QFuture<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) = 0; - virtual QFuture<void> removePreKeyPair(uint32_t keyId) = 0; + virtual QXmppTask<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) = 0; + virtual QXmppTask<void> removePreKeyPair(uint32_t keyId) = 0; - virtual QFuture<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) = 0; - virtual QFuture<void> removeDevice(const QString &jid, uint32_t deviceId) = 0; - virtual QFuture<void> removeDevices(const QString &jid) = 0; + virtual QXmppTask<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) = 0; + virtual QXmppTask<void> removeDevice(const QString &jid, uint32_t deviceId) = 0; + virtual QXmppTask<void> removeDevices(const QString &jid) = 0; - virtual QFuture<void> resetAll() = 0; + virtual QXmppTask<void> resetAll() = 0; }; #endif // QXMPPOMEMOSTORAGE_H |
