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/CMakeLists.txt | 3 + src/base/QXmppFutureUtils_p.h | 56 +++-- src/base/QXmppPacket.cpp | 21 +- src/base/QXmppPacket_p.h | 12 +- src/base/QXmppPromise.h | 103 +++++++++ src/base/QXmppStream.cpp | 38 ++-- src/base/QXmppStream.h | 12 +- src/base/QXmppStreamManagement.cpp | 13 +- src/base/QXmppTask.cpp | 85 +++++++ src/base/QXmppTask.h | 230 +++++++++++++++++++ src/client/QXmppAtmManager.cpp | 101 ++++---- src/client/QXmppAtmManager.h | 18 +- src/client/QXmppAtmTrustMemoryStorage.cpp | 24 +- src/client/QXmppAtmTrustMemoryStorage.h | 12 +- src/client/QXmppAtmTrustStorage.h | 12 +- src/client/QXmppCarbonManagerV2.cpp | 2 +- src/client/QXmppClient.cpp | 75 +++--- src/client/QXmppClient.h | 14 +- src/client/QXmppDiscoveryManager.cpp | 4 +- src/client/QXmppDiscoveryManager.h | 6 +- src/client/QXmppE2eeExtension.h | 10 +- src/client/QXmppEntityTimeManager.cpp | 2 +- src/client/QXmppEntityTimeManager.h | 4 +- src/client/QXmppHttpUploadManager.cpp | 14 +- src/client/QXmppIqHandling.h | 6 +- src/client/QXmppMamManager.cpp | 28 +-- src/client/QXmppMamManager.h | 14 +- src/client/QXmppMessageReceiptManager.cpp | 1 + src/client/QXmppOutgoingClient.cpp | 3 +- src/client/QXmppOutgoingClient.h | 2 +- src/client/QXmppPep_p.h | 2 +- src/client/QXmppPubSubManager.cpp | 59 +++-- src/client/QXmppPubSubManager.h | 169 +++++++------- src/client/QXmppRosterManager.cpp | 16 +- src/client/QXmppRosterManager.h | 12 +- src/client/QXmppTrustManager.cpp | 59 ++--- src/client/QXmppTrustManager.h | 37 +-- src/client/QXmppTrustMemoryStorage.cpp | 72 +++--- src/client/QXmppTrustMemoryStorage.h | 42 ++-- src/client/QXmppTrustStorage.h | 37 +-- src/client/QXmppUploadRequestManager.cpp | 8 +- src/client/QXmppUploadRequestManager.h | 20 +- src/client/QXmppUserLocationManager.cpp | 4 +- src/client/QXmppUserLocationManager.h | 6 +- src/client/QXmppUserTuneManager.cpp | 4 +- src/client/QXmppUserTuneManager.h | 6 +- src/omemo/QXmppOmemoManager.cpp | 164 +++++++------ src/omemo/QXmppOmemoManager.h | 47 ++-- src/omemo/QXmppOmemoManager_p.cpp | 367 +++++++++++++++--------------- src/omemo/QXmppOmemoManager_p.h | 77 +++---- src/omemo/QXmppOmemoMemoryStorage.cpp | 46 ++-- src/omemo/QXmppOmemoMemoryStorage.h | 21 +- src/omemo/QXmppOmemoStorage.h | 21 +- 53 files changed, 1325 insertions(+), 896 deletions(-) create mode 100644 src/base/QXmppPromise.h create mode 100644 src/base/QXmppTask.cpp create mode 100644 src/base/QXmppTask.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ac06abcc..2a542732 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,7 @@ set(INSTALL_HEADER_FILES base/QXmppOutOfBandUrl.h base/QXmppPingIq.h base/QXmppPresence.h + base/QXmppPromise.h base/QXmppPubSubAffiliation.h base/QXmppPubSubEvent.h base/QXmppPubSubIq_p.h @@ -71,6 +72,7 @@ set(INSTALL_HEADER_FILES base/QXmppStream.h base/QXmppStreamFeatures.h base/QXmppStun.h + base/QXmppTask.h base/QXmppThumbnail.h base/QXmppTrustMessageElement.h base/QXmppTrustMessageKeyOwner.h @@ -203,6 +205,7 @@ set(SOURCE_FILES base/QXmppStreamInitiationIq.cpp base/QXmppStreamManagement.cpp base/QXmppStun.cpp + base/QXmppTask.cpp base/QXmppThumbnail.cpp base/QXmppTrustMessages.cpp base/QXmppTuneItem.cpp diff --git a/src/base/QXmppFutureUtils_p.h b/src/base/QXmppFutureUtils_p.h index 311e7019..5e6b5ca8 100644 --- a/src/base/QXmppFutureUtils_p.h +++ b/src/base/QXmppFutureUtils_p.h @@ -16,6 +16,7 @@ // #include "QXmppIq.h" +#include "QXmppPromise.h" #include "QXmppSendResult.h" #include @@ -85,6 +86,21 @@ inline QFuture makeReadyFuture() } #endif +template +QXmppTask makeReadyTask(T &&value) +{ + QXmppPromise promise; + promise.finish(std::move(value)); + return promise.task(); +} + +inline QXmppTask makeReadyTask() +{ + QXmppPromise promise; + promise.finish(); + return promise.task(); +} + template void awaitLast(const QFuture &future, QObject *context, Handler handler) { @@ -123,18 +139,14 @@ void await(const QFuture &future, QObject *context, Handler handler) } template -auto chain(const QFuture &source, QObject *context, Converter task) -> QFuture +auto chain(QXmppTask &&source, QObject *context, Converter task) -> QXmppTask { - QFutureInterface resultInterface(QFutureInterfaceBase::Started); + QXmppPromise promise; - auto *watcher = new QFutureWatcher(context); - QObject::connect(watcher, &QFutureWatcherBase::finished, context, [=]() mutable { - resultInterface.reportResult(task(watcher->result())); - resultInterface.reportFinished(); - watcher->deleteLater(); + source.then(context, [=](Input &&input) mutable { + promise.finish(task(std::move(input))); }); - watcher->setFuture(source); - return resultInterface.future(); + return promise.task(); } template @@ -169,21 +181,21 @@ auto parseIq(Input &&sendResult) -> Result } template -auto chainIq(QFuture &&input, QObject *context, Converter convert) -> QFuture +auto chainIq(QXmppTask &&input, QObject *context, Converter convert) -> QXmppTask { using Result = decltype(convert({})); using IqType = std::decay_t>; - return chain(std::move(input), context, [convert { std::move(convert) }](Input &&input) -> Result { + return chain(std::move(input), context, [convert = std::move(convert)](Input &&input) -> Result { return parseIq(std::move(input), convert); }); } template -auto chainIq(QFuture &&input, QObject *context) -> QFuture +auto chainIq(QXmppTask &&input, QObject *context) -> QXmppTask { // IQ type is first std::variant parameter using IqType = std::decay_t(Result {}))>; - return chain(std::move(input), context, [](Input &&sendResult) { + return chain(std::move(input), context, [](Input &&sendResult) mutable { return parseIq(sendResult); }); } @@ -210,6 +222,24 @@ auto mapSuccess(std::variant var, Function lambda) std::move(var)); } +template +static auto taskFromFuture(QFuture &&future) -> QXmppTask +{ + QXmppPromise promise; + auto *watcher = new QFutureWatcher(); + QObject::connect(watcher, &QFutureWatcher::finished, [promise = std::move(promise), watcher]() mutable { + if constexpr (std::is_void_v) { + promise.finish(); + } else { + promise.finish(watcher->result()); + } + watcher->deleteLater(); + }); + watcher->setFuture(future); + + return promise.task(); +} + } // namespace QXmpp::Private #endif // QXMPPFUTUREUTILS_P_H diff --git a/src/base/QXmppPacket.cpp b/src/base/QXmppPacket.cpp index d61af9da..a0921973 100644 --- a/src/base/QXmppPacket.cpp +++ b/src/base/QXmppPacket.cpp @@ -5,7 +5,6 @@ #include "QXmppNonza.h" #include "QXmppPacket_p.h" -#include #include inline QByteArray serialize(const QXmppNonza &nonza) @@ -17,17 +16,16 @@ inline QByteArray serialize(const QXmppNonza &nonza) } /// \cond -QXmppPacket::QXmppPacket(const QXmppNonza &nonza, QFutureInterface interface) +QXmppPacket::QXmppPacket(const QXmppNonza &nonza, QXmppPromise interface) : QXmppPacket(serialize(nonza), nonza.isXmppStanza(), std::move(interface)) { } -QXmppPacket::QXmppPacket(const QByteArray &data, bool isXmppStanza, QFutureInterface interface) - : m_interface(std::move(interface)), +QXmppPacket::QXmppPacket(const QByteArray &data, bool isXmppStanza, QXmppPromise interface) + : m_promise(std::move(interface)), m_data(data), m_isXmppStanza(isXmppStanza) { - m_interface.reportStarted(); } QByteArray QXmppPacket::data() const @@ -40,18 +38,13 @@ bool QXmppPacket::isXmppStanza() const return m_isXmppStanza; } -QFuture QXmppPacket::future() +QXmppTask QXmppPacket::task() { - return m_interface.future(); + return m_promise.task(); } -void QXmppPacket::reportFinished() +void QXmppPacket::reportFinished(QXmpp::SendResult &&result) { - m_interface.reportFinished(); -} - -void QXmppPacket::reportResult(const QXmpp::SendResult &result) -{ - m_interface.reportResult(result); + m_promise.finish(std::move(result)); } /// \endcond diff --git a/src/base/QXmppPacket_p.h b/src/base/QXmppPacket_p.h index a7170a17..f5d95f85 100644 --- a/src/base/QXmppPacket_p.h +++ b/src/base/QXmppPacket_p.h @@ -6,6 +6,7 @@ #define QXMPPPACKET_H #include "QXmppGlobal.h" +#include "QXmppPromise.h" #include "QXmppSendResult.h" #include @@ -17,19 +18,18 @@ class QXmppNonza; class QXmppPacket { public: - QXmppPacket(const QXmppNonza &nonza, QFutureInterface = {}); - QXmppPacket(const QByteArray &data, bool isXmppStanza, QFutureInterface = {}); + QXmppPacket(const QXmppNonza &nonza, QXmppPromise = {}); + QXmppPacket(const QByteArray &data, bool isXmppStanza, QXmppPromise = {}); QByteArray data() const; bool isXmppStanza() const; - QFuture future(); + QXmppTask task(); - void reportFinished(); - void reportResult(const QXmpp::SendResult &); + void reportFinished(QXmpp::SendResult &&); private: - QFutureInterface m_interface; + QXmppPromise m_promise; QByteArray m_data; bool m_isXmppStanza; }; diff --git a/src/base/QXmppPromise.h b/src/base/QXmppPromise.h new file mode 100644 index 00000000..09bc5bcb --- /dev/null +++ b/src/base/QXmppPromise.h @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2022 Linus Jahn +// SPDX-FileCopyrightText: 2022 Jonah Brüchert +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef QXMPPPROMISE_H +#define QXMPPPROMISE_H + +#include "QXmppTask.h" + +/// +/// \brief Create and update QXmppTask objects to communicate results of asynchronous operations. +/// +/// Unlike QFuture, this is not thread-safe. This avoids the need to do mutex locking at every +/// access though. +/// +/// \ingroup Core classes +/// +/// \since QXmpp 1.5 +/// +template +class QXmppPromise +{ +public: + template> * = nullptr> + QXmppPromise() + : d(QXmpp::Private::TaskPrivate(nullptr)) + { + } + + template> * = nullptr> + QXmppPromise() + : d(QXmpp::Private::TaskPrivate([](void *r) { delete static_cast(r); })) + { + } + + /// + /// Report that the asynchronous operation has finished, and call the connected handler of the + /// QXmppTask belonging to this promise. + /// + /// \param value The result of the asynchronous computation + /// +#ifdef QXMPP_DOC + void reportFinished(T &&value) +#else + template && std::is_base_of_v> * = nullptr> + void finish(U &&value) +#endif + { + Q_ASSERT(!d.isFinished()); + d.setFinished(true); + if (d.continuation()) { + if (d.isContextAlive()) { + d.invokeContinuation(&value); + } + } else { + d.setResult(new U(std::move(value))); + } + } + + /// \cond + template && std::is_constructible_v && !std::is_base_of_v> * = nullptr> + void finish(U &&value) + { + Q_ASSERT(!d.isFinished()); + d.setFinished(true); + if (d.continuation()) { + if (d.isContextAlive()) { + T convertedValue { std::move(value) }; + d.invokeContinuation(&convertedValue); + } + } else { + d.setResult(new T(std::move(value))); + } + } + + template> * = nullptr> + void finish() + { + Q_ASSERT(!d.isFinished()); + d.setFinished(true); + if (d.continuation()) { + if (d.isContextAlive()) { + d.invokeContinuation(nullptr); + } + } + } + /// \endcond + + /// + /// Obtain a handle to this promise that allows to obtain the value that will be produced + /// asynchronously. + /// + QXmppTask task() + { + return QXmppTask(d); + } + +private: + QXmpp::Private::TaskPrivate d; +}; + +#endif // QXMPPPROMISE_H diff --git a/src/base/QXmppStream.cpp b/src/base/QXmppStream.cpp index cbe40b8a..d1a5ccd2 100644 --- a/src/base/QXmppStream.cpp +++ b/src/base/QXmppStream.cpp @@ -35,7 +35,7 @@ static bool randomSeeded = false; struct IqState { - QFutureInterface interface; + QXmppPromise interface; QString jid; }; @@ -172,7 +172,7 @@ bool QXmppStream::sendPacket(const QXmppNonza &nonza) /// /// \since QXmpp 1.5 /// -QFuture QXmppStream::send(QXmppNonza &&nonza) +QXmppTask QXmppStream::send(QXmppNonza &&nonza) { bool success; return send(QXmppPacket(nonza), success); @@ -183,13 +183,13 @@ QFuture QXmppStream::send(QXmppNonza &&nonza) /// /// \since QXmpp 1.5 /// -QFuture QXmppStream::send(QXmppPacket &&packet) +QXmppTask QXmppStream::send(QXmppPacket &&packet) { bool success; return send(std::move(packet), success); } -QFuture QXmppStream::send(QXmppPacket &&packet, bool &writtenToSocket) +QXmppTask QXmppStream::send(QXmppPacket &&packet, bool &writtenToSocket) { // the writtenToSocket parameter is just for backwards compat (see // QXmppStream::sendPacket()) @@ -198,7 +198,7 @@ QFuture QXmppStream::send(QXmppPacket &&packet, bool &written // handle stream management d->streamManager.handlePacketSent(packet, writtenToSocket); - return packet.future(); + return packet.task(); } /// @@ -208,7 +208,7 @@ QFuture QXmppStream::send(QXmppPacket &&packet, bool &written /// /// \since QXmpp 1.5 /// -QFuture QXmppStream::sendIq(QXmppIq &&iq) +QXmppTask QXmppStream::sendIq(QXmppIq &&iq) { using namespace QXmpp; @@ -233,18 +233,18 @@ QFuture QXmppStream::sendIq(QXmppIq &&iq) /// /// \since QXmpp 1.5 /// -QFuture QXmppStream::sendIq(QXmppPacket &&packet, const QString &id, const QString &to) +QXmppTask QXmppStream::sendIq(QXmppPacket &&packet, const QString &id, const QString &to) { using namespace QXmpp; if (id.isEmpty() || d->runningIqs.contains(id)) { - return makeReadyFuture(QXmppError { + return makeReadyTask(QXmppError { QStringLiteral("Invalid IQ id: empty or in use."), SendError::Disconnected }); } if (to.isEmpty()) { - return makeReadyFuture(QXmppError { + return makeReadyTask(QXmppError { QStringLiteral("The 'to' address must be set so the stream can match the response."), SendError::Disconnected }); } @@ -253,15 +253,13 @@ QFuture QXmppStream::sendIq(QXmppPacket &&packet, const Q if (sendFuture.isFinished()) { if (std::holds_alternative(sendFuture.result())) { // early exit (saves QFutureWatcher) - return makeReadyFuture(std::get(sendFuture.result())); + return makeReadyTask(std::get(sendFuture.result())); } } else { - awaitLast(sendFuture, this, [this, id](SendResult result) { + sendFuture.then(this, [this, id](SendResult result) { if (std::holds_alternative(result)) { if (auto itr = d->runningIqs.find(id); itr != d->runningIqs.end()) { - itr.value().interface.reportResult(std::get(result)); - itr.value().interface.reportFinished(); - + itr.value().interface.finish(std::get(result)); d->runningIqs.erase(itr); } } @@ -269,12 +267,12 @@ QFuture QXmppStream::sendIq(QXmppPacket &&packet, const Q } IqState state { - QFutureInterface(QFutureInterfaceBase::Started), + {}, to, }; - auto future = state.interface.future(); + auto task = state.interface.task(); d->runningIqs.insert(id, std::move(state)); - return future; + return task; } /// @@ -285,10 +283,9 @@ QFuture QXmppStream::sendIq(QXmppPacket &&packet, const Q void QXmppStream::cancelOngoingIqs() { for (auto &state : d->runningIqs) { - state.interface.reportResult(QXmppError { + state.interface.finish(QXmppError { QStringLiteral("IQ has been cancelled."), QXmpp::SendError::Disconnected }); - state.interface.reportFinished(); } d->runningIqs.clear(); } @@ -494,8 +491,7 @@ bool QXmppStream::handleIqResponse(const QDomElement &stanza) return false; } - itr.value().interface.reportResult(stanza); - itr.value().interface.reportFinished(); + itr.value().interface.finish(stanza); d->runningIqs.erase(itr); return true; diff --git a/src/base/QXmppStream.h b/src/base/QXmppStream.h index 464d576d..55dc7967 100644 --- a/src/base/QXmppStream.h +++ b/src/base/QXmppStream.h @@ -17,6 +17,8 @@ class QDomElement; template +class QXmppTask; +template class QFuture; template class QFutureInterface; @@ -41,12 +43,12 @@ public: virtual bool isConnected() const; bool sendPacket(const QXmppNonza &); - QFuture send(QXmppNonza &&); - QFuture send(QXmppPacket &&); + QXmppTask send(QXmppNonza &&); + QXmppTask send(QXmppPacket &&); using IqResult = std::variant; - QFuture sendIq(QXmppIq &&); - QFuture sendIq(QXmppPacket &&, const QString &id, const QString &to); + QXmppTask sendIq(QXmppIq &&); + QXmppTask sendIq(QXmppPacket &&, const QString &id, const QString &to); void cancelOngoingIqs(); bool hasIqId(const QString &id) const; @@ -97,7 +99,7 @@ private: friend class tst_QXmppStream; friend class TestClient; - QFuture send(QXmppPacket &&, bool &); + QXmppTask send(QXmppPacket &&, bool &); void processData(const QString &data); bool handleIqResponse(const QDomElement &); diff --git a/src/base/QXmppStreamManagement.cpp b/src/base/QXmppStreamManagement.cpp index 853327f9..f3b183e1 100644 --- a/src/base/QXmppStreamManagement.cpp +++ b/src/base/QXmppStreamManagement.cpp @@ -353,13 +353,12 @@ void QXmppStreamManager::handlePacketSent(QXmppPacket &packet, bool sentData) sendAcknowledgementRequest(); } else { if (sentData) { - packet.reportResult(QXmpp::SendSuccess { false }); + packet.reportFinished(QXmpp::SendSuccess { false }); } else { - packet.reportResult(QXmppError { + packet.reportFinished(QXmppError { QStringLiteral("Couldn't write data to socket. No stream management enabled."), QXmpp::SendError::SocketWriteError }); } - packet.reportFinished(); } } @@ -418,8 +417,7 @@ void QXmppStreamManager::setAcknowledgedSequenceNumber(unsigned int sequenceNumb { for (auto it = m_unacknowledgedStanzas.begin(); it != m_unacknowledgedStanzas.end();) { if (it.key() <= sequenceNumber) { - it->reportResult(QXmpp::SendSuccess { true }); - it->reportFinished(); + it->reportFinished(QXmpp::SendSuccess { true }); it = m_unacknowledgedStanzas.erase(it); } else { break; @@ -472,8 +470,9 @@ void QXmppStreamManager::sendAcknowledgementRequest() void QXmppStreamManager::resetCache() { for (auto &packet : m_unacknowledgedStanzas) { - packet.reportResult(QXmppError { QStringLiteral("Disconnected"), QXmpp::SendError::Disconnected }); - packet.reportFinished(); + packet.reportFinished(QXmppError { + QStringLiteral("Disconnected"), + QXmpp::SendError::Disconnected }); } m_unacknowledgedStanzas.clear(); diff --git a/src/base/QXmppTask.cpp b/src/base/QXmppTask.cpp new file mode 100644 index 00000000..c17a6e4f --- /dev/null +++ b/src/base/QXmppTask.cpp @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: 2023 Linus Jahn +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "QXmppTask.h" + +#include + +namespace QXmpp::Private { + +struct TaskData +{ + QPointer context; + std::function continuation; + void *result = nullptr; + void (*freeResult)(void *); + bool finished = false; + + ~TaskData() + { + if (freeResult) { + freeResult(result); + } + } +}; + +} // namespace QXmpp::Private + +QXmpp::Private::TaskPrivate::TaskPrivate(void (*freeResult)(void *)) + : d(std::make_shared()) +{ + d->freeResult = freeResult; +} + +QXmpp::Private::TaskPrivate::~TaskPrivate() +{ +} + +bool QXmpp::Private::TaskPrivate::isFinished() const +{ + return d->finished; +} + +void QXmpp::Private::TaskPrivate::setFinished(bool finished) +{ + d->finished = finished; +} + +bool QXmpp::Private::TaskPrivate::isContextAlive() +{ + return !d->context.isNull(); +} + +void QXmpp::Private::TaskPrivate::setContext(QObject *obj) +{ + d->context = obj; +} + +void *QXmpp::Private::TaskPrivate::result() const +{ + return d->result; +} + +void QXmpp::Private::TaskPrivate::setResult(void *result) +{ + if (d->freeResult) { + d->freeResult(d->result); + } + d->result = result; +} + +const std::function QXmpp::Private::TaskPrivate::continuation() const +{ + return d->continuation; +} + +void QXmpp::Private::TaskPrivate::setContinuation(std::function &&continuation) +{ + d->continuation = continuation; +} + +void QXmpp::Private::TaskPrivate::invokeContinuation(void *result) +{ + d->continuation(*this, result); +} diff --git a/src/base/QXmppTask.h b/src/base/QXmppTask.h new file mode 100644 index 00000000..c11557ac --- /dev/null +++ b/src/base/QXmppTask.h @@ -0,0 +1,230 @@ +// SPDX-FileCopyrightText: 2022 Linus Jahn +// SPDX-FileCopyrightText: 2022 Jonah Brüchert +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef QXMPPTASK_H +#define QXMPPTASK_H + +#include "qxmpp_export.h" + +#include +#include +#include + +#include +#include + +template +class QXmppPromise; + +namespace QXmpp::Private { + +struct TaskData; + +class QXMPP_EXPORT TaskPrivate +{ +public: + TaskPrivate(void (*freeResult)(void *)); + ~TaskPrivate(); + + bool isFinished() const; + void setFinished(bool); + bool isContextAlive(); + void setContext(QObject *); + void *result() const; + void setResult(void *); + void resetResult() { setResult(nullptr); } + const std::function continuation() const; + void setContinuation(std::function &&); + void invokeContinuation(void *result); + +private: + std::shared_ptr d; +}; + +} // namespace QXmpp::Private + +/// +/// Handle for an ongoing operation that finishes in the future. +/// +/// Tasks are generated by QXmppPromise and can be handled using QXmppTask::then(). +/// +/// It supports abstract types, i.e. you can create a QXmppTask and report MyIq +/// (derived from QXmppStanza) to it and when handling the result it is possible to cast the result +/// back to MyIq. +/// +/// Unlike QFuture, this is not thread-safe. This avoids the need to do mutex locking at every +/// access though. +/// +/// \ingroup Core classes +/// +/// \since QXmpp 1.5 +/// +template +class QXmppTask +{ +public: + ~QXmppTask() = default; + + /// + /// Registers a function that will be called with the result as parameter when the asynchronous + /// operation finishes. + /// + /// If the task is already finished when calling this (and still has a result), the function + /// will be called immediately. + /// + /// If another function was previously registered using .then(), the old function will be + /// replaced, and only the new one will be called. + /// + /// Example usage: + /// ``` + /// QXmppTask generateSomething(); + /// + /// void Manager::generate() + /// { + /// generateSomething().then(this, [](QString &&result) { + /// // runs as soon as the result is finished + /// qDebug() << "Generating finished:" << result; + /// }); + /// + /// // The generation could still be in progress here and the lambda might not + /// // have been executed yet. + /// } + /// + /// // Manager is derived from QObject. + /// ``` + /// + /// \param context QObject used for unregistering the handler function when the object is + /// deleted. This way your lambda will never be executed after your object has been deleted. + /// \param continuation A function accepting a result in the form of `T &&`. + /// +#ifndef QXMPP_DOC + template +#endif + void then(QObject *context, Continuation continuation) + { + static_assert( + std::is_void_v && std::is_invocable_v || + !std::is_void_v /* && invocable with T && causes forming ref to void error */, + "Function needs to be invocable with T && or without params for T=void."); + using namespace QXmpp::Private; + + if (d.isFinished()) { + if constexpr (std::is_void_v) { + continuation(); + } else { + // when calling then() after finished value could be empty + if (hasResult()) { + continuation(std::move(*reinterpret_cast(d.result()))); + d.resetResult(); + } + } + } else { + d.setContext(context); + d.setContinuation([f = std::forward(continuation)](TaskPrivate &d, void *result) mutable { + if (d.isContextAlive()) { + if constexpr (std::is_void_v) { + f(); + } else { + f(std::move(*reinterpret_cast(result))); + } + } + + // clear continuation to avoid "deadlocks" in case the user captured this QXmppTask + d.setContinuation({}); + }); + } + } + + /// + /// Whether the asynchronous operation is already finished. + /// + /// This does not mean that the result is still stored, it might have been taken using + /// takeResult() or handled using then(). + /// + [[nodiscard]] bool isFinished() const { return d.isFinished(); } + + /// + /// Returns whether the task is finished and the value has not been taken yet. + /// +#ifndef QXMPP_DOC + template)> * = nullptr> +#endif + [[nodiscard]] bool hasResult() const + { + return d.result() != nullptr; + } + + /// + /// The result of the operation. + /// + /// \warning This can only be used once the operation is finished. + /// +#ifdef QXMPP_DOC + [[nodiscard]] const T &result() const +#else + template)> * = nullptr> + [[nodiscard]] const U &result() const +#endif + { + Q_ASSERT(isFinished()); + Q_ASSERT(hasResult()); + return *reinterpret_cast(d.result()); + } + + /// + /// Moves the result of the operation out of the task. + /// + /// Since this returns by value, you will not be able to cast the result to derived types. Use + /// result() for read-only access or register a handler function using then(). + /// + /// \warning This can only be used once the operation is finished. + /// +#ifdef QXMPP_DOC + [[nodiscard]] T takeResult() +#else + template)> * = nullptr> + [[nodiscard]] U takeResult() +#endif + { + Q_ASSERT(isFinished()); + Q_ASSERT(hasResult()); + U result = std::move(*reinterpret_cast(d.result())); + d.resetResult(); + return result; + } + + /// + /// Converts the Task into a QFuture. Afterwards the QXmppTask object is invalid. + /// + QFuture toFuture(QObject *context) + { + QFutureInterface interface; + + if constexpr (std::is_same_v) { + then(context, [interface]() mutable { + interface.reportFinished(); + }); + } else { + then(context, [interface](T &&val) mutable { + interface.reportResult(val); + interface.reportFinished(); + }); + } + + return interface.future(); + } + +private: + friend class QXmppPromise; + + explicit QXmppTask(QXmpp::Private::TaskPrivate data) + : d(std::move(data)) + { + } + + QXmpp::Private::TaskPrivate d; +}; + +#endif // QXMPPTASK_H diff --git a/src/client/QXmppAtmManager.cpp b/src/client/QXmppAtmManager.cpp index 0f97452a..e6df2679 100644 --- a/src/client/QXmppAtmManager.cpp +++ b/src/client/QXmppAtmManager.cpp @@ -77,12 +77,12 @@ QXmppAtmManager::QXmppAtmManager(QXmppAtmTrustStorage *trustStorage) /// \param keyIdsForAuthentication IDs of the keys being authenticated /// \param keyIdsForDistrusting IDs of the keys being distrusted /// -QFuture QXmppAtmManager::makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting) +QXmppTask QXmppAtmManager::makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise promise; auto future = keys(encryption, TrustLevel::Authenticated | TrustLevel::ManuallyDistrusted); - await(future, this, [=](QHash> keys) mutable { + future.then(this, [=](QHash> keys) mutable { const auto authenticatedKeys = keys.value(TrustLevel::Authenticated); const auto manuallyDistrustedKeys = keys.value(TrustLevel::ManuallyDistrusted); const auto ownJid = client()->configuration().jidBare(); @@ -110,7 +110,7 @@ QFuture QXmppAtmManager::makeTrustDecisions(const QString &encryption, con if (modifiedAuthenticatedKeys.isEmpty() && modifiedManuallyDistrustedKeys.isEmpty()) { // Skip further processing if there are no changes. - interface.reportFinished(); + promise.finish(); } else { keyOwner.setTrustedKeys(modifiedAuthenticatedKeys); keyOwner.setDistrustedKeys(modifiedManuallyDistrustedKeys); @@ -170,7 +170,7 @@ QFuture QXmppAtmManager::makeTrustDecisions(const QString &encryption, con } auto future = makeTrustDecisions(encryption, keysBeingAuthenticated, keysBeingDistrusted); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { // Send a trust message for all authenticated or distrusted // keys to the own endpoints whose keys have been // authenticated. @@ -212,7 +212,7 @@ QFuture QXmppAtmManager::makeTrustDecisions(const QString &encryption, con } } - interface.reportFinished(); + promise.finish(); }); } else { // Send a trust message for the keys of the contact's endpoints @@ -223,7 +223,7 @@ QFuture QXmppAtmManager::makeTrustDecisions(const QString &encryption, con } auto future = makeTrustDecisions(encryption, keysBeingAuthenticated, keysBeingDistrusted); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { // Send a trust message for own authenticated or distrusted // keys to the contact's endpoints whose keys have been // authenticated. @@ -233,13 +233,13 @@ QFuture QXmppAtmManager::makeTrustDecisions(const QString &encryption, con sendTrustMessage(encryption, { ownKeyOwner }, keyOwnerJid); } - interface.reportFinished(); + promise.finish(); }); } } }); - return interface.future(); + return promise.task(); } /// \cond @@ -264,19 +264,20 @@ void QXmppAtmManager::handleMessageReceived(const QXmppMessage &message) /// \param keyIdsForDistrusting key owners' bare JIDs mapped to the IDs of their /// keys being distrusted /// -QFuture QXmppAtmManager::makeTrustDecisions(const QString &encryption, const QMultiHash &keyIdsForAuthentication, const QMultiHash &keyIdsForDistrusting) +QXmppTask QXmppAtmManager::makeTrustDecisions(const QString &encryption, const QMultiHash &keyIdsForAuthentication, const QMultiHash &keyIdsForDistrusting) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise promise; auto future = authenticate(encryption, keyIdsForAuthentication); - await(future, this, [=]() mutable { + + future.then(this, [=]() mutable { auto future = distrust(encryption, keyIdsForDistrusting); - await(future, this, [=]() mutable { - interface.reportFinished(); + future.then(this, [=]() mutable { + promise.finish(); }); }); - return interface.future(); + return promise.task(); } /// @@ -285,9 +286,9 @@ QFuture QXmppAtmManager::makeTrustDecisions(const QString &encryption, con /// /// \param message message that can contain a trust message element /// -QFuture QXmppAtmManager::handleMessage(const QXmppMessage &message) +QXmppTask QXmppAtmManager::handleMessage(const QXmppMessage &message) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise promise; if (const auto trustMessageElement = message.trustMessageElement(); trustMessageElement && @@ -299,7 +300,7 @@ QFuture QXmppAtmManager::handleMessage(const QXmppMessage &message) const auto encryption = trustMessageElement->encryption(); auto future = trustLevel(encryption, senderJid, senderKey); - await(future, this, [=](const auto &&senderKeyTrustLevel) mutable { + future.then(this, [=](const auto &&senderKeyTrustLevel) mutable { const auto isSenderKeyAuthenticated = senderKeyTrustLevel == TrustLevel::Authenticated; // key owner JIDs mapped to key IDs @@ -345,10 +346,10 @@ QFuture QXmppAtmManager::handleMessage(const QXmppMessage &message) } auto future = trustStorage()->addKeysForPostponedTrustDecisions(encryption, senderKey, keyOwnersForPostponedTrustDecisions); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = makeTrustDecisions(encryption, keysBeingAuthenticated, keysBeingDistrusted); - await(future, this, [=]() mutable { - interface.reportFinished(); + future.then(this, [=]() mutable { + promise.finish(); }); }); }); @@ -357,10 +358,10 @@ QFuture QXmppAtmManager::handleMessage(const QXmppMessage &message) // 1. The message does not contain a trust message element. // 2. The trust message is sent by this endpoint and reflected via // Message Carbons. - interface.reportFinished(); + promise.finish(); } - return interface.future(); + return promise.task(); } /// @@ -369,36 +370,36 @@ QFuture QXmppAtmManager::handleMessage(const QXmppMessage &message) /// \param encryption encryption protocol namespace /// \param keyIds key owners' bare JIDs mapped to the IDs of their keys /// -QFuture QXmppAtmManager::authenticate(const QString &encryption, const QMultiHash &keyIds) +QXmppTask QXmppAtmManager::authenticate(const QString &encryption, const QMultiHash &keyIds) { if (keyIds.isEmpty()) { - return makeReadyFuture(); + return makeReadyTask(); } - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise promise; auto future = setTrustLevel(encryption, keyIds, TrustLevel::Authenticated); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = securityPolicy(encryption); - await(future, this, [=](auto securityPolicy) mutable { + future.then(this, [=](auto securityPolicy) mutable { if (securityPolicy == Toakafa) { auto future = distrustAutomaticallyTrustedKeys(encryption, keyIds.uniqueKeys()); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = makePostponedTrustDecisions(encryption, keyIds.values()); - await(future, this, [=]() mutable { - interface.reportFinished(); + future.then(this, [=]() mutable { + promise.finish(); }); }); } else { auto future = makePostponedTrustDecisions(encryption, keyIds.values()); - await(future, this, [=]() mutable { - interface.reportFinished(); + future.then(this, [=]() mutable { + promise.finish(); }); } }); }); - return interface.future(); + return promise.task(); } /// @@ -407,23 +408,23 @@ QFuture QXmppAtmManager::authenticate(const QString &encryption, const QMu /// \param encryption encryption protocol namespace /// \param keyIds key owners' bare JIDs mapped to the IDs of their keys /// -QFuture QXmppAtmManager::distrust(const QString &encryption, const QMultiHash &keyIds) +QXmppTask QXmppAtmManager::distrust(const QString &encryption, const QMultiHash &keyIds) { if (keyIds.isEmpty()) { - return makeReadyFuture(); + return makeReadyTask(); } - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise promise; auto future = setTrustLevel(encryption, keyIds, TrustLevel::ManuallyDistrusted); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = trustStorage()->removeKeysForPostponedTrustDecisions(encryption, keyIds.values()); - await(future, this, [=]() mutable { - interface.reportFinished(); + future.then(this, [=]() mutable { + promise.finish(); }); }); - return interface.future(); + return promise.task(); } /// @@ -433,7 +434,7 @@ QFuture QXmppAtmManager::distrust(const QString &encryption, const QMultiH /// \param encryption encryption protocol namespace /// \param keyOwnerJids bare JIDs of the key owners /// -QFuture QXmppAtmManager::distrustAutomaticallyTrustedKeys(const QString &encryption, const QList &keyOwnerJids) +QXmppTask QXmppAtmManager::distrustAutomaticallyTrustedKeys(const QString &encryption, const QList &keyOwnerJids) { return setTrustLevel(encryption, keyOwnerJids, TrustLevel::AutomaticallyTrusted, TrustLevel::AutomaticallyDistrusted); } @@ -448,26 +449,26 @@ QFuture QXmppAtmManager::distrustAutomaticallyTrustedKeys(const QString &e /// \param encryption encryption protocol namespace /// \param senderKeyIds IDs of the keys that were used by the senders /// -QFuture QXmppAtmManager::makePostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) +QXmppTask QXmppAtmManager::makePostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise promise; auto future = trustStorage()->keysForPostponedTrustDecisions(encryption, senderKeyIds); - await(future, this, [=](const QHash> &&keysForPostponedTrustDecisions) mutable { + future.then(this, [=](const QHash> &&keysForPostponedTrustDecisions) mutable { // JIDs of key owners mapped to the IDs of their keys const auto keysBeingAuthenticated = keysForPostponedTrustDecisions.value(true); const auto keysBeingDistrusted = keysForPostponedTrustDecisions.value(false); auto future = trustStorage()->removeKeysForPostponedTrustDecisions(encryption, keysBeingAuthenticated.values(), keysBeingDistrusted.values()); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = makeTrustDecisions(encryption, keysBeingAuthenticated, keysBeingDistrusted); - await(future, this, [=]() mutable { - interface.reportFinished(); + future.then(this, [=]() mutable { + promise.finish(); }); }); }); - return interface.future(); + return promise.task(); } /// @@ -477,7 +478,7 @@ QFuture QXmppAtmManager::makePostponedTrustDecisions(const QString &encryp /// \param keyOwners key owners containing the data for authentication or distrusting /// \param recipientJid JID of the recipient /// -QFuture QXmppAtmManager::sendTrustMessage(const QString &encryption, const QList &keyOwners, const QString &recipientJid) +QXmppTask QXmppAtmManager::sendTrustMessage(const QString &encryption, const QList &keyOwners, const QString &recipientJid) { QXmppTrustMessageElement trustMessageElement; trustMessageElement.setUsage(ns_atm); diff --git a/src/client/QXmppAtmManager.h b/src/client/QXmppAtmManager.h index 9a0ab446..f1630ba4 100644 --- a/src/client/QXmppAtmManager.h +++ b/src/client/QXmppAtmManager.h @@ -11,6 +11,8 @@ class QXmppMessage; class QXmppTrustMessageKeyOwner; +template +class QXmppTask; class QXMPP_EXPORT QXmppAtmManager : public QXmppTrustManager { @@ -18,7 +20,7 @@ class QXMPP_EXPORT QXmppAtmManager : public QXmppTrustManager public: QXmppAtmManager(QXmppAtmTrustStorage *trustStorage); - QFuture makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting = {}); + QXmppTask makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting = {}); protected: /// \cond @@ -28,16 +30,16 @@ private: Q_SLOT void handleMessageReceived(const QXmppMessage &message); /// \endcond - QFuture makeTrustDecisions(const QString &encryption, const QMultiHash &keyIdsForAuthentication, const QMultiHash &keyIdsForDistrusting); - QFuture handleMessage(const QXmppMessage &message); + QXmppTask makeTrustDecisions(const QString &encryption, const QMultiHash &keyIdsForAuthentication, const QMultiHash &keyIdsForDistrusting); + QXmppTask handleMessage(const QXmppMessage &message); - QFuture authenticate(const QString &encryption, const QMultiHash &keyIds); - QFuture distrust(const QString &encryption, const QMultiHash &keyIds); + QXmppTask authenticate(const QString &encryption, const QMultiHash &keyIds); + QXmppTask distrust(const QString &encryption, const QMultiHash &keyIds); - QFuture distrustAutomaticallyTrustedKeys(const QString &encryption, const QList &keyOwnerJids); - QFuture makePostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds); + QXmppTask distrustAutomaticallyTrustedKeys(const QString &encryption, const QList &keyOwnerJids); + QXmppTask makePostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds); - QFuture sendTrustMessage(const QString &encryption, const QList &keyOwners, const QString &recipientJid); + QXmppTask sendTrustMessage(const QString &encryption, const QList &keyOwners, const QString &recipientJid); /// \cond inline QXmppAtmTrustStorage *trustStorage() const diff --git a/src/client/QXmppAtmTrustMemoryStorage.cpp b/src/client/QXmppAtmTrustMemoryStorage.cpp index eb8fe4df..04c8c747 100644 --- a/src/client/QXmppAtmTrustMemoryStorage.cpp +++ b/src/client/QXmppAtmTrustMemoryStorage.cpp @@ -49,7 +49,7 @@ QXmppAtmTrustMemoryStorage::QXmppAtmTrustMemoryStorage() QXmppAtmTrustMemoryStorage::~QXmppAtmTrustMemoryStorage() = default; /// \cond -QFuture QXmppAtmTrustMemoryStorage::addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList &keyOwners) +QXmppTask QXmppAtmTrustMemoryStorage::addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList &keyOwners) { const auto addKeys = [&](const QXmppTrustMessageKeyOwner &keyOwner, bool trust, const QList &keyIds) { for (const auto &keyId : keyIds) { @@ -85,10 +85,10 @@ QFuture QXmppAtmTrustMemoryStorage::addKeysForPostponedTrustDecisions(cons addKeys(keyOwner, false, keyOwner.distrustedKeys()); } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting) +QXmppTask QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting) { for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption;) { @@ -101,10 +101,10 @@ QFuture QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(c } } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) +QXmppTask QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) { for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption;) { @@ -115,16 +115,16 @@ QFuture QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(c } } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption) +QXmppTask QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption) { d->keys.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture>> QXmppAtmTrustMemoryStorage::keysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) +QXmppTask>> QXmppAtmTrustMemoryStorage::keysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) { QHash> keys; @@ -135,13 +135,13 @@ QFuture>> QXmppAtmTrustMemoryStorage } } - return makeReadyFuture(std::move(keys)); + return makeReadyTask(std::move(keys)); } -QFuture QXmppAtmTrustMemoryStorage::resetAll(const QString &encryption) +QXmppTask QXmppAtmTrustMemoryStorage::resetAll(const QString &encryption) { QXmppTrustMemoryStorage::resetAll(encryption); d->keys.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } /// \endcond diff --git a/src/client/QXmppAtmTrustMemoryStorage.h b/src/client/QXmppAtmTrustMemoryStorage.h index 9d309e2a..cb1a481b 100644 --- a/src/client/QXmppAtmTrustMemoryStorage.h +++ b/src/client/QXmppAtmTrustMemoryStorage.h @@ -17,13 +17,13 @@ public: ~QXmppAtmTrustMemoryStorage(); /// \cond - QFuture addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList &keyOwners) override; - QFuture removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting) override; - QFuture removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) override; - QFuture removeKeysForPostponedTrustDecisions(const QString &encryption) override; - QFuture>> keysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds = {}) override; + QXmppTask addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList &keyOwners) override; + QXmppTask removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting) override; + QXmppTask removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) override; + QXmppTask removeKeysForPostponedTrustDecisions(const QString &encryption) override; + QXmppTask>> keysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds = {}) override; - QFuture resetAll(const QString &encryption) override; + QXmppTask resetAll(const QString &encryption) override; /// \endcond private: diff --git a/src/client/QXmppAtmTrustStorage.h b/src/client/QXmppAtmTrustStorage.h index e801c7df..f2618e94 100644 --- a/src/client/QXmppAtmTrustStorage.h +++ b/src/client/QXmppAtmTrustStorage.h @@ -7,6 +7,8 @@ #include "QXmppTrustStorage.h" +#include + class QXmppTrustMessageKeyOwner; class QXMPP_EXPORT QXmppAtmTrustStorage : virtual public QXmppTrustStorage @@ -14,11 +16,11 @@ class QXMPP_EXPORT QXmppAtmTrustStorage : virtual public QXmppTrustStorage public: virtual ~QXmppAtmTrustStorage() = default; - virtual QFuture addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList &keyOwners) = 0; - virtual QFuture removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting) = 0; - virtual QFuture removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) = 0; - virtual QFuture removeKeysForPostponedTrustDecisions(const QString &encryption) = 0; - virtual QFuture>> keysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds = {}) = 0; + virtual QXmppTask addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList &keyOwners) = 0; + virtual QXmppTask removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &keyIdsForAuthentication, const QList &keyIdsForDistrusting) = 0; + virtual QXmppTask removeKeysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds) = 0; + virtual QXmppTask removeKeysForPostponedTrustDecisions(const QString &encryption) = 0; + virtual QXmppTask>> keysForPostponedTrustDecisions(const QString &encryption, const QList &senderKeyIds = {}) = 0; }; #endif // QXMPPATMTRUSTSTORAGE_H diff --git a/src/client/QXmppCarbonManagerV2.cpp b/src/client/QXmppCarbonManagerV2.cpp index 1c3a6fcc..0f48370e 100644 --- a/src/client/QXmppCarbonManagerV2.cpp +++ b/src/client/QXmppCarbonManagerV2.cpp @@ -163,7 +163,7 @@ void QXmppCarbonManagerV2::enableCarbons() return; } - await(client()->sendIq(CarbonEnableIq()), this, [this](QXmppClient::IqResult domResult) { + client()->sendIq(CarbonEnableIq()).then(this, [this](QXmppClient::IqResult domResult) { if (auto err = parseIq(std::move(domResult))) { warning("Could not enable message carbons: " % err->description); } else { diff --git a/src/client/QXmppClient.cpp b/src/client/QXmppClient.cpp index c0d7ee42..891de237 100644 --- a/src/client/QXmppClient.cpp +++ b/src/client/QXmppClient.cpp @@ -18,14 +18,15 @@ #include "QXmppMessageHandler.h" #include "QXmppOutgoingClient.h" #include "QXmppPacket_p.h" +#include "QXmppPromise.h" #include "QXmppRosterManager.h" +#include "QXmppTask.h" #include "QXmppTlsManager_p.h" #include "QXmppUtils.h" #include "QXmppVCardManager.h" #include "QXmppVersionManager.h" #include -#include #include #include @@ -394,7 +395,7 @@ bool QXmppClient::sendPacket(const QXmppNonza &packet) } /// -/// Sends a packet and reports the result via QFuture. +/// Sends a packet and reports the result via QXmppTask. /// /// If stream management is enabled, the future continues to be active until the /// server acknowledges the packet. On success, QXmpp::SendSuccess with @@ -405,29 +406,26 @@ bool QXmppClient::sendPacket(const QXmppNonza &packet) /// /// \warning THIS API IS NOT FINALIZED YET! /// -/// \returns A QFuture that makes it possible to track the state of the packet. -/// You can use QFutureWatcher in Qt 5 and QFuture::then() in Qt 6 to handle the -/// results. +/// \returns A QXmppTask that makes it possible to track the state of the packet. /// /// \since QXmpp 1.5 /// -QFuture QXmppClient::send(QXmppStanza &&stanza, const std::optional ¶ms) +QXmppTask QXmppClient::send(QXmppStanza &&stanza, const std::optional ¶ms) { - const auto sendEncrypted = [this](QFuture &&future) { - QFutureInterface interface(QFutureInterfaceBase::Started); - - await(future, this, [this, interface](MessageEncryptResult &&result) mutable { + const auto sendEncrypted = [this](QXmppTask &&future) { + QXmppPromise interface; + future.then(this, [this, interface](MessageEncryptResult &&result) mutable { if (const auto *xml = std::get_if(&result)) { auto future = d->stream->send(QXmppPacket(*xml, true, interface)); - await(future, this, [interface](QXmpp::SendResult &&result) mutable { - reportFinishedResult(interface, result); + future.then(this, [interface](QXmpp::SendResult &&result) mutable { + interface.finish(std::move(result)); }); } else { - reportFinishedResult(interface, { std::get(result) }); + interface.finish(std::get(std::move(result))); } }); - return interface.future(); + return interface.task(); }; if (d->encryptionExtension) { @@ -452,13 +450,11 @@ QFuture QXmppClient::send(QXmppStanza &&stanza, const std::op /// /// \warning THIS API IS NOT FINALIZED YET! /// -/// \returns A QFuture that makes it possible to track the state of the packet. -/// You can use QFutureWatcher in Qt 5 and QFuture::then() in Qt 6 to handle the -/// results. +/// \returns A QXmppTask that makes it possible to track the state of the packet. /// /// \since QXmpp 1.5 /// -QFuture QXmppClient::sendUnencrypted(QXmppStanza &&stanza, const std::optional &) +QXmppTask QXmppClient::sendUnencrypted(QXmppStanza &&stanza, const std::optional &) { return d->stream->send(stanza); } @@ -472,7 +468,7 @@ QFuture QXmppClient::sendUnencrypted(QXmppStanza &&stanza, co /// /// \since QXmpp 1.5 /// -QFuture QXmppClient::reply(QXmppStanza &&stanza, const std::optional &e2eeMetadata, const std::optional ¶ms) +QXmppTask QXmppClient::reply(QXmppStanza &&stanza, const std::optional &e2eeMetadata, const std::optional ¶ms) { // This should pick the right e2ee manager as soon as multiple encryptions // in parallel are supported. @@ -497,7 +493,7 @@ QFuture QXmppClient::reply(QXmppStanza &&stanza, const std::o /// /// \since QXmpp 1.5 /// -QFuture QXmppClient::sendIq(QXmppIq &&iq, const std::optional &) +QXmppTask QXmppClient::sendIq(QXmppIq &&iq, const std::optional &) { return d->stream->sendIq(std::move(iq)); } @@ -515,57 +511,52 @@ QFuture QXmppClient::sendIq(QXmppIq &&iq, const std::opti /// /// \since QXmpp 1.5 /// -QFuture QXmppClient::sendSensitiveIq(QXmppIq &&iq, const std::optional ¶ms) +QXmppTask QXmppClient::sendSensitiveIq(QXmppIq &&iq, const std::optional ¶ms) { - const auto sendEncrypted = [this](QFuture &&future, const QString &id, const QString &to) { - QFutureInterface interface(QFutureInterfaceBase::Started); - await(future, this, [this, interface, id, to](IqEncryptResult result) mutable { + const auto sendEncrypted = [this](QXmppTask &&future, const QString &id, const QString &to) { + QXmppPromise interface; + future.then(this, [this, interface, id, to](IqEncryptResult result) mutable { if (const auto *xml = std::get_if(&result)) { // encrypted successfully auto future = d->stream->QXmppStream::sendIq(QXmppPacket(*xml, true), id, to); - await(future, this, [this, interface](QXmppStream::IqResult result) mutable { + future.then(this, [this, interface](QXmppStream::IqResult result) mutable { if (const auto encryptedDom = std::get_if(&result)) { if (!isIqResponse(*encryptedDom)) { QXmppError err { QStringLiteral("Invalid IQ response received."), QXmpp::SendError::EncryptionError }; - interface.reportResult(err); - interface.reportFinished(); + interface.finish(std::move(err)); } else if (d->encryptionExtension) { // try to decrypt the result (should be encrypted) auto future = d->encryptionExtension->decryptIq(*encryptedDom); - await(future, this, [interface, encryptedDom = *encryptedDom](IqDecryptResult result) mutable { - if (const auto dom = std::get_if(&result)) { + future.then(this, [interface, encryptedDom = *encryptedDom](IqDecryptResult result) mutable { + if (auto dom = std::get_if(&result)) { // decrypted result - interface.reportResult(*dom); + interface.finish(std::move(*dom)); } else if (std::holds_alternative(result)) { // the IQ response from the other entity was not encrypted // then report IQ response without modifications - interface.reportResult(encryptedDom); - } else if (const auto error = std::get_if(&result)) { - interface.reportResult(*error); + interface.finish(std::move(encryptedDom)); + } else if (auto error = std::get_if(&result)) { + interface.finish(std::move(*error)); } - interface.reportFinished(); }); } else { - interface.reportResult(QXmppError { + interface.finish(QXmppError { QStringLiteral("No decryption extension found."), QXmpp::SendError::EncryptionError }); - interface.reportFinished(); } } else { - interface.reportResult(std::get(result)); - interface.reportFinished(); + interface.finish(std::get(result)); } }); } else { - interface.reportResult(std::get(result)); - interface.reportFinished(); + interface.finish(std::get(result)); } }); - return interface.future(); + return interface.task(); }; if (iq.id().isEmpty() || d->stream->hasIqId(iq.id())) { @@ -595,7 +586,7 @@ QFuture QXmppClient::sendSensitiveIq(QXmppIq &&iq, const /// /// \since QXmpp 1.5 /// -QFuture QXmppClient::sendGenericIq(QXmppIq &&iq, const std::optional &) +QXmppTask QXmppClient::sendGenericIq(QXmppIq &&iq, const std::optional &) { return chainIq(sendIq(std::move(iq)), this, [](const QXmppIq &) -> EmptyResult { return QXmpp::Success(); diff --git a/src/client/QXmppClient.h b/src/client/QXmppClient.h index e99937cb..5cef5fe3 100644 --- a/src/client/QXmppClient.h +++ b/src/client/QXmppClient.h @@ -19,7 +19,7 @@ #include template -class QFuture; +class QXmppTask; class QXmppE2eeExtension; class QXmppClientExtension; @@ -219,12 +219,12 @@ public: State state() const; QXmppStanza::Error::Condition xmppStreamError(); - QFuture send(QXmppStanza &&, const std::optional & = {}); - QFuture sendUnencrypted(QXmppStanza &&, const std::optional & = {}); - QFuture reply(QXmppStanza &&stanza, const std::optional &e2eeMetadata, const std::optional & = {}); - QFuture sendIq(QXmppIq &&, const std::optional & = {}); - QFuture sendSensitiveIq(QXmppIq &&, const std::optional & = {}); - QFuture sendGenericIq(QXmppIq &&, const std::optional & = {}); + QXmppTask send(QXmppStanza &&, const std::optional & = {}); + QXmppTask sendUnencrypted(QXmppStanza &&, const std::optional & = {}); + QXmppTask reply(QXmppStanza &&stanza, const std::optional &e2eeMetadata, const std::optional & = {}); + QXmppTask sendIq(QXmppIq &&, const std::optional & = {}); + QXmppTask sendSensitiveIq(QXmppIq &&, const std::optional & = {}); + QXmppTask sendGenericIq(QXmppIq &&, const std::optional & = {}); #if QXMPP_DEPRECATED_SINCE(1, 1) QT_DEPRECATED_X("Use QXmppClient::findExtension() instead") diff --git a/src/client/QXmppDiscoveryManager.cpp b/src/client/QXmppDiscoveryManager.cpp index bdea6ede..2a104100 100644 --- a/src/client/QXmppDiscoveryManager.cpp +++ b/src/client/QXmppDiscoveryManager.cpp @@ -117,7 +117,7 @@ QString QXmppDiscoveryManager::requestItems(const QString &jid, const QString &n /// /// \since QXmpp 1.5 /// -QFuture QXmppDiscoveryManager::requestDiscoInfo(const QString &jid, const QString &node) +QXmppTask QXmppDiscoveryManager::requestDiscoInfo(const QString &jid, const QString &node) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); @@ -140,7 +140,7 @@ QFuture QXmppDiscoveryManager::requestDiscoIn /// /// \since QXmpp 1.5 /// -QFuture QXmppDiscoveryManager::requestDiscoItems(const QString &jid, const QString &node) +QXmppTask QXmppDiscoveryManager::requestDiscoItems(const QString &jid, const QString &node) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); diff --git a/src/client/QXmppDiscoveryManager.h b/src/client/QXmppDiscoveryManager.h index bf18619e..56f6dfc4 100644 --- a/src/client/QXmppDiscoveryManager.h +++ b/src/client/QXmppDiscoveryManager.h @@ -10,7 +10,7 @@ #include template -class QFuture; +class QXmppTask; class QXmppDataForm; class QXmppDiscoveryIq; class QXmppDiscoveryManagerPrivate; @@ -35,8 +35,8 @@ public: using InfoResult = std::variant; using ItemsResult = std::variant, QXmppStanza::Error>; - QFuture requestDiscoInfo(const QString &jid, const QString &node = {}); - QFuture requestDiscoItems(const QString &jid, const QString &node = {}); + QXmppTask requestDiscoInfo(const QString &jid, const QString &node = {}); + QXmppTask requestDiscoItems(const QString &jid, const QString &node = {}); QString clientCapabilitiesNode() const; void setClientCapabilitiesNode(const QString &); diff --git a/src/client/QXmppE2eeExtension.h b/src/client/QXmppE2eeExtension.h index f65fec45..af4afdde 100644 --- a/src/client/QXmppE2eeExtension.h +++ b/src/client/QXmppE2eeExtension.h @@ -16,7 +16,7 @@ class QDomElement; class QXmppMessage; class QXmppIq; template -class QFuture; +class QXmppTask; class QXmppE2eeExtension : public QXmppExtension { @@ -30,10 +30,10 @@ public: using IqEncryptResult = std::variant; using IqDecryptResult = std::variant; - virtual QFuture encryptMessage(QXmppMessage &&, const std::optional &) = 0; - virtual QFuture decryptMessage(QXmppMessage &&) = 0; - virtual QFuture encryptIq(QXmppIq &&, const std::optional &) = 0; - virtual QFuture decryptIq(const QDomElement &) = 0; + virtual QXmppTask encryptMessage(QXmppMessage &&, const std::optional &) = 0; + virtual QXmppTask decryptMessage(QXmppMessage &&) = 0; + virtual QXmppTask encryptIq(QXmppIq &&, const std::optional &) = 0; + virtual QXmppTask decryptIq(const QDomElement &) = 0; virtual bool isEncrypted(const QDomElement &) = 0; virtual bool isEncrypted(const QXmppMessage &) = 0; }; diff --git a/src/client/QXmppEntityTimeManager.cpp b/src/client/QXmppEntityTimeManager.cpp index eb88fc0f..08089139 100644 --- a/src/client/QXmppEntityTimeManager.cpp +++ b/src/client/QXmppEntityTimeManager.cpp @@ -55,7 +55,7 @@ QString QXmppEntityTimeManager::requestTime(const QString &jid) /// /// \since QXmpp 1.5 /// -auto QXmppEntityTimeManager::requestEntityTime(const QString &jid) -> QFuture +auto QXmppEntityTimeManager::requestEntityTime(const QString &jid) -> QXmppTask { QXmppEntityTimeIq iq; iq.setType(QXmppIq::Get); diff --git a/src/client/QXmppEntityTimeManager.h b/src/client/QXmppEntityTimeManager.h index a807caad..81c6fb45 100644 --- a/src/client/QXmppEntityTimeManager.h +++ b/src/client/QXmppEntityTimeManager.h @@ -10,7 +10,7 @@ #include template -class QFuture; +class QXmppTask; class QXmppEntityTimeIq; /// @@ -27,7 +27,7 @@ public: QString requestTime(const QString &jid); using EntityTimeResult = std::variant; - QFuture requestEntityTime(const QString &jid); + QXmppTask requestEntityTime(const QString &jid); /// \cond QStringList discoveryFeatures() const override; diff --git a/src/client/QXmppHttpUploadManager.cpp b/src/client/QXmppHttpUploadManager.cpp index 2fe2994e..35eedf80 100644 --- a/src/client/QXmppHttpUploadManager.cpp +++ b/src/client/QXmppHttpUploadManager.cpp @@ -5,8 +5,8 @@ #include "QXmppHttpUploadManager.h" #include "QXmppClient.h" -#include "QXmppFutureUtils_p.h" #include "QXmppHttpUploadIq.h" +#include "QXmppTask.h" #include "QXmppUploadRequestManager.h" #include "QXmppUtils_p.h" @@ -299,11 +299,8 @@ std::shared_ptr QXmppHttpUploadManager::uploadFile(std::unique_ } auto future = client()->findExtension()->requestSlot(filename, fileSize, mimeType, uploadServiceJid); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) - await(future, this, [this, upload, data = std::move(data)](SlotResult result) mutable { -#else - await(future, this, [this, upload, rawSourceDevice = data.release()](SlotResult result) mutable { -#endif + // TODO: rawSourceDevice: could this lead to a memory leak if the "then lambda" is never executed? + future.then(this, [this, upload, rawSourceDevice = data.release()](SlotResult result) mutable { // first check whether upload was cancelled in the meantime if (upload->d->cancelled) { upload->d->reportFinished(); @@ -331,11 +328,6 @@ std::shared_ptr QXmppHttpUploadManager::uploadFile(std::unique_ request.setRawHeader(itr.key().toUtf8(), itr.value().toUtf8()); } -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) - auto *rawSourceDevice = data.release(); -#else - // already defined in lambda capture -#endif auto *reply = d->netManager->put(request, rawSourceDevice); rawSourceDevice->setParent(reply); upload->d->reply = reply; diff --git a/src/client/QXmppIqHandling.h b/src/client/QXmppIqHandling.h index e7db2b5d..530e214b 100644 --- a/src/client/QXmppIqHandling.h +++ b/src/client/QXmppIqHandling.h @@ -53,7 +53,7 @@ namespace Private { const QString &requestId, const QString &requestFrom, const std::optional &e2eeMetadata, - QFuture future) + QXmppTask future) { Private::await(future, client, [client, requestId, requestFrom, e2eeMetadata](T result) { processHandleIqResult(client, requestId, requestFrom, e2eeMetadata, result); @@ -162,7 +162,7 @@ namespace Private { /// The return type of the handler function can be: /// 1. an QXmppIq based type /// 2. a std::variant of QXmppIq based types (multiple are possible) and optionally also QXmppStanza::Error -/// 3. a QFuture of 1. or 2. +/// 3. a QXmppTask of 1. or 2. /// /// You don't need to set the values for id or the to address on the IQ result because that's done /// automatically. Unless you want to return an error IQ you also don't need to set the IQ type. @@ -254,7 +254,7 @@ bool handleIqRequests(const QDomElement &element, /// The return type of the handler function can be: /// 1. an QXmppIq based type /// 2. a std::variant of QXmppIq based types (multiple are possible) and optionally also QXmppStanza::Error -/// 3. a QFuture of 1. or 2. +/// 3. a QXmppTask of 1. or 2. /// /// You don't need to set the values for id or the to address on the IQ result because that's done /// automatically. Unless you want to return an error IQ you also don't need to set the IQ type. diff --git a/src/client/QXmppMamManager.cpp b/src/client/QXmppMamManager.cpp index 125e9a48..f173aa01 100644 --- a/src/client/QXmppMamManager.cpp +++ b/src/client/QXmppMamManager.cpp @@ -17,24 +17,21 @@ #include #include -#include -#include using namespace QXmpp::Private; struct RetrieveRequestState { - QFutureInterface interface; + QXmppPromise promise; QXmppMamResultIq iq; QVector messages; - void reportFinished() + void finish() { - interface.reportResult( + promise.finish( QXmppMamManager::RetrievedMessages { std::move(iq), std::move(messages) }); - interface.reportFinished(); } }; @@ -89,7 +86,6 @@ QStringList QXmppMamManager::discoveryFeatures() const bool QXmppMamManager::handleStanza(const QDomElement &element) { - if (element.tagName() == "message") { QDomElement resultElement = element.firstChildElement("result"); if (!resultElement.isNull() && resultElement.namespaceURI() == ns_mam) { @@ -241,14 +237,14 @@ QString QXmppMamManager::retrieveArchivedMessages(const QString &to, /// /// \since QXmpp 1.5 /// -QFuture QXmppMamManager::retrieveMessages(const QString &to, const QString &node, const QString &jid, const QDateTime &start, const QDateTime &end, const QXmppResultSetQuery &resultSetQuery) +QXmppTask QXmppMamManager::retrieveMessages(const QString &to, const QString &node, const QString &jid, const QDateTime &start, const QDateTime &end, const QXmppResultSetQuery &resultSetQuery) { auto queryIq = buildRequest(to, node, jid, start, end, resultSetQuery); auto [itr, _] = d->ongoingRequests.insert({ queryIq.queryId().toStdString(), RetrieveRequestState() }); // retrieve messages - await(client()->sendIq(std::move(queryIq)), this, [this, queryId = queryIq.queryId()](QXmppClient::IqResult result) { + client()->sendIq(std::move(queryIq)).then(this, [this, queryId = queryIq.queryId()](QXmppClient::IqResult result) { auto itr = d->ongoingRequests.find(queryId.toStdString()); if (itr == d->ongoingRequests.end()) { return; @@ -259,8 +255,7 @@ QFuture QXmppMamManager::retrieveMessages(const iq.parse(std::get(result)); if (iq.type() == QXmppIq::Error) { - itr->second.interface.reportResult(QXmppError { iq.error().text(), iq.error() }); - itr->second.interface.reportFinished(); + itr->second.promise.finish(QXmppError { iq.error().text(), iq.error() }); d->ongoingRequests.erase(itr); return; } @@ -277,7 +272,7 @@ QFuture QXmppMamManager::retrieveMessages(const auto message = messages.at(i); (*running)++; - await(e2eeExt->decryptMessage(std::move(message)), this, [this, i, running, queryId](auto result) { + e2eeExt->decryptMessage(std::move(message)).then(this, [this, i, running, queryId](auto result) { (*running)--; auto itr = d->ongoingRequests.find(queryId.toStdString()); if (itr == d->ongoingRequests.end()) { @@ -290,21 +285,20 @@ QFuture QXmppMamManager::retrieveMessages(const warning(QStringLiteral("Error decrypting message.")); } if (*running == 0) { - itr->second.reportFinished(); + itr->second.finish(); d->ongoingRequests.erase(itr); } }); } } else { - itr->second.reportFinished(); + itr->second.finish(); d->ongoingRequests.erase(itr); } } else { - itr->second.interface.reportResult(std::get(result)); - itr->second.interface.reportFinished(); + itr->second.promise.finish(std::get(result)); d->ongoingRequests.erase(itr); } }); - return itr->second.interface.future(); + return itr->second.promise.task(); } diff --git a/src/client/QXmppMamManager.h b/src/client/QXmppMamManager.h index 579bfc74..71cb4311 100644 --- a/src/client/QXmppMamManager.h +++ b/src/client/QXmppMamManager.h @@ -15,7 +15,7 @@ #include template -class QFuture; +class QXmppTask; class QXmppMessage; class QXmppMamManagerPrivate; @@ -57,12 +57,12 @@ public: const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime(), const QXmppResultSetQuery &resultSetQuery = QXmppResultSetQuery()); - QFuture retrieveMessages(const QString &to = QString(), - const QString &node = QString(), - const QString &jid = QString(), - const QDateTime &start = QDateTime(), - const QDateTime &end = QDateTime(), - const QXmppResultSetQuery &resultSetQuery = QXmppResultSetQuery()); + QXmppTask retrieveMessages(const QString &to = QString(), + const QString &node = QString(), + const QString &jid = QString(), + const QDateTime &start = QDateTime(), + const QDateTime &end = QDateTime(), + const QXmppResultSetQuery &resultSetQuery = QXmppResultSetQuery()); /// \cond QStringList discoveryFeatures() const override; diff --git a/src/client/QXmppMessageReceiptManager.cpp b/src/client/QXmppMessageReceiptManager.cpp index b464ed18..ae50bbd3 100644 --- a/src/client/QXmppMessageReceiptManager.cpp +++ b/src/client/QXmppMessageReceiptManager.cpp @@ -9,6 +9,7 @@ #include "QXmppConstants_p.h" #include "QXmppE2eeMetadata.h" #include "QXmppMessage.h" +#include "QXmppTask.h" #include "QXmppUtils.h" #include diff --git a/src/client/QXmppOutgoingClient.cpp b/src/client/QXmppOutgoingClient.cpp index 7a774f51..20e88b9c 100644 --- a/src/client/QXmppOutgoingClient.cpp +++ b/src/client/QXmppOutgoingClient.cpp @@ -15,6 +15,7 @@ #include "QXmppSasl_p.h" #include "QXmppStreamFeatures.h" #include "QXmppStreamManagement_p.h" +#include "QXmppTask.h" #include "QXmppUtils.h" #include @@ -325,7 +326,7 @@ bool QXmppOutgoingClient::isStreamResumed() const /// /// \since QXmpp 1.5 /// -QFuture QXmppOutgoingClient::sendIq(QXmppIq &&iq) +QXmppTask QXmppOutgoingClient::sendIq(QXmppIq &&iq) { // always set a to address (the QXmppStream needs this for matching) if (iq.to().isEmpty()) { diff --git a/src/client/QXmppOutgoingClient.h b/src/client/QXmppOutgoingClient.h index 6c72d076..019275f8 100644 --- a/src/client/QXmppOutgoingClient.h +++ b/src/client/QXmppOutgoingClient.h @@ -38,7 +38,7 @@ public: bool isClientStateIndicationEnabled() const; bool isStreamManagementEnabled() const; bool isStreamResumed() const; - QFuture sendIq(QXmppIq &&); + QXmppTask sendIq(QXmppIq &&); /// Returns the used socket QSslSocket *socket() const { return QXmppStream::socket(); }; diff --git a/src/client/QXmppPep_p.h b/src/client/QXmppPep_p.h index 6ffac236..aafc6520 100644 --- a/src/client/QXmppPep_p.h +++ b/src/client/QXmppPep_p.h @@ -12,7 +12,7 @@ using GetResult = std::variant; using PublishResult = std::variant; template -inline QFuture> request(QXmppPubSubManager *pubSub, const QString &jid, const QString &nodeName, QObject *parent) +inline QXmppTask> request(QXmppPubSubManager *pubSub, const QString &jid, const QString &nodeName, QObject *parent) { using PubSub = QXmppPubSubManager; using Error = QXmppStanza::Error; diff --git a/src/client/QXmppPubSubManager.cpp b/src/client/QXmppPubSubManager.cpp index 1582c65e..a10fc25b 100644 --- a/src/client/QXmppPubSubManager.cpp +++ b/src/client/QXmppPubSubManager.cpp @@ -17,7 +17,6 @@ #include "QXmppUtils.h" #include -#include using namespace QXmpp::Private; @@ -211,7 +210,7 @@ QXmppPubSubManager::~QXmppPubSubManager() /// \param serviceJid JID of the entity hosting the pubsub service /// \param serviceType type of service to retrieve features for /// -QFuture QXmppPubSubManager::requestFeatures(const QString &serviceJid, ServiceType serviceType) +QXmppTask QXmppPubSubManager::requestFeatures(const QString &serviceJid, ServiceType serviceType) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); @@ -259,7 +258,7 @@ QFuture QXmppPubSubManager::requestFeatures( /// \param jid Jabber ID of the entity hosting the pubsub service /// \return /// -QFuture QXmppPubSubManager::requestNodes(const QString &jid) +QXmppTask QXmppPubSubManager::requestNodes(const QString &jid) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); @@ -293,7 +292,7 @@ QFuture QXmppPubSubManager::requestNodes(const /// \param nodeName the name of the node to be created /// \return /// -auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName) -> QFuture +auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName) -> QXmppTask { PubSubIq request; request.setType(QXmppIq::Set); @@ -316,7 +315,7 @@ auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName) /// \param config The configuration for the node /// \return /// -auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config) -> QFuture +auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config) -> QXmppTask { PubSubIq request; request.setType(QXmppIq::Set); @@ -337,7 +336,7 @@ auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName, /// \param jid Jabber ID of the entity hosting the pubsub service /// \return /// -QFuture QXmppPubSubManager::createInstantNode(const QString &jid) +QXmppTask QXmppPubSubManager::createInstantNode(const QString &jid) { PubSubIq request; request.setType(QXmppIq::Set); @@ -360,7 +359,7 @@ QFuture QXmppPubSubManager::createInstant /// \param config The configuration for the node /// \return /// -auto QXmppPubSubManager::createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config) -> QFuture +auto QXmppPubSubManager::createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config) -> QXmppTask { PubSubIq request; request.setType(QXmppIq::Set); @@ -381,7 +380,7 @@ auto QXmppPubSubManager::createInstantNode(const QString &jid, const QXmppPubSub /// \param nodeName the name of the node to delete along with all of its items /// \return /// -auto QXmppPubSubManager::deleteNode(const QString &jid, const QString &nodeName) -> QFuture +auto QXmppPubSubManager::deleteNode(const QString &jid, const QString &nodeName) -> QXmppTask { PubSubIq request; request.setType(QXmppIq::Set); @@ -403,7 +402,7 @@ auto QXmppPubSubManager::deleteNode(const QString &jid, const QString &nodeName) /// \param nodeName the name of the node whose items are requested /// \return /// -QFuture QXmppPubSubManager::requestItemIds(const QString &serviceJid, const QString &nodeName) +QXmppTask QXmppPubSubManager::requestItemIds(const QString &serviceJid, const QString &nodeName) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); @@ -430,7 +429,7 @@ QFuture QXmppPubSubManager::requestItemIds(co /// \param itemId the ID of the item to delete /// \return /// -auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName, const QString &itemId) -> QFuture +auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName, const QString &itemId) -> QXmppTask { PubSubIq request; request.setType(QXmppIq::Set); @@ -449,7 +448,7 @@ auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName /// \param nodeName the name of the node to delete the item from /// \param itemId the ID of the item to delete /// -auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId) -> QFuture +auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId) -> QXmppTask { return retractItem(jid, nodeName, standardItemIdToString(itemId)); } @@ -462,7 +461,7 @@ auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName /// items /// \return /// -auto QXmppPubSubManager::purgeItems(const QString &jid, const QString &nodeName) -> QFuture +auto QXmppPubSubManager::purgeItems(const QString &jid, const QString &nodeName) -> QXmppTask { PubSubIq request; request.setType(QXmppIq::Set); @@ -479,7 +478,7 @@ auto QXmppPubSubManager::purgeItems(const QString &jid, const QString &nodeName) /// \param jid JID of the pubsub service /// \return /// -QFuture QXmppPubSubManager::requestSubscriptions(const QString &jid) +QXmppTask QXmppPubSubManager::requestSubscriptions(const QString &jid) { return requestSubscriptions(jid, {}); } @@ -491,7 +490,7 @@ QFuture QXmppPubSubManager::requestSubs /// \param nodeName Name of the node on the pubsub service /// \return /// -QFuture QXmppPubSubManager::requestSubscriptions(const QString &jid, const QString &nodeName) +QXmppTask QXmppPubSubManager::requestSubscriptions(const QString &jid, const QString &nodeName) { PubSubIq request; request.setType(QXmppIq::Get); @@ -515,7 +514,7 @@ QFuture QXmppPubSubManager::requestSubs /// \param nodeName Name of the pubsub node on the service. /// \return /// -QFuture QXmppPubSubManager::requestNodeAffiliations(const QString &jid, const QString &nodeName) +QXmppTask QXmppPubSubManager::requestNodeAffiliations(const QString &jid, const QString &nodeName) { PubSubIq request; request.setType(QXmppIq::Get); @@ -535,7 +534,7 @@ QFuture QXmppPubSubManager::requestNodeA /// \param jid JID of the pubsub service /// \return /// -QFuture QXmppPubSubManager::requestAffiliations(const QString &jid) +QXmppTask QXmppPubSubManager::requestAffiliations(const QString &jid) { return requestAffiliations(jid, {}); } @@ -547,7 +546,7 @@ QFuture QXmppPubSubManager::requestAffil /// \param nodeName Name of the pubsub node on the service. /// \return /// -QFuture QXmppPubSubManager::requestAffiliations(const QString &jid, const QString &nodeName) +QXmppTask QXmppPubSubManager::requestAffiliations(const QString &jid, const QString &nodeName) { PubSubIq request; request.setType(QXmppIq::Get); @@ -568,7 +567,7 @@ QFuture QXmppPubSubManager::requestAffil /// \param nodeName Name of the pubsub node on the service. /// \return /// -QFuture QXmppPubSubManager::requestSubscribeOptions(const QString &service, const QString &nodeName) +QXmppTask QXmppPubSubManager::requestSubscribeOptions(const QString &service, const QString &nodeName) { return requestSubscribeOptions(service, nodeName, client()->configuration().jidBare()); } @@ -581,7 +580,7 @@ QFuture QXmppPubSubManager::requestSubscribeO /// \param subscriberJid JID of the user to request the options for /// \return /// -QFuture QXmppPubSubManager::requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid) +QXmppTask QXmppPubSubManager::requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid) { PubSubIq request; request.setType(QXmppIq::Get); @@ -614,7 +613,7 @@ QFuture QXmppPubSubManager::requestSubscribeO /// \param options The new options to be set /// \return /// -QFuture QXmppPubSubManager::setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options) +QXmppTask QXmppPubSubManager::setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options) { return setSubscribeOptions(service, nodeName, options, client()->configuration().jidBare()); } @@ -628,7 +627,7 @@ QFuture QXmppPubSubManager::setSubscribeOptions(cons /// \param subscriberJid The JID of the user /// \return /// -QFuture QXmppPubSubManager::setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid) +QXmppTask QXmppPubSubManager::setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid) { PubSubIq request; request.setType(QXmppIq::Set); @@ -654,7 +653,7 @@ QFuture QXmppPubSubManager::setSubscribeOptions(cons /// \sa configureNode() /// \sa cancelNodeConfiguration() /// -QFuture QXmppPubSubManager::requestNodeConfiguration(const QString &service, const QString &nodeName) +QXmppTask QXmppPubSubManager::requestNodeConfiguration(const QString &service, const QString &nodeName) { using Error = QXmppStanza::Error; @@ -689,7 +688,7 @@ QFuture QXmppPubSubManager::requestNodeCon /// /// \sa requestNodeConfiguration() /// -QFuture QXmppPubSubManager::configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config) +QXmppTask QXmppPubSubManager::configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config) { PubSubIq request; request.setType(QXmppIq::Set); @@ -710,7 +709,7 @@ QFuture QXmppPubSubManager::configureNode(const QStr /// /// \sa requestNodeConfiguration() /// -QFuture QXmppPubSubManager::cancelNodeConfiguration(const QString &service, const QString &nodeName) +QXmppTask QXmppPubSubManager::cancelNodeConfiguration(const QString &service, const QString &nodeName) { PubSubIq request; request.setType(QXmppIq::Set); @@ -730,7 +729,7 @@ QFuture QXmppPubSubManager::cancelNodeConfiguration( /// \param nodeName name of the pubsub node being subscribed /// \param subscriberJid bare or full JID of the subscriber /// -QFuture QXmppPubSubManager::subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid) +QXmppTask QXmppPubSubManager::subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid) { PubSubIq request; request.setType(QXmppIq::Set); @@ -750,7 +749,7 @@ QFuture QXmppPubSubManager::subscribeToNode(const QS /// \param nodeName name of the pubsub node being subscribed /// \param subscriberJid bare or full JID of the subscriber /// -QFuture QXmppPubSubManager::unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid) +QXmppTask QXmppPubSubManager::unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid) { PubSubIq request; request.setType(QXmppIq::Set); @@ -785,7 +784,7 @@ QFuture QXmppPubSubManager::unsubscribeFromNode(cons /// /// -/// \fn QFuture QXmppPubSubManager::createOwnPepNode(const QString &nodeName) +/// \fn QXmppTask QXmppPubSubManager::createOwnPepNode(const QString &nodeName) /// /// Creates an empty PEP node with the default configuration. /// @@ -801,7 +800,7 @@ QFuture QXmppPubSubManager::unsubscribeFromNode(cons /// /// -/// \fn QFuture QXmppPubSubManager::createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) +/// \fn QXmppTask QXmppPubSubManager::createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) /// /// Creates an empty PEP node with a custom configuration. /// @@ -1024,7 +1023,7 @@ PubSubIq<> QXmppPubSubManager::requestItemsIq(const QString &jid, const QString return request; } -auto QXmppPubSubManager::publishItem(PubSubIqBase &&request) -> QFuture +auto QXmppPubSubManager::publishItem(PubSubIqBase &&request) -> QXmppTask { request.setType(QXmppIq::Set); request.setQueryType(PubSubIqBase::Publish); @@ -1039,7 +1038,7 @@ auto QXmppPubSubManager::publishItem(PubSubIqBase &&request) -> QFuture QFuture +auto QXmppPubSubManager::publishItems(PubSubIqBase &&request) -> QXmppTask { request.setType(QXmppIq::Set); request.setQueryType(PubSubIqBase::Publish); diff --git a/src/client/QXmppPubSubManager.h b/src/client/QXmppPubSubManager.h index ddd3840c..4e5ab9f8 100644 --- a/src/client/QXmppPubSubManager.h +++ b/src/client/QXmppPubSubManager.h @@ -14,9 +14,6 @@ #include "QXmppPubSubPublishOptions.h" #include "QXmppResultSet.h" -#include -#include - class QXmppPubSubPublishOptions; class QXmppPubSubSubscribeOptions; @@ -75,73 +72,73 @@ public: ~QXmppPubSubManager(); // Generic PubSub (the PubSub service is the given entity) - QFuture requestNodes(const QString &jid); - QFuture createNode(const QString &jid, const QString &nodeName); - QFuture createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config); - QFuture createInstantNode(const QString &jid); - QFuture createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config); - QFuture deleteNode(const QString &jid, const QString &nodeName); - QFuture requestItemIds(const QString &serviceJid, const QString &nodeName); + QXmppTask requestNodes(const QString &jid); + QXmppTask createNode(const QString &jid, const QString &nodeName); + QXmppTask createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config); + QXmppTask createInstantNode(const QString &jid); + QXmppTask createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config); + QXmppTask deleteNode(const QString &jid, const QString &nodeName); + QXmppTask requestItemIds(const QString &serviceJid, const QString &nodeName); template - QFuture> requestItem(const QString &jid, const QString &nodeName, const QString &itemId); + QXmppTask> requestItem(const QString &jid, const QString &nodeName, const QString &itemId); template - QFuture> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId); + QXmppTask> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId); template - QFuture> requestItems(const QString &jid, const QString &nodeName); + QXmppTask> requestItems(const QString &jid, const QString &nodeName); template - QFuture> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds); + QXmppTask> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds); template - QFuture publishItem(const QString &jid, const QString &nodeName, const T &item); + QXmppTask publishItem(const QString &jid, const QString &nodeName, const T &item); template - QFuture publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); + QXmppTask publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); template - QFuture publishItems(const QString &jid, const QString &nodeName, const QVector &items); + QXmppTask publishItems(const QString &jid, const QString &nodeName, const QVector &items); template - QFuture publishItems(const QString &jid, const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions); - QFuture retractItem(const QString &jid, const QString &nodeName, const QString &itemId); - QFuture retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId); - QFuture purgeItems(const QString &jid, const QString &nodeName); - QFuture requestSubscriptions(const QString &jid); - QFuture requestSubscriptions(const QString &jid, const QString &nodeName); - QFuture requestNodeAffiliations(const QString &jid, const QString &nodeName); - QFuture requestAffiliations(const QString &jid); - QFuture requestAffiliations(const QString &jid, const QString &nodeName); - QFuture requestSubscribeOptions(const QString &service, const QString &nodeName); - QFuture requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid); - QFuture setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options); - QFuture setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid); - QFuture requestNodeConfiguration(const QString &service, const QString &nodeName); - QFuture configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config); - QFuture cancelNodeConfiguration(const QString &service, const QString &nodeName); - QFuture subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); - QFuture unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); + QXmppTask publishItems(const QString &jid, const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions); + QXmppTask retractItem(const QString &jid, const QString &nodeName, const QString &itemId); + QXmppTask retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId); + QXmppTask purgeItems(const QString &jid, const QString &nodeName); + QXmppTask requestSubscriptions(const QString &jid); + QXmppTask requestSubscriptions(const QString &jid, const QString &nodeName); + QXmppTask requestNodeAffiliations(const QString &jid, const QString &nodeName); + QXmppTask requestAffiliations(const QString &jid); + QXmppTask requestAffiliations(const QString &jid, const QString &nodeName); + QXmppTask requestSubscribeOptions(const QString &service, const QString &nodeName); + QXmppTask requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid); + QXmppTask setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options); + QXmppTask setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid); + QXmppTask requestNodeConfiguration(const QString &service, const QString &nodeName); + QXmppTask configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config); + QXmppTask cancelNodeConfiguration(const QString &service, const QString &nodeName); + QXmppTask subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); + QXmppTask unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); // PEP-specific (the PubSub service is the current account) - QFuture requestOwnPepNodes() { return requestNodes(client()->configuration().jidBare()); }; - QFuture createOwnPepNode(const QString &nodeName) { return createNode(client()->configuration().jidBare(), nodeName); } - QFuture createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return createNode(client()->configuration().jidBare(), nodeName, config); } - QFuture deleteOwnPepNode(const QString &nodeName) { return deleteNode(client()->configuration().jidBare(), nodeName); } + QXmppTask requestOwnPepNodes() { return requestNodes(client()->configuration().jidBare()); }; + QXmppTask createOwnPepNode(const QString &nodeName) { return createNode(client()->configuration().jidBare(), nodeName); } + QXmppTask createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return createNode(client()->configuration().jidBare(), nodeName, config); } + QXmppTask deleteOwnPepNode(const QString &nodeName) { return deleteNode(client()->configuration().jidBare(), nodeName); } template - QFuture> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem(client()->configuration().jidBare(), nodeName, itemId); } + QXmppTask> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem(client()->configuration().jidBare(), nodeName, itemId); } template - QFuture> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem(client()->configuration().jidBare(), nodeName, itemId); } + QXmppTask> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem(client()->configuration().jidBare(), nodeName, itemId); } template - QFuture> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); } - QFuture requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); } + QXmppTask> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); } + QXmppTask requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); } template - QFuture publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); + QXmppTask publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); template - QFuture publishOwnPepItem(const QString &nodeName, const T &item); + QXmppTask publishOwnPepItem(const QString &nodeName, const T &item); template - QFuture publishOwnPepItems(const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions); + QXmppTask publishOwnPepItems(const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions); template - QFuture publishOwnPepItems(const QString &nodeName, const QVector &items); - QFuture retractOwnPepItem(const QString &nodeName, const QString &itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } - QFuture retractOwnPepItem(const QString &nodeName, StandardItemId itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } - QFuture purgeOwnPepItems(const QString &nodeName) { return purgeItems(client()->configuration().jidBare(), nodeName); } - QFuture requestOwnPepNodeConfiguration(const QString &nodeName) { return requestNodeConfiguration(client()->configuration().jidBare(), nodeName); } - QFuture configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return configureNode(client()->configuration().jidBare(), nodeName, config); } - QFuture cancelOwnPepNodeConfiguration(const QString &nodeName) { return cancelNodeConfiguration(client()->configuration().jidBare(), nodeName); } + QXmppTask publishOwnPepItems(const QString &nodeName, const QVector &items); + QXmppTask retractOwnPepItem(const QString &nodeName, const QString &itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } + QXmppTask retractOwnPepItem(const QString &nodeName, StandardItemId itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } + QXmppTask purgeOwnPepItems(const QString &nodeName) { return purgeItems(client()->configuration().jidBare(), nodeName); } + QXmppTask requestOwnPepNodeConfiguration(const QString &nodeName) { return requestNodeConfiguration(client()->configuration().jidBare(), nodeName); } + QXmppTask configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return configureNode(client()->configuration().jidBare(), nodeName, config); } + QXmppTask cancelOwnPepNodeConfiguration(const QString &nodeName) { return cancelNodeConfiguration(client()->configuration().jidBare(), nodeName); } static QString standardItemIdToString(StandardItemId itemId); @@ -155,11 +152,11 @@ private: friend class tst_QXmppPubSubManager; friend class QXmppOmemoManagerPrivate; - QFuture requestFeatures(const QString &serviceJid, ServiceType serviceType = PubSubOrPep); - QFuture requestOwnPepFeatures() { return requestFeatures(client()->configuration().jidBare(), Pep); }; + QXmppTask requestFeatures(const QString &serviceJid, ServiceType serviceType = PubSubOrPep); + QXmppTask requestOwnPepFeatures() { return requestFeatures(client()->configuration().jidBare(), Pep); }; - QFuture publishItem(QXmpp::Private::PubSubIqBase &&iq); - QFuture publishItems(QXmpp::Private::PubSubIqBase &&iq); + QXmppTask publishItem(QXmpp::Private::PubSubIqBase &&iq); + QXmppTask publishItems(QXmpp::Private::PubSubIqBase &&iq); static QXmpp::Private::PubSubIq<> requestItemsIq(const QString &jid, const QString &nodeName, const QStringList &itemIds); }; @@ -173,9 +170,9 @@ private: /// \return /// template -QFuture> QXmppPubSubManager::requestItem(const QString &jid, - const QString &nodeName, - const QString &itemId) +QXmppTask> QXmppPubSubManager::requestItem(const QString &jid, + const QString &nodeName, + const QString &itemId) { using namespace QXmpp::Private; using Error = QXmppStanza::Error; @@ -198,9 +195,9 @@ QFuture> QXmppPubSubManager::requestItem(const /// \return /// template -QFuture> QXmppPubSubManager::requestItem(const QString &jid, - const QString &nodeName, - StandardItemId itemId) +QXmppTask> QXmppPubSubManager::requestItem(const QString &jid, + const QString &nodeName, + StandardItemId itemId) { return requestItem(jid, nodeName, standardItemIdToString(itemId)); } @@ -214,8 +211,8 @@ QFuture> QXmppPubSubManager::requestItem(const /// \return /// template -QFuture> QXmppPubSubManager::requestItems(const QString &jid, - const QString &nodeName) +QXmppTask> QXmppPubSubManager::requestItems(const QString &jid, + const QString &nodeName) { return requestItems(jid, nodeName, {}); } @@ -231,9 +228,9 @@ QFuture> QXmppPubSubManager::requestItems(con /// \return /// template -QFuture> QXmppPubSubManager::requestItems(const QString &jid, - const QString &nodeName, - const QStringList &itemIds) +QXmppTask> QXmppPubSubManager::requestItems(const QString &jid, + const QString &nodeName, + const QStringList &itemIds) { using namespace QXmpp::Private; return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, itemIds)), this, @@ -257,9 +254,9 @@ QFuture> QXmppPubSubManager::requestItems(con /// \return /// template -QFuture QXmppPubSubManager::publishItem(const QString &jid, - const QString &nodeName, - const T &item) +QXmppTask QXmppPubSubManager::publishItem(const QString &jid, + const QString &nodeName, + const T &item) { QXmpp::Private::PubSubIq request; request.setTo(jid); @@ -281,10 +278,10 @@ QFuture QXmppPubSubManager::publishItem(c /// \return /// template -QFuture QXmppPubSubManager::publishItem(const QString &jid, - const QString &nodeName, - const T &item, - const QXmppPubSubPublishOptions &publishOptions) +QXmppTask QXmppPubSubManager::publishItem(const QString &jid, + const QString &nodeName, + const T &item, + const QXmppPubSubPublishOptions &publishOptions) { QXmpp::Private::PubSubIq request; request.setTo(jid); @@ -303,9 +300,9 @@ QFuture QXmppPubSubManager::publishItem(c /// \return /// template -QFuture QXmppPubSubManager::publishItems(const QString &jid, - const QString &nodeName, - const QVector &items) +QXmppTask QXmppPubSubManager::publishItems(const QString &jid, + const QString &nodeName, + const QVector &items) { QXmpp::Private::PubSubIq request; request.setTo(jid); @@ -324,10 +321,10 @@ QFuture QXmppPubSubManager::publishItems /// \return /// template -QFuture QXmppPubSubManager::publishItems(const QString &jid, - const QString &nodeName, - const QVector &items, - const QXmppPubSubPublishOptions &publishOptions) +QXmppTask QXmppPubSubManager::publishItems(const QString &jid, + const QString &nodeName, + const QVector &items, + const QXmppPubSubPublishOptions &publishOptions) { QXmpp::Private::PubSubIq request; request.setTo(jid); @@ -346,7 +343,7 @@ QFuture QXmppPubSubManager::publishItems /// \return /// template -QFuture QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions) +QXmppTask QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions) { return publishItem(client()->configuration().jidBare(), nodeName, item, publishOptions); } @@ -359,7 +356,7 @@ QFuture QXmppPubSubManager::publishOwnPep /// \return /// template -QFuture QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item) +QXmppTask QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item) { return publishItem(client()->configuration().jidBare(), nodeName, item); } @@ -374,7 +371,7 @@ QFuture QXmppPubSubManager::publishOwnPep /// \return /// template -QFuture QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions) +QXmppTask QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions) { return publishItems(client()->configuration().jidBare(), nodeName, items, publishOptions); } @@ -387,7 +384,7 @@ QFuture QXmppPubSubManager::publishOwnPe /// \return /// template -QFuture QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector &items) +QXmppTask QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector &items) { return publishItems(client()->configuration().jidBare(), nodeName, items); } diff --git a/src/client/QXmppRosterManager.cpp b/src/client/QXmppRosterManager.cpp index 810a4615..87ebbd26 100644 --- a/src/client/QXmppRosterManager.cpp +++ b/src/client/QXmppRosterManager.cpp @@ -256,7 +256,7 @@ void QXmppRosterManager::_q_presenceReceived(const QXmppPresence &presence) /// /// \since QXmpp 1.5 /// -QFuture QXmppRosterManager::addRosterItem(const QString &bareJid, const QString &name, const QSet &groups) +QXmppTask QXmppRosterManager::addRosterItem(const QString &bareJid, const QString &name, const QSet &groups) { QXmppRosterIq::Item item; item.setBareJid(bareJid); @@ -280,7 +280,7 @@ QFuture QXmppRosterManager::addRosterItem(const QStr /// /// \since QXmpp 1.5 /// -QFuture QXmppRosterManager::removeRosterItem(const QString &bareJid) +QXmppTask QXmppRosterManager::removeRosterItem(const QString &bareJid) { QXmppRosterIq::Item item; item.setBareJid(bareJid); @@ -303,11 +303,11 @@ QFuture QXmppRosterManager::removeRosterItem(const Q /// /// \since QXmpp 1.5 /// -QFuture QXmppRosterManager::renameRosterItem(const QString &bareJid, const QString &name) +QXmppTask QXmppRosterManager::renameRosterItem(const QString &bareJid, const QString &name) { using Error = QXmppStanza::Error; if (!d->entries.contains(bareJid)) { - return QXmpp::Private::makeReadyFuture( + return QXmpp::Private::makeReadyTask( Error(Error::Modify, Error::ItemNotFound, QStringLiteral("The roster doesn't contain this user."))); } @@ -334,7 +334,7 @@ QFuture QXmppRosterManager::renameRosterItem(const Q /// /// \since QXmpp 1.5 /// -QFuture QXmppRosterManager::subscribeTo(const QString &bareJid, const QString &reason) +QXmppTask QXmppRosterManager::subscribeTo(const QString &bareJid, const QString &reason) { QXmppPresence packet; packet.setTo(QXmppUtils::jidToBareJid(bareJid)); @@ -351,7 +351,7 @@ QFuture QXmppRosterManager::subscribeTo(const QString &bareJi /// /// \since QXmpp 1.5 /// -QFuture QXmppRosterManager::unsubscribeFrom(const QString &bareJid, const QString &reason) +QXmppTask QXmppRosterManager::unsubscribeFrom(const QString &bareJid, const QString &reason) { QXmppPresence packet; packet.setTo(QXmppUtils::jidToBareJid(bareJid)); @@ -375,13 +375,13 @@ bool QXmppRosterManager::refuseSubscription(const QString &bareJid, const QStrin } /// -/// Adds a new item to the roster without sending any subscription requests. +/// Adds a new item the roster without sending any subscription requests. /// /// As a result, the server will initiate a roster push, causing the /// itemAdded() or itemChanged() signal to be emitted. /// /// \param bareJid -/// \param name Optional name for the item. +/// \param name Optotional name for the item. /// \param groups Optional groups for the item. /// bool QXmppRosterManager::addItem(const QString &bareJid, const QString &name, const QSet &groups) diff --git a/src/client/QXmppRosterManager.h b/src/client/QXmppRosterManager.h index be4f45d6..f3629342 100644 --- a/src/client/QXmppRosterManager.h +++ b/src/client/QXmppRosterManager.h @@ -19,7 +19,7 @@ #include template -class QFuture; +class QXmppTask; class QXmppRosterManagerPrivate; /// @@ -73,11 +73,11 @@ public: QXmppPresence getPresence(const QString &bareJid, const QString &resource) const; - QFuture addRosterItem(const QString &bareJid, const QString &name = {}, const QSet &groups = {}); - QFuture removeRosterItem(const QString &bareJid); - QFuture renameRosterItem(const QString &bareJid, const QString &name); - QFuture subscribeTo(const QString &bareJid, const QString &reason = {}); - QFuture unsubscribeFrom(const QString &bareJid, const QString &reason = {}); + QXmppTask addRosterItem(const QString &bareJid, const QString &name = {}, const QSet &groups = {}); + QXmppTask removeRosterItem(const QString &bareJid); + QXmppTask renameRosterItem(const QString &bareJid, const QString &name); + QXmppTask subscribeTo(const QString &bareJid, const QString &reason = {}); + QXmppTask unsubscribeFrom(const QString &bareJid, const QString &reason = {}); /// \cond bool handleStanza(const QDomElement &element) override; diff --git a/src/client/QXmppTrustManager.cpp b/src/client/QXmppTrustManager.cpp index a5031a52..2772a4a5 100644 --- a/src/client/QXmppTrustManager.cpp +++ b/src/client/QXmppTrustManager.cpp @@ -5,6 +5,8 @@ #include "QXmppTrustManager.h" #include "QXmppFutureUtils_p.h" +#include "QXmppPromise.h" +#include "QXmppTask.h" #include "QXmppTrustStorage.h" using namespace QXmpp; @@ -40,7 +42,7 @@ QXmppTrustManager::~QXmppTrustManager() = default; /// \param encryption encryption protocol namespace /// \param securityPolicy security policy being applied /// -QFuture QXmppTrustManager::setSecurityPolicy(const QString &encryption, TrustSecurityPolicy securityPolicy) +QXmppTask QXmppTrustManager::setSecurityPolicy(const QString &encryption, TrustSecurityPolicy securityPolicy) { return m_trustStorage->setSecurityPolicy(encryption, securityPolicy); } @@ -50,7 +52,7 @@ QFuture QXmppTrustManager::setSecurityPolicy(const QString &encryption, Tr /// /// \param encryption encryption protocol namespace /// -QFuture QXmppTrustManager::resetSecurityPolicy(const QString &encryption) +QXmppTask QXmppTrustManager::resetSecurityPolicy(const QString &encryption) { return m_trustStorage->resetSecurityPolicy(encryption); } @@ -62,7 +64,7 @@ QFuture QXmppTrustManager::resetSecurityPolicy(const QString &encryption) /// /// \return the set security policy /// -QFuture QXmppTrustManager::securityPolicy(const QString &encryption) +QXmppTask QXmppTrustManager::securityPolicy(const QString &encryption) { return m_trustStorage->securityPolicy(encryption); } @@ -74,7 +76,7 @@ QFuture QXmppTrustManager::securityPolicy(const QString &en /// \param encryption encryption protocol namespace /// \param keyId ID of the key /// -QFuture QXmppTrustManager::setOwnKey(const QString &encryption, const QByteArray &keyId) +QXmppTask QXmppTrustManager::setOwnKey(const QString &encryption, const QByteArray &keyId) { return m_trustStorage->setOwnKey(encryption, keyId); } @@ -85,7 +87,7 @@ QFuture QXmppTrustManager::setOwnKey(const QString &encryption, const QByt /// /// \param encryption encryption protocol namespace /// -QFuture QXmppTrustManager::resetOwnKey(const QString &encryption) +QXmppTask QXmppTrustManager::resetOwnKey(const QString &encryption) { return m_trustStorage->resetOwnKey(encryption); } @@ -98,7 +100,7 @@ QFuture QXmppTrustManager::resetOwnKey(const QString &encryption) /// /// \return the ID of the own key /// -QFuture QXmppTrustManager::ownKey(const QString &encryption) +QXmppTask QXmppTrustManager::ownKey(const QString &encryption) { return m_trustStorage->ownKey(encryption); } @@ -111,7 +113,7 @@ QFuture QXmppTrustManager::ownKey(const QString &encryption) /// \param keyIds IDs of the keys /// \param trustLevel trust level of the keys /// -QFuture QXmppTrustManager::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, TrustLevel trustLevel) +QXmppTask QXmppTrustManager::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, TrustLevel trustLevel) { return m_trustStorage->addKeys(encryption, keyOwnerJid, keyIds, trustLevel); } @@ -122,7 +124,7 @@ QFuture QXmppTrustManager::addKeys(const QString &encryption, const QStrin /// \param encryption encryption protocol namespace /// \param keyIds IDs of the keys /// -QFuture QXmppTrustManager::removeKeys(const QString &encryption, const QList &keyIds) +QXmppTask QXmppTrustManager::removeKeys(const QString &encryption, const QList &keyIds) { return m_trustStorage->removeKeys(encryption, keyIds); } @@ -133,7 +135,7 @@ QFuture QXmppTrustManager::removeKeys(const QString &encryption, const QLi /// \param encryption encryption protocol namespace /// \param keyOwnerJid key owner's bare JID /// -QFuture QXmppTrustManager::removeKeys(const QString &encryption, const QString &keyOwnerJid) +QXmppTask QXmppTrustManager::removeKeys(const QString &encryption, const QString &keyOwnerJid) { return m_trustStorage->removeKeys(encryption, keyOwnerJid); } @@ -143,7 +145,7 @@ QFuture QXmppTrustManager::removeKeys(const QString &encryption, const QSt /// /// \param encryption encryption protocol namespace /// -QFuture QXmppTrustManager::removeKeys(const QString &encryption) +QXmppTask QXmppTrustManager::removeKeys(const QString &encryption) { return m_trustStorage->removeKeys(encryption); } @@ -159,7 +161,7 @@ QFuture QXmppTrustManager::removeKeys(const QString &encryption) /// /// \return the key owner JIDs mapped to their keys with specific trust levels /// -QFuture>> QXmppTrustManager::keys(const QString &encryption, QXmpp::TrustLevels trustLevels) +QXmppTask>> QXmppTrustManager::keys(const QString &encryption, QXmpp::TrustLevels trustLevels) { return m_trustStorage->keys(encryption, trustLevels); } @@ -177,7 +179,7 @@ QFuture>> QXmppTrustMan /// /// \return the key IDs mapped to their trust levels for specific key owners /// -QFuture>> QXmppTrustManager::keys(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevels trustLevels) +QXmppTask>> QXmppTrustManager::keys(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevels trustLevels) { return m_trustStorage->keys(encryption, keyOwnerJids, trustLevels); } @@ -192,7 +194,7 @@ QFuture>> QXmppTrustManager: /// /// \return whether a key of the key owner with a passed trust level is stored /// -QFuture QXmppTrustManager::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) +QXmppTask QXmppTrustManager::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) { return m_trustStorage->hasKey(encryption, keyOwnerJid, trustLevels); } @@ -206,17 +208,17 @@ QFuture QXmppTrustManager::hasKey(const QString &encryption, const QString /// \param keyIds key owners' bare JIDs mapped to the IDs of their keys /// \param trustLevel trust level being set /// -QFuture QXmppTrustManager::setTrustLevel(const QString &encryption, const QMultiHash &keyIds, TrustLevel trustLevel) +QXmppTask QXmppTrustManager::setTrustLevel(const QString &encryption, const QMultiHash &keyIds, TrustLevel trustLevel) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise promise; auto future = m_trustStorage->setTrustLevel(encryption, keyIds, trustLevel); - await(future, this, [=](QHash> modifiedKeys) mutable { + future.then(this, [=](QHash> modifiedKeys) mutable { Q_EMIT trustLevelsChanged(modifiedKeys); - interface.reportFinished(); + promise.finish(); }); - return interface.future(); + return promise.task(); } /// @@ -227,17 +229,16 @@ QFuture QXmppTrustManager::setTrustLevel(const QString &encryption, const /// \param oldTrustLevel trust level being changed /// \param newTrustLevel trust level being set /// -QFuture QXmppTrustManager::setTrustLevel(const QString &encryption, const QList &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) +QXmppTask QXmppTrustManager::setTrustLevel(const QString &encryption, const QList &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise promise; + m_trustStorage->setTrustLevel(encryption, keyOwnerJids, oldTrustLevel, newTrustLevel) + .then(this, [=](QHash> modifiedKeys) mutable { + Q_EMIT trustLevelsChanged(modifiedKeys); + promise.finish(); + }); - auto future = m_trustStorage->setTrustLevel(encryption, keyOwnerJids, oldTrustLevel, newTrustLevel); - await(future, this, [=](QHash> modifiedKeys) mutable { - Q_EMIT trustLevelsChanged(modifiedKeys); - interface.reportFinished(); - }); - - return interface.future(); + return promise.task(); } /// @@ -251,7 +252,7 @@ QFuture QXmppTrustManager::setTrustLevel(const QString &encryption, const /// /// \return the key's trust level /// -QFuture QXmppTrustManager::trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) +QXmppTask QXmppTrustManager::trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) { return m_trustStorage->trustLevel(encryption, keyOwnerJid, keyId); } @@ -261,7 +262,7 @@ QFuture QXmppTrustManager::trustLevel(const QString &encryption, con /// /// \param encryption encryption protocol namespace /// -QFuture QXmppTrustManager::resetAll(const QString &encryption) +QXmppTask QXmppTrustManager::resetAll(const QString &encryption) { return m_trustStorage->resetAll(encryption); } diff --git a/src/client/QXmppTrustManager.h b/src/client/QXmppTrustManager.h index 456a2036..d9fc8f23 100644 --- a/src/client/QXmppTrustManager.h +++ b/src/client/QXmppTrustManager.h @@ -9,7 +9,8 @@ #include "QXmppTrustLevel.h" #include "QXmppTrustSecurityPolicy.h" -#include +template +class QXmppTask; class QXmppTrustStorage; @@ -21,27 +22,27 @@ public: QXmppTrustManager(QXmppTrustStorage *trustStorage); ~QXmppTrustManager(); - QFuture setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy); - QFuture resetSecurityPolicy(const QString &encryption); - QFuture securityPolicy(const QString &encryption); + QXmppTask setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy); + QXmppTask resetSecurityPolicy(const QString &encryption); + QXmppTask securityPolicy(const QString &encryption); - QFuture setOwnKey(const QString &encryption, const QByteArray &keyId); - QFuture resetOwnKey(const QString &encryption); - QFuture ownKey(const QString &encryption); + QXmppTask setOwnKey(const QString &encryption, const QByteArray &keyId); + QXmppTask resetOwnKey(const QString &encryption); + QXmppTask ownKey(const QString &encryption); - QFuture addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted); - QFuture removeKeys(const QString &encryption, const QList &keyIds); - QFuture removeKeys(const QString &encryption, const QString &keyOwnerJid); - QFuture removeKeys(const QString &encryption); - QFuture>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}); - QFuture>> keys(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}); - QFuture hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels); + QXmppTask addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted); + QXmppTask removeKeys(const QString &encryption, const QList &keyIds); + QXmppTask removeKeys(const QString &encryption, const QString &keyOwnerJid); + QXmppTask removeKeys(const QString &encryption); + QXmppTask>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}); + QXmppTask>> keys(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}); + QXmppTask hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels); - QFuture setTrustLevel(const QString &encryption, const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel); - QFuture setTrustLevel(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel); - QFuture trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId); + QXmppTask setTrustLevel(const QString &encryption, const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel); + QXmppTask setTrustLevel(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel); + QXmppTask trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId); - QFuture resetAll(const QString &encryption); + QXmppTask resetAll(const QString &encryption); Q_SIGNAL void trustLevelsChanged(const QHash> &modifiedKeys); diff --git a/src/client/QXmppTrustMemoryStorage.cpp b/src/client/QXmppTrustMemoryStorage.cpp index aca9dcb9..29762bb0 100644 --- a/src/client/QXmppTrustMemoryStorage.cpp +++ b/src/client/QXmppTrustMemoryStorage.cpp @@ -53,42 +53,42 @@ QXmppTrustMemoryStorage::QXmppTrustMemoryStorage() QXmppTrustMemoryStorage::~QXmppTrustMemoryStorage() = default; /// \cond -QFuture QXmppTrustMemoryStorage::setSecurityPolicy(const QString &encryption, TrustSecurityPolicy securityPolicy) +QXmppTask QXmppTrustMemoryStorage::setSecurityPolicy(const QString &encryption, TrustSecurityPolicy securityPolicy) { d->securityPolicies.insert(encryption, securityPolicy); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppTrustMemoryStorage::resetSecurityPolicy(const QString &encryption) +QXmppTask QXmppTrustMemoryStorage::resetSecurityPolicy(const QString &encryption) { d->securityPolicies.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppTrustMemoryStorage::securityPolicy(const QString &encryption) +QXmppTask QXmppTrustMemoryStorage::securityPolicy(const QString &encryption) { - return makeReadyFuture(std::move(d->securityPolicies.value(encryption))); + return makeReadyTask(std::move(d->securityPolicies.value(encryption))); } -QFuture QXmppTrustMemoryStorage::setOwnKey(const QString &encryption, const QByteArray &keyId) +QXmppTask QXmppTrustMemoryStorage::setOwnKey(const QString &encryption, const QByteArray &keyId) { d->ownKeys.insert(encryption, keyId); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppTrustMemoryStorage::resetOwnKey(const QString &encryption) +QXmppTask QXmppTrustMemoryStorage::resetOwnKey(const QString &encryption) { d->ownKeys.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppTrustMemoryStorage::ownKey(const QString &encryption) +QXmppTask QXmppTrustMemoryStorage::ownKey(const QString &encryption) { auto key = d->ownKeys[encryption]; - return makeReadyFuture(std::move(key)); + return makeReadyTask(std::move(key)); } -QFuture QXmppTrustMemoryStorage::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, TrustLevel trustLevel) +QXmppTask QXmppTrustMemoryStorage::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, TrustLevel trustLevel) { for (const auto &keyId : keyIds) { Key key; @@ -98,10 +98,10 @@ QFuture QXmppTrustMemoryStorage::addKeys(const QString &encryption, const d->keys.insert(encryption, key); } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QList &keyIds) +QXmppTask QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QList &keyIds) { for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption;) { @@ -112,10 +112,10 @@ QFuture QXmppTrustMemoryStorage::removeKeys(const QString &encryption, con } } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QString &keyOwnerJid) +QXmppTask QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QString &keyOwnerJid) { for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption;) { @@ -126,16 +126,16 @@ QFuture QXmppTrustMemoryStorage::removeKeys(const QString &encryption, con } } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppTrustMemoryStorage::removeKeys(const QString &encryption) +QXmppTask QXmppTrustMemoryStorage::removeKeys(const QString &encryption) { d->keys.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture>> QXmppTrustMemoryStorage::keys(const QString &encryption, TrustLevels trustLevels) +QXmppTask>> QXmppTrustMemoryStorage::keys(const QString &encryption, TrustLevels trustLevels) { QHash> keys; @@ -147,10 +147,10 @@ QFuture>> QXmppTrustMemoryStor } } - return makeReadyFuture(std::move(keys)); + return makeReadyTask(std::move(keys)); } -QFuture>> QXmppTrustMemoryStorage::keys(const QString &encryption, const QList &keyOwnerJids, TrustLevels trustLevels) +QXmppTask>> QXmppTrustMemoryStorage::keys(const QString &encryption, const QList &keyOwnerJids, TrustLevels trustLevels) { QHash> keys; @@ -163,22 +163,22 @@ QFuture>> QXmppTrustMemoryStorage:: } } - return makeReadyFuture(std::move(keys)); + return makeReadyTask(std::move(keys)); } -QFuture QXmppTrustMemoryStorage::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) +QXmppTask QXmppTrustMemoryStorage::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) { const auto storedKeys = d->keys.values(encryption); for (const auto &key : storedKeys) { if (key.ownerJid == keyOwnerJid && trustLevels.testFlag(key.trustLevel)) { - return makeReadyFuture(std::move(true)); + return makeReadyTask(std::move(true)); } } - return makeReadyFuture(std::move(false)); + return makeReadyTask(std::move(false)); } -QFuture>> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QMultiHash &keyIds, TrustLevel trustLevel) +QXmppTask>> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QMultiHash &keyIds, TrustLevel trustLevel) { QHash> modifiedKeys; @@ -215,10 +215,10 @@ QFuture>> QXmppTrustMemoryStorage } } - return makeReadyFuture(std::move(modifiedKeys)); + return makeReadyTask(std::move(modifiedKeys)); } -QFuture>> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QList &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) +QXmppTask>> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QList &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) { QHash> modifiedKeys; @@ -231,27 +231,27 @@ QFuture>> QXmppTrustMemoryStorage } } - return makeReadyFuture(std::move(modifiedKeys)); + return makeReadyTask(std::move(modifiedKeys)); } -QFuture QXmppTrustMemoryStorage::trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) +QXmppTask QXmppTrustMemoryStorage::trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) { const auto keys = d->keys.values(encryption); for (const auto &key : keys) { if (key.id == keyId && key.ownerJid == keyOwnerJid) { - return makeReadyFuture(std::move(TrustLevel(key.trustLevel))); + return makeReadyTask(std::move(TrustLevel(key.trustLevel))); } } - return makeReadyFuture(std::move(TrustLevel::Undecided)); + return makeReadyTask(std::move(TrustLevel::Undecided)); } -QFuture QXmppTrustMemoryStorage::resetAll(const QString &encryption) +QXmppTask QXmppTrustMemoryStorage::resetAll(const QString &encryption) { d->securityPolicies.remove(encryption); d->ownKeys.remove(encryption); d->keys.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } /// \endcond diff --git a/src/client/QXmppTrustMemoryStorage.h b/src/client/QXmppTrustMemoryStorage.h index f5e92569..53c70aa7 100644 --- a/src/client/QXmppTrustMemoryStorage.h +++ b/src/client/QXmppTrustMemoryStorage.h @@ -18,27 +18,27 @@ public: ~QXmppTrustMemoryStorage(); /// \cond - QFuture setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy) override; - QFuture resetSecurityPolicy(const QString &encryption) override; - QFuture securityPolicy(const QString &encryption) override; - - QFuture setOwnKey(const QString &encryption, const QByteArray &keyId) override; - QFuture resetOwnKey(const QString &encryption) override; - QFuture ownKey(const QString &encryption) override; - - QFuture addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted) override; - QFuture removeKeys(const QString &encryption, const QList &keyIds) override; - QFuture removeKeys(const QString &encryption, const QString &keyOwnerJid) override; - QFuture removeKeys(const QString &encryption) override; - QFuture>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}) override; - QFuture>> keys(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}) override; - QFuture hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) override; - - QFuture>> setTrustLevel(const QString &encryption, const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel) override; - QFuture>> setTrustLevel(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel) override; - QFuture trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) override; - - QFuture resetAll(const QString &encryption) override; + QXmppTask setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy) override; + QXmppTask resetSecurityPolicy(const QString &encryption) override; + QXmppTask securityPolicy(const QString &encryption) override; + + QXmppTask setOwnKey(const QString &encryption, const QByteArray &keyId) override; + QXmppTask resetOwnKey(const QString &encryption) override; + QXmppTask ownKey(const QString &encryption) override; + + QXmppTask addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted) override; + QXmppTask removeKeys(const QString &encryption, const QList &keyIds) override; + QXmppTask removeKeys(const QString &encryption, const QString &keyOwnerJid) override; + QXmppTask removeKeys(const QString &encryption) override; + QXmppTask>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}) override; + QXmppTask>> keys(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}) override; + QXmppTask hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) override; + + QXmppTask>> setTrustLevel(const QString &encryption, const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel) override; + QXmppTask>> setTrustLevel(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel) override; + QXmppTask trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) override; + + QXmppTask resetAll(const QString &encryption) override; /// \endcond private: diff --git a/src/client/QXmppTrustStorage.h b/src/client/QXmppTrustStorage.h index 0edc92a4..65c46e36 100644 --- a/src/client/QXmppTrustStorage.h +++ b/src/client/QXmppTrustStorage.h @@ -9,34 +9,35 @@ #include "QXmppTrustLevel.h" #include "QXmppTrustSecurityPolicy.h" -#include +template +class QXmppTask; class QXMPP_EXPORT QXmppTrustStorage { public: virtual ~QXmppTrustStorage() = default; - virtual QFuture setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy) = 0; - virtual QFuture resetSecurityPolicy(const QString &encryption) = 0; - virtual QFuture securityPolicy(const QString &encryption) = 0; + virtual QXmppTask setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy) = 0; + virtual QXmppTask resetSecurityPolicy(const QString &encryption) = 0; + virtual QXmppTask securityPolicy(const QString &encryption) = 0; - virtual QFuture setOwnKey(const QString &encryption, const QByteArray &keyId) = 0; - virtual QFuture resetOwnKey(const QString &encryption) = 0; - virtual QFuture ownKey(const QString &encryption) = 0; + virtual QXmppTask setOwnKey(const QString &encryption, const QByteArray &keyId) = 0; + virtual QXmppTask resetOwnKey(const QString &encryption) = 0; + virtual QXmppTask ownKey(const QString &encryption) = 0; - virtual QFuture addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted) = 0; - virtual QFuture removeKeys(const QString &encryption, const QList &keyIds) = 0; - virtual QFuture removeKeys(const QString &encryption, const QString &keyOwnerJid) = 0; - virtual QFuture removeKeys(const QString &encryption) = 0; - virtual QFuture>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}) = 0; - virtual QFuture>> keys(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}) = 0; - virtual QFuture hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) = 0; + virtual QXmppTask addKeys(const QString &encryption, const QString &keyOwnerJid, const QList &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted) = 0; + virtual QXmppTask removeKeys(const QString &encryption, const QList &keyIds) = 0; + virtual QXmppTask removeKeys(const QString &encryption, const QString &keyOwnerJid) = 0; + virtual QXmppTask removeKeys(const QString &encryption) = 0; + virtual QXmppTask>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}) = 0; + virtual QXmppTask>> keys(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}) = 0; + virtual QXmppTask hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) = 0; - virtual QFuture>> setTrustLevel(const QString &encryption, const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel) = 0; - virtual QFuture>> setTrustLevel(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel) = 0; - virtual QFuture trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) = 0; + virtual QXmppTask>> setTrustLevel(const QString &encryption, const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel) = 0; + virtual QXmppTask>> setTrustLevel(const QString &encryption, const QList &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel) = 0; + virtual QXmppTask trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) = 0; - virtual QFuture resetAll(const QString &encryption) = 0; + virtual QXmppTask resetAll(const QString &encryption) = 0; }; #endif // QXMPPTRUSTSTORAGE_H diff --git a/src/client/QXmppUploadRequestManager.cpp b/src/client/QXmppUploadRequestManager.cpp index 17a58893..4a45d86b 100644 --- a/src/client/QXmppUploadRequestManager.cpp +++ b/src/client/QXmppUploadRequestManager.cpp @@ -185,7 +185,7 @@ QString QXmppUploadRequestManager::requestUploadSlot(const QString &fileName, /// \since QXmpp 1.5 /// auto QXmppUploadRequestManager::requestSlot(const QFileInfo &file, - const QString &uploadService) -> QFuture + const QString &uploadService) -> QXmppTask { return requestSlot(file, file.fileName(), uploadService); } @@ -206,7 +206,7 @@ auto QXmppUploadRequestManager::requestSlot(const QFileInfo &file, /// auto QXmppUploadRequestManager::requestSlot(const QFileInfo &file, const QString &customFileName, - const QString &uploadService) -> QFuture + const QString &uploadService) -> QXmppTask { return requestSlot(customFileName, file.size(), QMimeDatabase().mimeTypeForFile(file), @@ -233,12 +233,12 @@ auto QXmppUploadRequestManager::requestSlot(const QFileInfo &file, auto QXmppUploadRequestManager::requestSlot(const QString &fileName, qint64 fileSize, const QMimeType &mimeType, - const QString &uploadService) -> QFuture + const QString &uploadService) -> QXmppTask { if (!serviceFound() && uploadService.isEmpty()) { using Error = QXmppStanza::Error; const auto errorMessage = QStringLiteral("Couldn't request upload slot: No service found."); - return makeReadyFuture(SlotResult(Error(Error::Cancel, Error::FeatureNotImplemented, errorMessage))); + return makeReadyTask(SlotResult(Error(Error::Cancel, Error::FeatureNotImplemented, errorMessage))); } QXmppHttpUploadRequestIq iq; diff --git a/src/client/QXmppUploadRequestManager.h b/src/client/QXmppUploadRequestManager.h index 60a8da1e..e5ed752c 100644 --- a/src/client/QXmppUploadRequestManager.h +++ b/src/client/QXmppUploadRequestManager.h @@ -13,7 +13,7 @@ class QFileInfo; template -class QFuture; +class QXmppTask; class QMimeType; class QXmppHttpUploadRequestIq; class QXmppHttpUploadSlotIq; @@ -98,15 +98,15 @@ public: const QString &uploadService = QString()); using SlotResult = std::variant; - QFuture requestSlot(const QFileInfo &file, - const QString &uploadService = {}); - QFuture requestSlot(const QFileInfo &file, - const QString &customFileName, - const QString &uploadService = {}); - QFuture requestSlot(const QString &fileName, - qint64 fileSize, - const QMimeType &mimeType, - const QString &uploadService = {}); + QXmppTask requestSlot(const QFileInfo &file, + const QString &uploadService = {}); + QXmppTask requestSlot(const QFileInfo &file, + const QString &customFileName, + const QString &uploadService = {}); + QXmppTask requestSlot(const QString &fileName, + qint64 fileSize, + const QMimeType &mimeType, + const QString &uploadService = {}); bool serviceFound() const; diff --git a/src/client/QXmppUserLocationManager.cpp b/src/client/QXmppUserLocationManager.cpp index cf35013e..90c79dea 100644 --- a/src/client/QXmppUserLocationManager.cpp +++ b/src/client/QXmppUserLocationManager.cpp @@ -77,7 +77,7 @@ QStringList QXmppUserLocationManager::discoveryFeatures() const /// \param jid The account JID to request. /// auto QXmppUserLocationManager::request(const QString &jid) - -> QFuture + -> QXmppTask { return Pep::request(pubSub(client()), jid, ns_geoloc, this); } @@ -88,7 +88,7 @@ auto QXmppUserLocationManager::request(const QString &jid) /// \param item The User Location item to be published. /// auto QXmppUserLocationManager::publish(const QXmppGeolocItem &item) - -> QFuture + -> QXmppTask { return pubSub(client())->publishOwnPepItem(ns_geoloc, item); } diff --git a/src/client/QXmppUserLocationManager.h b/src/client/QXmppUserLocationManager.h index bc455d86..f9db4bc1 100644 --- a/src/client/QXmppUserLocationManager.h +++ b/src/client/QXmppUserLocationManager.h @@ -12,7 +12,7 @@ #include template -class QFuture; +class QXmppTask; class QXmppGeolocItem; class QXMPP_EXPORT QXmppUserLocationManager : public QXmppClientExtension, public QXmppPubSubEventHandler @@ -28,8 +28,8 @@ public: QStringList discoveryFeatures() const override; - QFuture request(const QString &jid); - QFuture publish(const Item &); + QXmppTask request(const QString &jid); + QXmppTask publish(const Item &); Q_SIGNAL void itemReceived(const QString &jid, const QXmppGeolocItem &); diff --git a/src/client/QXmppUserTuneManager.cpp b/src/client/QXmppUserTuneManager.cpp index e0023416..ab46db64 100644 --- a/src/client/QXmppUserTuneManager.cpp +++ b/src/client/QXmppUserTuneManager.cpp @@ -78,7 +78,7 @@ QStringList QXmppUserTuneManager::discoveryFeatures() const /// \param jid The account JID to request. /// auto QXmppUserTuneManager::request(const QString &jid) - -> QFuture + -> QXmppTask { return Pep::request(pubSub(client()), jid, ns_tune, this); } @@ -89,7 +89,7 @@ auto QXmppUserTuneManager::request(const QString &jid) /// \param item The User Tune item to be published. /// auto QXmppUserTuneManager::publish(const QXmppTuneItem &item) - -> QFuture + -> QXmppTask { return pubSub(client())->publishOwnPepItem(ns_tune, item); } diff --git a/src/client/QXmppUserTuneManager.h b/src/client/QXmppUserTuneManager.h index b25d1b00..90bc2d25 100644 --- a/src/client/QXmppUserTuneManager.h +++ b/src/client/QXmppUserTuneManager.h @@ -12,7 +12,7 @@ class QXmppTuneItem; template -class QFuture; +class QXmppTask; class QXMPP_EXPORT QXmppUserTuneManager : public QXmppClientExtension, public QXmppPubSubEventHandler { @@ -27,8 +27,8 @@ public: QStringList discoveryFeatures() const override; - QFuture request(const QString &jid); - QFuture publish(const QXmppTuneItem &); + QXmppTask request(const QString &jid); + QXmppTask publish(const QXmppTuneItem &); Q_SIGNAL void itemReceived(const QString &jid, const QXmppTuneItem &item); 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)); } 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 load(); - QFuture setUp(); + QXmppTask load(); + QXmppTask setUp(); - QFuture ownKey(); - QFuture>> keys(QXmpp::TrustLevels trustLevels = {}); - QFuture>> keys(const QList &jids, QXmpp::TrustLevels trustLevels = {}); + QXmppTask ownKey(); + QXmppTask>> keys(QXmpp::TrustLevels trustLevels = {}); + QXmppTask>> keys(const QList &jids, QXmpp::TrustLevels trustLevels = {}); - QFuture changeDeviceLabel(const QString &deviceLabel = {}); + QXmppTask changeDeviceLabel(const QString &deviceLabel = {}); int maximumDevicesPerJid() const; void setMaximumDevicesPerJid(int maximum); @@ -97,14 +96,14 @@ public: int maximumDevicesPerStanza() const; void setMaximumDevicesPerStanza(int maximum); - QFuture> requestDeviceLists(const QList &jids); - QFuture> subscribeToDeviceLists(const QList &jids); - QFuture> unsubscribeFromDeviceLists(); + QXmppTask> requestDeviceLists(const QList &jids); + QXmppTask> subscribeToDeviceLists(const QList &jids); + QXmppTask> unsubscribeFromDeviceLists(); QXmppOmemoOwnDevice ownDevice(); - QFuture> devices(); - QFuture> devices(const QList &jids); - QFuture removeContactDevices(const QString &jid); + QXmppTask> devices(); + QXmppTask> devices(const QList &jids); + QXmppTask removeContactDevices(const QString &jid); void setAcceptedSessionBuildingTrustLevels(QXmpp::TrustLevels trustLevels); QXmpp::TrustLevels acceptedSessionBuildingTrustLevels(); @@ -112,23 +111,23 @@ public: void setNewDeviceAutoSessionBuildingEnabled(bool isNewDeviceAutoSessionBuildingEnabled); bool isNewDeviceAutoSessionBuildingEnabled(); - QFuture buildMissingSessions(const QList &jids); + QXmppTask buildMissingSessions(const QList &jids); - QFuture resetOwnDevice(); - QFuture resetAll(); + QXmppTask resetOwnDevice(); + QXmppTask resetAll(); - QFuture setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy); - QFuture securityPolicy(); + QXmppTask setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy); + QXmppTask securityPolicy(); - QFuture setTrustLevel(const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel); - QFuture trustLevel(const QString &keyOwnerJid, const QByteArray &keyId); + QXmppTask setTrustLevel(const QMultiHash &keyIds, QXmpp::TrustLevel trustLevel); + QXmppTask trustLevel(const QString &keyOwnerJid, const QByteArray &keyId); /// \cond - QFuture encryptMessage(QXmppMessage &&message, const std::optional ¶ms) override; - QFuture decryptMessage(QXmppMessage &&message) override; + QXmppTask encryptMessage(QXmppMessage &&message, const std::optional ¶ms) override; + QXmppTask decryptMessage(QXmppMessage &&message) override; - QFuture encryptIq(QXmppIq &&iq, const std::optional ¶ms) override; - QFuture decryptIq(const QDomElement &element) override; + QXmppTask encryptIq(QXmppIq &&iq, const std::optional ¶ms) override; + QXmppTask 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 ManagerPrivate::setUpDeviceId() +QXmppTask ManagerPrivate::setUpDeviceId() { auto future = pubSubManager->requestOwnPepItemIds(ns_omemo_2_bundles); - return chain(future, q, [this](QXmppPubSubManager::ItemIdsResult result) mutable { + return chain(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 ManagerPrivate::encryptMessageForRecipients(QXmppMessage &&message, QVector recipientJids, TrustLevels acceptedTrustLevels) +QXmppTask ManagerPrivate::encryptMessageForRecipients(QXmppMessage &&message, QVector recipientJids, TrustLevels acceptedTrustLevels) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 omemoElement) mutable { + future.then(q, [=, message = std::move(message)](std::optional 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 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 ManagerPrivate::encryptMessage // successful, otherwise none // template -QFuture> ManagerPrivate::encryptStanza(const T &stanza, const QVector &recipientJids, TrustLevels acceptedTrustLevels) +QXmppTask> ManagerPrivate::encryptStanza(const T &stanza, const QVector &recipientJids, TrustLevels acceptedTrustLevels) { Q_ASSERT_X(!recipientJids.isEmpty(), "Creating OMEMO envelope", "OMEMO element could not be created because no recipient JIDs are passed"); - QFutureInterface> interface(QFutureInterfaceBase::Started); + QXmppPromise> interface; if (const auto optionalPayloadEncryptionResult = encryptPayload(createSceEnvelope(stanza))) { const auto &payloadEncryptionResult = *optionalPayloadEncryptionResult; @@ -1141,7 +1141,7 @@ QFuture> 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> 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> ManagerPrivate::encryptStanza(const T // determined and the session built. if (device.keyId.isEmpty()) { auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=](std::optional optionalDeviceBundle) mutable { + future.then(q, [=](std::optional 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> 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> 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> ManagerPrivate::encryptStanza(const T // Otherwise, use the existing session. if (device.session.isEmpty()) { auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=](std::optional optionalDeviceBundle) mutable { + future.then(q, [=](std::optional optionalDeviceBundle) mutable { if (optionalDeviceBundle) { const auto &deviceBundle = *optionalDeviceBundle; buildSessionDependingOnTrustLevel(deviceBundle, trustLevel); @@ -1284,18 +1284,18 @@ QFuture> 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> ManagerPrivate::encryptStanza(const QXmppIq &, const QVector &, TrustLevels); -template QFuture> ManagerPrivate::encryptStanza(const QXmppMessage &, const QVector &, TrustLevels); +template QXmppTask> ManagerPrivate::encryptStanza(const QXmppIq &, const QVector &, TrustLevels); +template QXmppTask> ManagerPrivate::encryptStanza(const QXmppMessage &, const QVector &, 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> ManagerPrivate::decryptMessage(QXmppMessage stanza) +QXmppTask> ManagerPrivate::decryptMessage(QXmppMessage stanza) { - QFutureInterface> interface(QFutureInterfaceBase::Started); + QXmppPromise> interface; // At this point, the stanza has always an OMEMO element. const auto omemoElement = *stanza.omemoElement(); @@ -1460,18 +1460,20 @@ QFuture> 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 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 optionalDecryptionResult) mutable { + future.then(q, [=](std::optional optionalDecryptionResult) mutable { if (optionalDecryptionResult) { const auto decryptionResult = std::move(*optionalDecryptionResult); stanza.parseExtensions(decryptionResult.sceContent, SceSensitive); @@ -1482,15 +1484,15 @@ QFuture> 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> ManagerPrivate::decryptMessage(QXmppMessage // // \return the serialized decrypted stanza if it could be decrypted // -QFuture> ManagerPrivate::decryptIq(const QDomElement &iqElement) +QXmppTask> ManagerPrivate::decryptIq(const QDomElement &iqElement) { using Result = std::optional; @@ -1518,7 +1520,7 @@ QFuture> ManagerPrivate::decryptIq(const QDomE subscribeToNewDeviceLists(senderJid, senderDeviceId); auto future = decryptStanza(iq, senderJid, senderDeviceId, *envelope, omemoElement.payload(), false); - return chain(future, q, [iqElement](auto result) -> Result { + return chain(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> ManagerPrivate::decryptIq(const QDomE return {}; }); } - return makeReadyFuture(std::nullopt); + return makeReadyTask(std::nullopt); } // @@ -1549,15 +1551,15 @@ QFuture> ManagerPrivate::decryptIq(const QDomE // \return the result of the decryption if it succeeded // template -QFuture> ManagerPrivate::decryptStanza(T stanza, const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) +QXmppTask> ManagerPrivate::decryptStanza(T stanza, const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) { - QFutureInterface> interface(QFutureInterfaceBase::Started); + QXmppPromise> 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> 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> 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> 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> ManagerPrivate::decryptStanza(T stanza, // \return the serialized SCE envelope if it could be extracted, otherwise a // default-constructed byte array // -QFuture ManagerPrivate::extractSceEnvelope(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) +QXmppTask ManagerPrivate::extractSceEnvelope(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise interface; auto future = extractPayloadDecryptionData(senderJid, senderDeviceId, omemoEnvelope, isMessageStanza); - await(future, q, [=](QCA::SecureArray payloadDecryptionData) mutable { - if (payloadDecryptionData.isEmpty()) { + future.then(q, [=](std::optional 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 ManagerPrivate::extractSceEnvelope(const QString &senderJid, // \return the serialized payload decryption data if it could be extracted, otherwise a // default-constructed secure array // -QFuture ManagerPrivate::extractPayloadDecryptionData(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, bool isMessageStanza) +QXmppTask> ManagerPrivate::extractPayloadDecryptionData(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, bool isMessageStanza) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise> interface; SessionCipherPtr sessionCipher; const auto address = Address(senderJid, senderDeviceId); @@ -1667,7 +1672,7 @@ QFuture 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::nullopt); } session_cipher_set_version(sessionCipher.get(), CIPHERTEXT_OMEMO_VERSION); @@ -1682,7 +1687,7 @@ QFuture 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 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 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 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 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 omemoEnvelopeData; @@ -1791,32 +1796,32 @@ QFuture ManagerPrivate::extractPayloadDecryptionData(const QSt if (signal_message_deserialize_omemo(omemoEnvelopeData.ptrRef(), reinterpret_cast(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 ManagerPrivate::publishOmemoData() +QXmppTask ManagerPrivate::publishOmemoData() { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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(&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>(result); @@ -1904,13 +1909,13 @@ QFuture 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(&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>(result); @@ -1943,11 +1948,11 @@ QFuture 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 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> ManagerPrivate::requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const +QXmppTask> ManagerPrivate::requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const { - QFutureInterface> interface(QFutureInterfaceBase::Started); + QXmppPromise> interface; auto future = pubSubManager->requestItem(deviceOwnerJid, ns_omemo_2_bundles, QString::number(deviceId)); - await(future, q, [=](QXmppPubSubManager::ItemResult result) mutable { + future.then(q, [=](QXmppPubSubManager::ItemResult result) mutable { if (const auto error = std::get_if(&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(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(ns_omemo_2_devices, QXmppPubSubManager::Current); - await(future, q, [=](QXmppPubSubManager::ItemResult result) mutable { + future.then(q, [=](QXmppPubSubManager::ItemResult result) mutable { if (const auto error = std::get_if(&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(&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(&result)) { warning("Features of PEP service '" % deviceOwnerJid % "' could not be retrieved: " % errorToString(*error)); @@ -2979,7 +2984,7 @@ template 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(&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 -void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QFuture future, const QString &errorMessage, Function continuation) +void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QXmppTask 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(&result)) { warning(errorMessage % u": " % errorToString(*error)); continuation(false); @@ -3053,24 +3058,24 @@ void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QFuture future, } // See QXmppOmemoManager for documentation -QFuture ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) +QXmppTask ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) // // \return the result of the request // -QFuture> ManagerPrivate::requestDeviceList(const QString &jid) +QXmppTask> ManagerPrivate::requestDeviceList(const QString &jid) { auto future = pubSubManager->requestItem(jid, ns_omemo_2_devices, QXmppPubSubManager::Current); - await(future, q, [this, jid](QXmppPubSubManager::ItemResult result) mutable { + future.then(q, [this, jid](QXmppPubSubManager::ItemResult result) mutable { if (const auto error = std::get_if(&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 ManagerPrivate::subscribeToDeviceList(const QString &jid) +QXmppTask ManagerPrivate::subscribeToDeviceList(const QString &jid) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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(&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 ManagerPrivate::subscribeToDeviceList(const // // \return the results of each unsubscribe request // -QFuture> ManagerPrivate::unsubscribeFromDeviceLists(const QList &jids) +QXmppTask> ManagerPrivate::unsubscribeFromDeviceLists(const QList &jids) { if (jids.isEmpty()) { - return makeReadyFuture(QVector()); + return makeReadyTask(QVector()); } - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface> interface; + QXmppPromise> interface; QVector devicesResults; }; @@ -3171,19 +3177,18 @@ QFuture> 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> ManagerPrivate::unsubscribeFromDeviceLi // // \return the result of the unsubscription // -QFuture ManagerPrivate::unsubscribeFromDeviceList(const QString &jid) +QXmppTask ManagerPrivate::unsubscribeFromDeviceList(const QString &jid) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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(&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 ManagerPrivate::resetOwnDevice() +QXmppTask ManagerPrivate::resetOwnDevice() { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 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 ManagerPrivate::resetAll() +QXmppTask ManagerPrivate::resetAll() { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 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 ManagerPrivate::resetAll() // \return true if a session could be built or it is not enabled, otherwise // false // -QFuture ManagerPrivate::buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) +QXmppTask 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 ManagerPrivate::buildSessionForNewDevice(const QString &jid, uint3 // // \return whether a session could be built // -QFuture ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) +QXmppTask ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise interface; auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=, &device](std::optional optionalDeviceBundle) mutable { + future.then(q, [=, &device](std::optional 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 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(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 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 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 ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u // bool ManagerPrivate::buildSession(signal_protocol_address address, const QXmppOmemoDeviceBundle &deviceBundle) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 ManagerPrivate::sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange) const +QXmppTask ManagerPrivate::sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange) const { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise interface; const auto address = Address(recipientJid, recipientDeviceId); const auto decryptionData = QCA::SecureArray(EMPTY_MESSAGE_DECRYPTION_DATA_SIZE); @@ -3592,7 +3597,7 @@ QFuture 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 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 ManagerPrivate::sendEmptyMessage(const QString &recip // It corresponds to the fingerprint shown to users which also does not contain // the first byte. // -QFuture ManagerPrivate::storeOwnKey() const +QXmppTask ManagerPrivate::storeOwnKey() const { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 ManagerPrivate::storeOwnKey() const // // \return the trust level of the stored key // -QFuture ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key) +QXmppTask ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key) { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise interface; - auto awaitStoreKey = [=](const QFuture &future) mutable { - await(future, q, [=](TrustLevel trustLevel) mutable { - reportFinishedResult(interface, trustLevel); + auto awaitStoreKey = [=](QXmppTask &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 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 ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QStr } }); - return interface.future(); + return interface.task(); } // @@ -3700,17 +3705,17 @@ QFuture ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QStr // // \return the trust level of the stored key // -QFuture ManagerPrivate::storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel) const +QXmppTask ManagerPrivate::storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel) const { - QFutureInterface interface(QFutureInterfaceBase::Started); + QXmppPromise 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 setUpDeviceId(); + QXmppTask setUpDeviceId(); std::optional generateDeviceId(); std::optional generateDeviceId(const QVector &existingIds); bool setUpIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair); @@ -189,37 +190,37 @@ public: void removeDevicesRemovedFromServer(); bool generateIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair) const; - QFuture encryptMessageForRecipients(QXmppMessage &&message, - QVector recipientJids, - TrustLevels acceptedTrustLevels); + QXmppTask encryptMessageForRecipients(QXmppMessage &&message, + QVector recipientJids, + TrustLevels acceptedTrustLevels); template - QFuture> encryptStanza(const T &stanza, const QVector &recipientJids, TrustLevels acceptedTrustLevels); + QXmppTask> encryptStanza(const T &stanza, const QVector &recipientJids, TrustLevels acceptedTrustLevels); std::optional encryptPayload(const QByteArray &payload) const; template QByteArray createSceEnvelope(const T &stanza); QByteArray createOmemoEnvelopeData(const signal_protocol_address &address, const QCA::SecureArray &payloadDecryptionData) const; - QFuture> decryptMessage(QXmppMessage stanza); - QFuture> decryptIq(const QDomElement &iqElement); + QXmppTask> decryptMessage(QXmppMessage stanza); + QXmppTask> decryptIq(const QDomElement &iqElement); template - QFuture> decryptStanza(T stanza, - const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - const QByteArray &omemoPayload, - bool isMessageStanza = true); - QFuture extractSceEnvelope(const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - const QByteArray &omemoPayload, - bool isMessageStanza); - QFuture extractPayloadDecryptionData(const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - bool isMessageStanza = true); + QXmppTask> decryptStanza(T stanza, + const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + const QByteArray &omemoPayload, + bool isMessageStanza = true); + QXmppTask extractSceEnvelope(const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + const QByteArray &omemoPayload, + bool isMessageStanza); + QXmppTask> extractPayloadDecryptionData(const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + bool isMessageStanza = true); QByteArray decryptPayload(const QCA::SecureArray &payloadDecryptionData, const QByteArray &payload) const; - QFuture publishOmemoData(); + QXmppTask publishOmemoData(); template void publishDeviceBundle(bool isDeviceBundlesNodeExistent, @@ -250,7 +251,7 @@ public: template void publishDeviceBundleItemWithOptions(Function continuation); QXmppOmemoDeviceBundleItem deviceBundleItem() const; - QFuture> requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const; + QXmppTask> requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const; template void deleteDeviceBundle(Function continuation); @@ -305,21 +306,21 @@ public: void publishItem(const QString &node, const T &item, const QXmppPubSubPublishOptions &publishOptions, Function continuation); template - void runPubSubQueryWithContinuation(QFuture future, const QString &errorMessage, Function continuation); + void runPubSubQueryWithContinuation(QXmppTask future, const QString &errorMessage, Function continuation); - QFuture changeDeviceLabel(const QString &deviceLabel); + QXmppTask changeDeviceLabel(const QString &deviceLabel); - QFuture> requestDeviceList(const QString &jid); + QXmppTask> requestDeviceList(const QString &jid); void subscribeToNewDeviceLists(const QString &jid, uint32_t deviceId); - QFuture subscribeToDeviceList(const QString &jid); - QFuture> unsubscribeFromDeviceLists(const QList &jids); - QFuture unsubscribeFromDeviceList(const QString &jid); + QXmppTask subscribeToDeviceList(const QString &jid); + QXmppTask> unsubscribeFromDeviceLists(const QList &jids); + QXmppTask unsubscribeFromDeviceList(const QString &jid); - QFuture resetOwnDevice(); - QFuture resetAll(); + QXmppTask resetOwnDevice(); + QXmppTask resetAll(); - QFuture buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); - QFuture buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); + QXmppTask buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); + QXmppTask 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 sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange = false) const; - QFuture storeOwnKey() const; - QFuture storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key); - QFuture storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel = TrustLevel::AutomaticallyDistrusted) const; + QXmppTask sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange = false) const; + QXmppTask storeOwnKey() const; + QXmppTask storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key); + QXmppTask storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel = TrustLevel::AutomaticallyDistrusted) const; QString ownBareJid() const; QString ownFullJid() const; QHash 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 QXmppOmemoMemoryStorage::allData() +QXmppTask 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 QXmppOmemoMemoryStorage::setOwnDevice(const std::optional &device) +QXmppTask QXmppOmemoMemoryStorage::setOwnDevice(const std::optional &device) { d->ownDevice = device; - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppOmemoMemoryStorage::addSignedPreKeyPair(const uint32_t keyId, const SignedPreKeyPair &keyPair) +QXmppTask QXmppOmemoMemoryStorage::addSignedPreKeyPair(const uint32_t keyId, const SignedPreKeyPair &keyPair) { d->signedPreKeyPairs.insert(keyId, keyPair); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppOmemoMemoryStorage::removeSignedPreKeyPair(const uint32_t keyId) +QXmppTask QXmppOmemoMemoryStorage::removeSignedPreKeyPair(const uint32_t keyId) { d->signedPreKeyPairs.remove(keyId); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppOmemoMemoryStorage::addPreKeyPairs(const QHash &keyPairs) +QXmppTask QXmppOmemoMemoryStorage::addPreKeyPairs(const QHash &keyPairs) { d->preKeyPairs.insert(keyPairs); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppOmemoMemoryStorage::removePreKeyPair(const uint32_t keyId) +QXmppTask QXmppOmemoMemoryStorage::removePreKeyPair(const uint32_t keyId) { d->preKeyPairs.remove(keyId); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppOmemoMemoryStorage::addDevice(const QString &jid, const uint32_t deviceId, const QXmppOmemoStorage::Device &device) +QXmppTask QXmppOmemoMemoryStorage::addDevice(const QString &jid, const uint32_t deviceId, const QXmppOmemoStorage::Device &device) { d->devices[jid].insert(deviceId, device); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const uint32_t deviceId) +QXmppTask QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const uint32_t deviceId) { auto &devices = d->devices[jid]; devices.remove(deviceId); @@ -102,18 +102,18 @@ QFuture QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const ui d->devices.remove(jid); } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppOmemoMemoryStorage::removeDevices(const QString &jid) +QXmppTask QXmppOmemoMemoryStorage::removeDevices(const QString &jid) { d->devices.remove(jid); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture QXmppOmemoMemoryStorage::resetAll() +QXmppTask 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 @@ -19,21 +20,21 @@ public: ~QXmppOmemoMemoryStorage() override; /// \cond - QFuture allData() override; + QXmppTask allData() override; - QFuture setOwnDevice(const std::optional &device) override; + QXmppTask setOwnDevice(const std::optional &device) override; - QFuture addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) override; - QFuture removeSignedPreKeyPair(uint32_t keyId) override; + QXmppTask addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) override; + QXmppTask removeSignedPreKeyPair(uint32_t keyId) override; - QFuture addPreKeyPairs(const QHash &keyPairs) override; - QFuture removePreKeyPair(uint32_t keyId) override; + QXmppTask addPreKeyPairs(const QHash &keyPairs) override; + QXmppTask removePreKeyPair(uint32_t keyId) override; - QFuture addDevice(const QString &jid, uint32_t deviceId, const Device &device) override; - QFuture removeDevice(const QString &jid, uint32_t deviceId) override; - QFuture removeDevices(const QString &jid) override; + QXmppTask addDevice(const QString &jid, uint32_t deviceId, const Device &device) override; + QXmppTask removeDevice(const QString &jid, uint32_t deviceId) override; + QXmppTask removeDevices(const QString &jid) override; - QFuture resetAll() override; + QXmppTask 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 @@ -154,21 +155,21 @@ public: virtual ~QXmppOmemoStorage() = default; - virtual QFuture allData() = 0; + virtual QXmppTask allData() = 0; - virtual QFuture setOwnDevice(const std::optional &device) = 0; + virtual QXmppTask setOwnDevice(const std::optional &device) = 0; - virtual QFuture addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) = 0; - virtual QFuture removeSignedPreKeyPair(uint32_t keyId) = 0; + virtual QXmppTask addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) = 0; + virtual QXmppTask removeSignedPreKeyPair(uint32_t keyId) = 0; - virtual QFuture addPreKeyPairs(const QHash &keyPairs) = 0; - virtual QFuture removePreKeyPair(uint32_t keyId) = 0; + virtual QXmppTask addPreKeyPairs(const QHash &keyPairs) = 0; + virtual QXmppTask removePreKeyPair(uint32_t keyId) = 0; - virtual QFuture addDevice(const QString &jid, uint32_t deviceId, const Device &device) = 0; - virtual QFuture removeDevice(const QString &jid, uint32_t deviceId) = 0; - virtual QFuture removeDevices(const QString &jid) = 0; + virtual QXmppTask addDevice(const QString &jid, uint32_t deviceId, const Device &device) = 0; + virtual QXmppTask removeDevice(const QString &jid, uint32_t deviceId) = 0; + virtual QXmppTask removeDevices(const QString &jid) = 0; - virtual QFuture resetAll() = 0; + virtual QXmppTask resetAll() = 0; }; #endif // QXMPPOMEMOSTORAGE_H -- cgit v1.2.3