From b17284ee7d674416e0d11f1699f73fcc606262d4 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Tue, 16 Aug 2022 21:00:15 +0200 Subject: Introduce QXmppTask & QXmppPromise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #502. Co-authored-by: Jonah BrĂ¼chert --- src/omemo/QXmppOmemoManager.cpp | 164 ++++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 83 deletions(-) (limited to 'src/omemo/QXmppOmemoManager.cpp') 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 Manager::load() +QXmppTask Manager::load() { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 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 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 Manager::load() /// /// \return whether everything is set up successfully /// -QFuture Manager::setUp() +QXmppTask Manager::setUp() { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 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 Manager::setUp() /// /// \return the own key /// -QFuture Manager::ownKey() +QXmppTask Manager::ownKey() { return d->trustManager->ownKey(ns_omemo_2); } @@ -457,7 +459,7 @@ QFuture Manager::ownKey() /// /// \return the key owner JIDs mapped to their keys with specific trust levels /// -QFuture>> Manager::keys(QXmpp::TrustLevels trustLevels) +QXmppTask>> Manager::keys(QXmpp::TrustLevels trustLevels) { return d->trustManager->keys(ns_omemo_2, trustLevels); } @@ -477,7 +479,7 @@ QFuture>> Manager::keys /// /// \return the key IDs mapped to their trust levels for specific key owners /// -QFuture>> Manager::keys(const QList &jids, QXmpp::TrustLevels trustLevels) +QXmppTask>> Manager::keys(const QList &jids, QXmpp::TrustLevels trustLevels) { return d->trustManager->keys(ns_omemo_2, jids, trustLevels); } @@ -496,7 +498,7 @@ QFuture>> Manager::keys(cons /// /// \return whether the action was successful /// -QFuture Manager::changeDeviceLabel(const QString &deviceLabel) +QXmppTask 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> Manager::requestDeviceLists(const QList &jids) +QXmppTask> Manager::requestDeviceLists(const QList &jids) { if (const auto jidsCount = jids.size()) { - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface> interface; + QXmppPromise> interface; QVector devicesResults; }; @@ -581,21 +584,20 @@ QFuture> 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()); + return makeReadyTask(QVector()); } /// @@ -612,13 +614,14 @@ QFuture> Manager::requestDeviceLists(const QList /// /// \return the results of the subscription for each JID /// -QFuture> Manager::subscribeToDeviceLists(const QList &jids) +QXmppTask> Manager::subscribeToDeviceLists(const QList &jids) { if (const auto jidsCount = jids.size()) { - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface> interface; + QXmppPromise> interface; QVector devicesResults; }; @@ -627,21 +630,20 @@ QFuture> 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()); + return makeReadyTask(QVector()); } /// @@ -653,7 +655,7 @@ QFuture> Manager::subscribeToDeviceLists(const Q /// /// \return the results of the unsubscription for each JID /// -QFuture> Manager::unsubscribeFromDeviceLists() +QXmppTask> Manager::unsubscribeFromDeviceLists() { return d->unsubscribeFromDeviceLists(d->jidsOfManuallySubscribedDevices); } @@ -684,7 +686,7 @@ QXmppOmemoOwnDevice Manager::ownDevice() /// /// /\return all devices except the own device /// -QFuture> Manager::devices() +QXmppTask> Manager::devices() { return devices(d->devices.keys()); } @@ -702,12 +704,12 @@ QFuture> Manager::devices() /// /// \return all devices of the passed JIDs /// -QFuture> Manager::devices(const QList &jids) +QXmppTask> Manager::devices(const QList &jids) { - QFutureInterface> interface(QFutureInterfaceBase::Started); + QXmppPromise> interface; auto future = keys(jids); - await(future, this, [=](QHash> keys) mutable { + future.then(this, [=](QHash> keys) mutable { QVector devices; for (const auto &jid : jids) { @@ -730,10 +732,10 @@ QFuture> Manager::devices(const QList &jids) } } - reportFinishedResult(interface, devices); + interface.finish(std::move(devices)); }); - return interface.future(); + return interface.task(); } /// @@ -749,32 +751,32 @@ QFuture> Manager::devices(const QList &jids) /// /// \return the result of the contact device removals /// -QFuture Manager::removeContactDevices(const QString &jid) +QXmppTask Manager::removeContactDevices(const QString &jid) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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(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 Manager::buildMissingSessions(const QList &jids) +QXmppTask Manager::buildMissingSessions(const QList &jids) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise interface; auto &devices = d->devices; auto devicesCount = 0; @@ -883,21 +885,18 @@ QFuture Manager::buildMissingSessions(const QList &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 Manager::buildMissingSessions(const QList &jids) /// Existing sessions are reset, which might lead to undecryptable incoming /// stanzas until everything is set up again. /// -QFuture Manager::resetOwnDevice() +QXmppTask Manager::resetOwnDevice() { return d->resetOwnDevice(); } @@ -938,7 +937,7 @@ QFuture Manager::resetOwnDevice() /// Existing sessions are reset, which might lead to undecryptable incoming /// stanzas until everything is set up again. /// -QFuture Manager::resetAll() +QXmppTask Manager::resetAll() { return d->resetAll(); } @@ -948,7 +947,7 @@ QFuture Manager::resetAll() /// /// \param securityPolicy security policy being set /// -QFuture Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy) +QXmppTask Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy) { return d->trustManager->setSecurityPolicy(ns_omemo_2, securityPolicy); } @@ -958,7 +957,7 @@ QFuture Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPoli /// /// \return the used security policy /// -QFuture Manager::securityPolicy() +QXmppTask Manager::securityPolicy() { return d->trustManager->securityPolicy(ns_omemo_2); } @@ -971,7 +970,7 @@ QFuture Manager::securityPolicy() /// \param keyIds key owners' bare JIDs mapped to the IDs of their keys /// \param trustLevel trust level being set /// -QFuture Manager::setTrustLevel(const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel) +QXmppTask Manager::setTrustLevel(const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel) { return d->trustManager->setTrustLevel(ns_omemo_2, keyIds, trustLevel); } @@ -986,13 +985,13 @@ QFuture Manager::setTrustLevel(const QMultiHash &keyI /// /// \return the key's trust level /// -QFuture Manager::trustLevel(const QString &keyOwnerJid, const QByteArray &keyId) +QXmppTask Manager::trustLevel(const QString &keyOwnerJid, const QByteArray &keyId) { return d->trustManager->trustLevel(ns_omemo_2, keyOwnerJid, keyId); } /// \cond -QFuture Manager::encryptMessage(QXmppMessage &&message, const std::optional ¶ms) +QXmppTask Manager::encryptMessage(QXmppMessage &&message, const std::optional ¶ms) { QVector recipientJids; std::optional acceptedTrustLevels; @@ -1013,17 +1012,17 @@ QFuture Manager::encryptMessage(QXmppM return d->encryptMessageForRecipients(std::move(message), recipientJids, *acceptedTrustLevels); } -QFuture QXmppOmemoManager::decryptMessage(QXmppMessage &&message) +QXmppTask QXmppOmemoManager::decryptMessage(QXmppMessage &&message) { if (!d->isStarted) { - return makeReadyFuture(QXmppError { + return makeReadyTask(QXmppError { QStringLiteral("OMEMO manager must be started before decrypting"), SendError::EncryptionError }); } auto omemoElement = message.omemoElement(); if (!omemoElement) { - return makeReadyFuture(NotEncrypted()); + return makeReadyTask(NotEncrypted()); } return chain(d->decryptMessage(message), this, [](std::optional message) -> MessageDecryptResult { @@ -1037,15 +1036,14 @@ QFuture QXmppOmemoManager::decryptMess }); } -QFuture Manager::encryptIq(QXmppIq &&iq, const std::optional ¶ms) +QXmppTask Manager::encryptIq(QXmppIq &&iq, const std::optional ¶ms) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 acceptedTrustLevels; @@ -1058,12 +1056,12 @@ QFuture Manager::encryptIq(QXmppIq &&iq, co } auto future = d->encryptStanza(iq, { QXmppUtils::jidToBareJid(iq.to()) }, *acceptedTrustLevels); - await(future, this, [=, iq = std::move(iq)](std::optional omemoElement) mutable { + future.then(this, [=, iq = std::move(iq)](std::optional 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 Manager::encryptIq(QXmppIq &&iq, co QXmlStreamWriter writer(&serializedEncryptedIq); omemoIq.toXml(&writer); - reportFinishedResult(interface, { serializedEncryptedIq }); + interface.finish(serializedEncryptedIq); } }); } - return interface.future(); + return interface.task(); } -QFuture Manager::decryptIq(const QDomElement &element) +QXmppTask Manager::decryptIq(const QDomElement &element) { if (!d->isStarted) { // TODO: Add decryption queue to avoid this error - return makeReadyFuture(QXmppError { + return makeReadyTask(QXmppError { QStringLiteral("OMEMO manager must be started before decrypting"), SendError::EncryptionError }); } @@ -1107,7 +1105,7 @@ QFuture Manager::decryptIq(const QDomElemen }); } - return makeReadyFuture(NotEncrypted()); + return makeReadyTask(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 optionalDecryptedMessage) mutable { + future.then(this, [=](std::optional optionalDecryptedMessage) mutable { if (optionalDecryptedMessage) { injectMessage(std::move(*optionalDecryptedMessage)); } -- cgit v1.2.3