diff options
| author | Linus Jahn <lnj@kaidan.im> | 2022-08-16 21:00:15 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2023-01-03 22:05:54 +0100 |
| commit | b17284ee7d674416e0d11f1699f73fcc606262d4 (patch) | |
| tree | 86597f2bc2a1ed2d257e0cbf8e7de1ca54080c08 /src | |
| parent | 3271c6642439d4d3c0d8c634e2b3f4cf17b908a0 (diff) | |
| download | qxmpp-b17284ee7d674416e0d11f1699f73fcc606262d4.tar.gz | |
Introduce QXmppTask & QXmppPromise
Closes #502.
Co-authored-by: Jonah BrĂ¼chert <jbb@kaidan.im>
Diffstat (limited to 'src')
53 files changed, 1325 insertions, 896 deletions
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 <memory> @@ -85,6 +86,21 @@ inline QFuture<void> makeReadyFuture() } #endif +template<typename T> +QXmppTask<T> makeReadyTask(T &&value) +{ + QXmppPromise<T> promise; + promise.finish(std::move(value)); + return promise.task(); +} + +inline QXmppTask<void> makeReadyTask() +{ + QXmppPromise<void> promise; + promise.finish(); + return promise.task(); +} + template<typename T, typename Handler> void awaitLast(const QFuture<T> &future, QObject *context, Handler handler) { @@ -123,18 +139,14 @@ void await(const QFuture<void> &future, QObject *context, Handler handler) } template<typename Result, typename Input, typename Converter> -auto chain(const QFuture<Input> &source, QObject *context, Converter task) -> QFuture<Result> +auto chain(QXmppTask<Input> &&source, QObject *context, Converter task) -> QXmppTask<Result> { - QFutureInterface<Result> resultInterface(QFutureInterfaceBase::Started); + QXmppPromise<Result> promise; - auto *watcher = new QFutureWatcher<Input>(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<typename IqType, typename Input, typename Converter> @@ -169,21 +181,21 @@ auto parseIq(Input &&sendResult) -> Result } template<typename Input, typename Converter> -auto chainIq(QFuture<Input> &&input, QObject *context, Converter convert) -> QFuture<decltype(convert({}))> +auto chainIq(QXmppTask<Input> &&input, QObject *context, Converter convert) -> QXmppTask<decltype(convert({}))> { using Result = decltype(convert({})); using IqType = std::decay_t<first_argument_t<Converter>>; - return chain<Result>(std::move(input), context, [convert { std::move(convert) }](Input &&input) -> Result { + return chain<Result>(std::move(input), context, [convert = std::move(convert)](Input &&input) -> Result { return parseIq<IqType>(std::move(input), convert); }); } template<typename Result, typename Input> -auto chainIq(QFuture<Input> &&input, QObject *context) -> QFuture<Result> +auto chainIq(QXmppTask<Input> &&input, QObject *context) -> QXmppTask<Result> { // IQ type is first std::variant parameter using IqType = std::decay_t<decltype(std::get<0>(Result {}))>; - return chain<Result>(std::move(input), context, [](Input &&sendResult) { + return chain<Result>(std::move(input), context, [](Input &&sendResult) mutable { return parseIq<IqType, Result>(sendResult); }); } @@ -210,6 +222,24 @@ auto mapSuccess(std::variant<T, Err> var, Function lambda) std::move(var)); } +template<typename T> +static auto taskFromFuture(QFuture<T> &&future) -> QXmppTask<T> +{ + QXmppPromise<T> promise; + auto *watcher = new QFutureWatcher<T>(); + QObject::connect(watcher, &QFutureWatcher<T>::finished, [promise = std::move(promise), watcher]() mutable { + if constexpr (std::is_void_v<T>) { + 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 <QFuture> #include <QXmlStreamWriter> inline QByteArray serialize(const QXmppNonza &nonza) @@ -17,17 +16,16 @@ inline QByteArray serialize(const QXmppNonza &nonza) } /// \cond -QXmppPacket::QXmppPacket(const QXmppNonza &nonza, QFutureInterface<QXmpp::SendResult> interface) +QXmppPacket::QXmppPacket(const QXmppNonza &nonza, QXmppPromise<QXmpp::SendResult> interface) : QXmppPacket(serialize(nonza), nonza.isXmppStanza(), std::move(interface)) { } -QXmppPacket::QXmppPacket(const QByteArray &data, bool isXmppStanza, QFutureInterface<QXmpp::SendResult> interface) - : m_interface(std::move(interface)), +QXmppPacket::QXmppPacket(const QByteArray &data, bool isXmppStanza, QXmppPromise<QXmpp::SendResult> 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<QXmpp::SendResult> QXmppPacket::future() +QXmppTask<QXmpp::SendResult> 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 <memory> @@ -17,19 +18,18 @@ class QXmppNonza; class QXmppPacket { public: - QXmppPacket(const QXmppNonza &nonza, QFutureInterface<QXmpp::SendResult> = {}); - QXmppPacket(const QByteArray &data, bool isXmppStanza, QFutureInterface<QXmpp::SendResult> = {}); + QXmppPacket(const QXmppNonza &nonza, QXmppPromise<QXmpp::SendResult> = {}); + QXmppPacket(const QByteArray &data, bool isXmppStanza, QXmppPromise<QXmpp::SendResult> = {}); QByteArray data() const; bool isXmppStanza() const; - QFuture<QXmpp::SendResult> future(); + QXmppTask<QXmpp::SendResult> task(); - void reportFinished(); - void reportResult(const QXmpp::SendResult &); + void reportFinished(QXmpp::SendResult &&); private: - QFutureInterface<QXmpp::SendResult> m_interface; + QXmppPromise<QXmpp::SendResult> 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 <lnj@kaidan.im> +// SPDX-FileCopyrightText: 2022 Jonah BrĂ¼chert <jbb@kaidan.im> +// +// 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<typename T> +class QXmppPromise +{ +public: + template<typename U = T, std::enable_if_t<std::is_void_v<U>> * = nullptr> + QXmppPromise() + : d(QXmpp::Private::TaskPrivate(nullptr)) + { + } + + template<typename U = T, std::enable_if_t<!std::is_void_v<U>> * = nullptr> + QXmppPromise() + : d(QXmpp::Private::TaskPrivate([](void *r) { delete static_cast<T *>(r); })) + { + } + + /// + /// Report that the asynchronous operation has finished, and call the connected handler of the + /// QXmppTask<T> belonging to this promise. + /// + /// \param value The result of the asynchronous computation + /// +#ifdef QXMPP_DOC + void reportFinished(T &&value) +#else + template<typename U, std::enable_if_t<!std::is_void_v<T> && std::is_base_of_v<T, U>> * = 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<typename U, std::enable_if_t<!std::is_void_v<T> && std::is_constructible_v<T, U> && !std::is_base_of_v<T, U>> * = 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<typename U = T, std::enable_if_t<std::is_void_v<U>> * = 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<T> task() + { + return QXmppTask<T>(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<QXmppStream::IqResult> interface; + QXmppPromise<QXmppStream::IqResult> interface; QString jid; }; @@ -172,7 +172,7 @@ bool QXmppStream::sendPacket(const QXmppNonza &nonza) /// /// \since QXmpp 1.5 /// -QFuture<QXmpp::SendResult> QXmppStream::send(QXmppNonza &&nonza) +QXmppTask<QXmpp::SendResult> QXmppStream::send(QXmppNonza &&nonza) { bool success; return send(QXmppPacket(nonza), success); @@ -183,13 +183,13 @@ QFuture<QXmpp::SendResult> QXmppStream::send(QXmppNonza &&nonza) /// /// \since QXmpp 1.5 /// -QFuture<QXmpp::SendResult> QXmppStream::send(QXmppPacket &&packet) +QXmppTask<QXmpp::SendResult> QXmppStream::send(QXmppPacket &&packet) { bool success; return send(std::move(packet), success); } -QFuture<QXmpp::SendResult> QXmppStream::send(QXmppPacket &&packet, bool &writtenToSocket) +QXmppTask<QXmpp::SendResult> QXmppStream::send(QXmppPacket &&packet, bool &writtenToSocket) { // the writtenToSocket parameter is just for backwards compat (see // QXmppStream::sendPacket()) @@ -198,7 +198,7 @@ QFuture<QXmpp::SendResult> 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<QXmpp::SendResult> QXmppStream::send(QXmppPacket &&packet, bool &written /// /// \since QXmpp 1.5 /// -QFuture<QXmppStream::IqResult> QXmppStream::sendIq(QXmppIq &&iq) +QXmppTask<QXmppStream::IqResult> QXmppStream::sendIq(QXmppIq &&iq) { using namespace QXmpp; @@ -233,18 +233,18 @@ QFuture<QXmppStream::IqResult> QXmppStream::sendIq(QXmppIq &&iq) /// /// \since QXmpp 1.5 /// -QFuture<QXmppStream::IqResult> QXmppStream::sendIq(QXmppPacket &&packet, const QString &id, const QString &to) +QXmppTask<QXmppStream::IqResult> QXmppStream::sendIq(QXmppPacket &&packet, const QString &id, const QString &to) { using namespace QXmpp; if (id.isEmpty() || d->runningIqs.contains(id)) { - return makeReadyFuture<IqResult>(QXmppError { + return makeReadyTask<IqResult>(QXmppError { QStringLiteral("Invalid IQ id: empty or in use."), SendError::Disconnected }); } if (to.isEmpty()) { - return makeReadyFuture<IqResult>(QXmppError { + return makeReadyTask<IqResult>(QXmppError { QStringLiteral("The 'to' address must be set so the stream can match the response."), SendError::Disconnected }); } @@ -253,15 +253,13 @@ QFuture<QXmppStream::IqResult> QXmppStream::sendIq(QXmppPacket &&packet, const Q if (sendFuture.isFinished()) { if (std::holds_alternative<QXmppError>(sendFuture.result())) { // early exit (saves QFutureWatcher) - return makeReadyFuture<IqResult>(std::get<QXmppError>(sendFuture.result())); + return makeReadyTask<IqResult>(std::get<QXmppError>(sendFuture.result())); } } else { - awaitLast(sendFuture, this, [this, id](SendResult result) { + sendFuture.then(this, [this, id](SendResult result) { if (std::holds_alternative<QXmppError>(result)) { if (auto itr = d->runningIqs.find(id); itr != d->runningIqs.end()) { - itr.value().interface.reportResult(std::get<QXmppError>(result)); - itr.value().interface.reportFinished(); - + itr.value().interface.finish(std::get<QXmppError>(result)); d->runningIqs.erase(itr); } } @@ -269,12 +267,12 @@ QFuture<QXmppStream::IqResult> QXmppStream::sendIq(QXmppPacket &&packet, const Q } IqState state { - QFutureInterface<IqResult>(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::IqResult> 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<typename T> +class QXmppTask; +template<typename T> class QFuture; template<typename T> class QFutureInterface; @@ -41,12 +43,12 @@ public: virtual bool isConnected() const; bool sendPacket(const QXmppNonza &); - QFuture<QXmpp::SendResult> send(QXmppNonza &&); - QFuture<QXmpp::SendResult> send(QXmppPacket &&); + QXmppTask<QXmpp::SendResult> send(QXmppNonza &&); + QXmppTask<QXmpp::SendResult> send(QXmppPacket &&); using IqResult = std::variant<QDomElement, QXmppError>; - QFuture<IqResult> sendIq(QXmppIq &&); - QFuture<IqResult> sendIq(QXmppPacket &&, const QString &id, const QString &to); + QXmppTask<IqResult> sendIq(QXmppIq &&); + QXmppTask<IqResult> 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<QXmpp::SendResult> send(QXmppPacket &&, bool &); + QXmppTask<QXmpp::SendResult> 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 <lnj@kaidan.im> +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "QXmppTask.h" + +#include <QDebug> + +namespace QXmpp::Private { + +struct TaskData +{ + QPointer<QObject> context; + std::function<void(TaskPrivate &, void *)> 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<QXmpp::Private::TaskData>()) +{ + 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<void(QXmpp::Private::TaskPrivate &, void *)> QXmpp::Private::TaskPrivate::continuation() const +{ + return d->continuation; +} + +void QXmpp::Private::TaskPrivate::setContinuation(std::function<void(TaskPrivate &, void *)> &&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 <lnj@kaidan.im> +// SPDX-FileCopyrightText: 2022 Jonah BrĂ¼chert <jbb@kaidan.im> +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef QXMPPTASK_H +#define QXMPPTASK_H + +#include "qxmpp_export.h" + +#include <functional> +#include <memory> +#include <optional> + +#include <QFuture> +#include <QPointer> + +template<typename T> +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<void(TaskPrivate &, void *)> continuation() const; + void setContinuation(std::function<void(TaskPrivate &, void *)> &&); + void invokeContinuation(void *result); + +private: + std::shared_ptr<TaskData> 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<QXmppStanza> 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<typename T> +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<QString> 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<typename Continuation> +#endif + void then(QObject *context, Continuation continuation) + { + static_assert( + std::is_void_v<T> && std::is_invocable_v<Continuation> || + !std::is_void_v<T> /* && 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<T>) { + continuation(); + } else { + // when calling then() after finished value could be empty + if (hasResult()) { + continuation(std::move(*reinterpret_cast<T *>(d.result()))); + d.resetResult(); + } + } + } else { + d.setContext(context); + d.setContinuation([f = std::forward<Continuation>(continuation)](TaskPrivate &d, void *result) mutable { + if (d.isContextAlive()) { + if constexpr (std::is_void_v<T>) { + f(); + } else { + f(std::move(*reinterpret_cast<T *>(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<typename U = T, std::enable_if_t<(!std::is_void_v<U>)> * = 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<typename U = T, std::enable_if_t<(!std::is_void_v<U>)> * = nullptr> + [[nodiscard]] const U &result() const +#endif + { + Q_ASSERT(isFinished()); + Q_ASSERT(hasResult()); + return *reinterpret_cast<U *>(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<typename U = T, std::enable_if_t<(!std::is_void_v<U>)> * = nullptr> + [[nodiscard]] U takeResult() +#endif + { + Q_ASSERT(isFinished()); + Q_ASSERT(hasResult()); + U result = std::move(*reinterpret_cast<U *>(d.result())); + d.resetResult(); + return result; + } + + /// + /// Converts the Task into a QFuture. Afterwards the QXmppTask object is invalid. + /// + QFuture<T> toFuture(QObject *context) + { + QFutureInterface<T> interface; + + if constexpr (std::is_same_v<T, void>) { + 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<T>; + + 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<void> QXmppAtmManager::makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) +QXmppTask<void> QXmppAtmManager::makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> promise; auto future = keys(encryption, TrustLevel::Authenticated | TrustLevel::ManuallyDistrusted); - await(future, this, [=](QHash<TrustLevel, QMultiHash<QString, QByteArray>> keys) mutable { + future.then(this, [=](QHash<TrustLevel, QMultiHash<QString, QByteArray>> 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> QXmppAtmManager::makeTrustDecisions(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIdsForAuthentication, const QMultiHash<QString, QByteArray> &keyIdsForDistrusting) +QXmppTask<void> QXmppAtmManager::makeTrustDecisions(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIdsForAuthentication, const QMultiHash<QString, QByteArray> &keyIdsForDistrusting) { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> 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<void> QXmppAtmManager::makeTrustDecisions(const QString &encryption, con /// /// \param message message that can contain a trust message element /// -QFuture<void> QXmppAtmManager::handleMessage(const QXmppMessage &message) +QXmppTask<void> QXmppAtmManager::handleMessage(const QXmppMessage &message) { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> promise; if (const auto trustMessageElement = message.trustMessageElement(); trustMessageElement && @@ -299,7 +300,7 @@ QFuture<void> 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<void> 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<void> 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<void> QXmppAtmManager::handleMessage(const QXmppMessage &message) /// \param encryption encryption protocol namespace /// \param keyIds key owners' bare JIDs mapped to the IDs of their keys /// -QFuture<void> QXmppAtmManager::authenticate(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds) +QXmppTask<void> QXmppAtmManager::authenticate(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds) { if (keyIds.isEmpty()) { - return makeReadyFuture(); + return makeReadyTask(); } - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> 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<void> 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<void> QXmppAtmManager::distrust(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds) +QXmppTask<void> QXmppAtmManager::distrust(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds) { if (keyIds.isEmpty()) { - return makeReadyFuture(); + return makeReadyTask(); } - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> 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<void> QXmppAtmManager::distrust(const QString &encryption, const QMultiH /// \param encryption encryption protocol namespace /// \param keyOwnerJids bare JIDs of the key owners /// -QFuture<void> QXmppAtmManager::distrustAutomaticallyTrustedKeys(const QString &encryption, const QList<QString> &keyOwnerJids) +QXmppTask<void> QXmppAtmManager::distrustAutomaticallyTrustedKeys(const QString &encryption, const QList<QString> &keyOwnerJids) { return setTrustLevel(encryption, keyOwnerJids, TrustLevel::AutomaticallyTrusted, TrustLevel::AutomaticallyDistrusted); } @@ -448,26 +449,26 @@ QFuture<void> QXmppAtmManager::distrustAutomaticallyTrustedKeys(const QString &e /// \param encryption encryption protocol namespace /// \param senderKeyIds IDs of the keys that were used by the senders /// -QFuture<void> QXmppAtmManager::makePostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) +QXmppTask<void> QXmppAtmManager::makePostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> promise; auto future = trustStorage()->keysForPostponedTrustDecisions(encryption, senderKeyIds); - await(future, this, [=](const QHash<bool, QMultiHash<QString, QByteArray>> &&keysForPostponedTrustDecisions) mutable { + future.then(this, [=](const QHash<bool, QMultiHash<QString, QByteArray>> &&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<void> QXmppAtmManager::makePostponedTrustDecisions(const QString &encryp /// \param keyOwners key owners containing the data for authentication or distrusting /// \param recipientJid JID of the recipient /// -QFuture<QXmpp::SendResult> QXmppAtmManager::sendTrustMessage(const QString &encryption, const QList<QXmppTrustMessageKeyOwner> &keyOwners, const QString &recipientJid) +QXmppTask<QXmpp::SendResult> QXmppAtmManager::sendTrustMessage(const QString &encryption, const QList<QXmppTrustMessageKeyOwner> &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<typename T> +class QXmppTask; class QXMPP_EXPORT QXmppAtmManager : public QXmppTrustManager { @@ -18,7 +20,7 @@ class QXMPP_EXPORT QXmppAtmManager : public QXmppTrustManager public: QXmppAtmManager(QXmppAtmTrustStorage *trustStorage); - QFuture<void> makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting = {}); + QXmppTask<void> makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting = {}); protected: /// \cond @@ -28,16 +30,16 @@ private: Q_SLOT void handleMessageReceived(const QXmppMessage &message); /// \endcond - QFuture<void> makeTrustDecisions(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIdsForAuthentication, const QMultiHash<QString, QByteArray> &keyIdsForDistrusting); - QFuture<void> handleMessage(const QXmppMessage &message); + QXmppTask<void> makeTrustDecisions(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIdsForAuthentication, const QMultiHash<QString, QByteArray> &keyIdsForDistrusting); + QXmppTask<void> handleMessage(const QXmppMessage &message); - QFuture<void> authenticate(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds); - QFuture<void> distrust(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds); + QXmppTask<void> authenticate(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds); + QXmppTask<void> distrust(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds); - QFuture<void> distrustAutomaticallyTrustedKeys(const QString &encryption, const QList<QString> &keyOwnerJids); - QFuture<void> makePostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds); + QXmppTask<void> distrustAutomaticallyTrustedKeys(const QString &encryption, const QList<QString> &keyOwnerJids); + QXmppTask<void> makePostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds); - QFuture<QXmpp::SendResult> sendTrustMessage(const QString &encryption, const QList<QXmppTrustMessageKeyOwner> &keyOwners, const QString &recipientJid); + QXmppTask<QXmpp::SendResult> sendTrustMessage(const QString &encryption, const QList<QXmppTrustMessageKeyOwner> &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<void> QXmppAtmTrustMemoryStorage::addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) +QXmppTask<void> QXmppAtmTrustMemoryStorage::addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) { const auto addKeys = [&](const QXmppTrustMessageKeyOwner &keyOwner, bool trust, const QList<QByteArray> &keyIds) { for (const auto &keyId : keyIds) { @@ -85,10 +85,10 @@ QFuture<void> QXmppAtmTrustMemoryStorage::addKeysForPostponedTrustDecisions(cons addKeys(keyOwner, false, keyOwner.distrustedKeys()); } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) +QXmppTask<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) { for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption;) { @@ -101,10 +101,10 @@ QFuture<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(c } } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) +QXmppTask<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) { for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption;) { @@ -115,16 +115,16 @@ QFuture<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(c } } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption) +QXmppTask<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption) { d->keys.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> QXmppAtmTrustMemoryStorage::keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) +QXmppTask<QHash<bool, QMultiHash<QString, QByteArray>>> QXmppAtmTrustMemoryStorage::keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) { QHash<bool, QMultiHash<QString, QByteArray>> keys; @@ -135,13 +135,13 @@ QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> QXmppAtmTrustMemoryStorage } } - return makeReadyFuture(std::move(keys)); + return makeReadyTask(std::move(keys)); } -QFuture<void> QXmppAtmTrustMemoryStorage::resetAll(const QString &encryption) +QXmppTask<void> 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<void> addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) override; - QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) override; - QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) override; - QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption) override; - QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {}) override; + QXmppTask<void> addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) override; + QXmppTask<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) override; + QXmppTask<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) override; + QXmppTask<void> removeKeysForPostponedTrustDecisions(const QString &encryption) override; + QXmppTask<QHash<bool, QMultiHash<QString, QByteArray>>> keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {}) override; - QFuture<void> resetAll(const QString &encryption) override; + QXmppTask<void> 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 <QList> + 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<void> addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) = 0; - virtual QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) = 0; - virtual QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) = 0; - virtual QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption) = 0; - virtual QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {}) = 0; + virtual QXmppTask<void> addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) = 0; + virtual QXmppTask<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) = 0; + virtual QXmppTask<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) = 0; + virtual QXmppTask<void> removeKeysForPostponedTrustDecisions(const QString &encryption) = 0; + virtual QXmppTask<QHash<bool, QMultiHash<QString, QByteArray>>> keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &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 <QDomElement> -#include <QFuture> #include <QSslSocket> #include <QTimer> @@ -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<QXmpp::SendResult> QXmppClient::send(QXmppStanza &&stanza, const std::optional<QXmppSendStanzaParams> ¶ms) +QXmppTask<QXmpp::SendResult> QXmppClient::send(QXmppStanza &&stanza, const std::optional<QXmppSendStanzaParams> ¶ms) { - const auto sendEncrypted = [this](QFuture<MessageEncryptResult> &&future) { - QFutureInterface<QXmpp::SendResult> interface(QFutureInterfaceBase::Started); - - await(future, this, [this, interface](MessageEncryptResult &&result) mutable { + const auto sendEncrypted = [this](QXmppTask<MessageEncryptResult> &&future) { + QXmppPromise<QXmpp::SendResult> interface; + future.then(this, [this, interface](MessageEncryptResult &&result) mutable { if (const auto *xml = std::get_if<QByteArray>(&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<QXmppError>(result) }); + interface.finish(std::get<QXmppError>(std::move(result))); } }); - return interface.future(); + return interface.task(); }; if (d->encryptionExtension) { @@ -452,13 +450,11 @@ QFuture<QXmpp::SendResult> 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<QXmpp::SendResult> QXmppClient::sendUnencrypted(QXmppStanza &&stanza, const std::optional<QXmppSendStanzaParams> &) +QXmppTask<QXmpp::SendResult> QXmppClient::sendUnencrypted(QXmppStanza &&stanza, const std::optional<QXmppSendStanzaParams> &) { return d->stream->send(stanza); } @@ -472,7 +468,7 @@ QFuture<QXmpp::SendResult> QXmppClient::sendUnencrypted(QXmppStanza &&stanza, co /// /// \since QXmpp 1.5 /// -QFuture<QXmpp::SendResult> QXmppClient::reply(QXmppStanza &&stanza, const std::optional<QXmppE2eeMetadata> &e2eeMetadata, const std::optional<QXmppSendStanzaParams> ¶ms) +QXmppTask<QXmpp::SendResult> QXmppClient::reply(QXmppStanza &&stanza, const std::optional<QXmppE2eeMetadata> &e2eeMetadata, const std::optional<QXmppSendStanzaParams> ¶ms) { // This should pick the right e2ee manager as soon as multiple encryptions // in parallel are supported. @@ -497,7 +493,7 @@ QFuture<QXmpp::SendResult> QXmppClient::reply(QXmppStanza &&stanza, const std::o /// /// \since QXmpp 1.5 /// -QFuture<QXmppClient::IqResult> QXmppClient::sendIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> &) +QXmppTask<QXmppClient::IqResult> QXmppClient::sendIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> &) { return d->stream->sendIq(std::move(iq)); } @@ -515,57 +511,52 @@ QFuture<QXmppClient::IqResult> QXmppClient::sendIq(QXmppIq &&iq, const std::opti /// /// \since QXmpp 1.5 /// -QFuture<QXmppClient::IqResult> QXmppClient::sendSensitiveIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) +QXmppTask<QXmppClient::IqResult> QXmppClient::sendSensitiveIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) { - const auto sendEncrypted = [this](QFuture<IqEncryptResult> &&future, const QString &id, const QString &to) { - QFutureInterface<IqResult> interface(QFutureInterfaceBase::Started); - await(future, this, [this, interface, id, to](IqEncryptResult result) mutable { + const auto sendEncrypted = [this](QXmppTask<IqEncryptResult> &&future, const QString &id, const QString &to) { + QXmppPromise<IqResult> interface; + future.then(this, [this, interface, id, to](IqEncryptResult result) mutable { if (const auto *xml = std::get_if<QByteArray>(&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<QDomElement>(&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<QDomElement>(&result)) { + future.then(this, [interface, encryptedDom = *encryptedDom](IqDecryptResult result) mutable { + if (auto dom = std::get_if<QDomElement>(&result)) { // decrypted result - interface.reportResult(*dom); + interface.finish(std::move(*dom)); } else if (std::holds_alternative<QXmppE2eeExtension::NotEncrypted>(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<QXmppError>(&result)) { - interface.reportResult(*error); + interface.finish(std::move(encryptedDom)); + } else if (auto error = std::get_if<QXmppError>(&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<QXmppError>(result)); - interface.reportFinished(); + interface.finish(std::get<QXmppError>(result)); } }); } else { - interface.reportResult(std::get<QXmppError>(result)); - interface.reportFinished(); + interface.finish(std::get<QXmppError>(result)); } }); - return interface.future(); + return interface.task(); }; if (iq.id().isEmpty() || d->stream->hasIqId(iq.id())) { @@ -595,7 +586,7 @@ QFuture<QXmppClient::IqResult> QXmppClient::sendSensitiveIq(QXmppIq &&iq, const /// /// \since QXmpp 1.5 /// -QFuture<QXmppClient::EmptyResult> QXmppClient::sendGenericIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> &) +QXmppTask<QXmppClient::EmptyResult> QXmppClient::sendGenericIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> &) { 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 <QSslError> template<typename T> -class QFuture; +class QXmppTask; class QXmppE2eeExtension; class QXmppClientExtension; @@ -219,12 +219,12 @@ public: State state() const; QXmppStanza::Error::Condition xmppStreamError(); - QFuture<QXmpp::SendResult> send(QXmppStanza &&, const std::optional<QXmppSendStanzaParams> & = {}); - QFuture<QXmpp::SendResult> sendUnencrypted(QXmppStanza &&, const std::optional<QXmppSendStanzaParams> & = {}); - QFuture<QXmpp::SendResult> reply(QXmppStanza &&stanza, const std::optional<QXmppE2eeMetadata> &e2eeMetadata, const std::optional<QXmppSendStanzaParams> & = {}); - QFuture<IqResult> sendIq(QXmppIq &&, const std::optional<QXmppSendStanzaParams> & = {}); - QFuture<IqResult> sendSensitiveIq(QXmppIq &&, const std::optional<QXmppSendStanzaParams> & = {}); - QFuture<EmptyResult> sendGenericIq(QXmppIq &&, const std::optional<QXmppSendStanzaParams> & = {}); + QXmppTask<QXmpp::SendResult> send(QXmppStanza &&, const std::optional<QXmppSendStanzaParams> & = {}); + QXmppTask<QXmpp::SendResult> sendUnencrypted(QXmppStanza &&, const std::optional<QXmppSendStanzaParams> & = {}); + QXmppTask<QXmpp::SendResult> reply(QXmppStanza &&stanza, const std::optional<QXmppE2eeMetadata> &e2eeMetadata, const std::optional<QXmppSendStanzaParams> & = {}); + QXmppTask<IqResult> sendIq(QXmppIq &&, const std::optional<QXmppSendStanzaParams> & = {}); + QXmppTask<IqResult> sendSensitiveIq(QXmppIq &&, const std::optional<QXmppSendStanzaParams> & = {}); + QXmppTask<EmptyResult> sendGenericIq(QXmppIq &&, const std::optional<QXmppSendStanzaParams> & = {}); #if QXMPP_DEPRECATED_SINCE(1, 1) QT_DEPRECATED_X("Use QXmppClient::findExtension<QXmppRosterManager>() 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::InfoResult> QXmppDiscoveryManager::requestDiscoInfo(const QString &jid, const QString &node) +QXmppTask<QXmppDiscoveryManager::InfoResult> QXmppDiscoveryManager::requestDiscoInfo(const QString &jid, const QString &node) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); @@ -140,7 +140,7 @@ QFuture<QXmppDiscoveryManager::InfoResult> QXmppDiscoveryManager::requestDiscoIn /// /// \since QXmpp 1.5 /// -QFuture<QXmppDiscoveryManager::ItemsResult> QXmppDiscoveryManager::requestDiscoItems(const QString &jid, const QString &node) +QXmppTask<QXmppDiscoveryManager::ItemsResult> 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 <variant> template<typename T> -class QFuture; +class QXmppTask; class QXmppDataForm; class QXmppDiscoveryIq; class QXmppDiscoveryManagerPrivate; @@ -35,8 +35,8 @@ public: using InfoResult = std::variant<QXmppDiscoveryIq, QXmppStanza::Error>; using ItemsResult = std::variant<QList<QXmppDiscoveryIq::Item>, QXmppStanza::Error>; - QFuture<InfoResult> requestDiscoInfo(const QString &jid, const QString &node = {}); - QFuture<ItemsResult> requestDiscoItems(const QString &jid, const QString &node = {}); + QXmppTask<InfoResult> requestDiscoInfo(const QString &jid, const QString &node = {}); + QXmppTask<ItemsResult> 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<typename T> -class QFuture; +class QXmppTask; class QXmppE2eeExtension : public QXmppExtension { @@ -30,10 +30,10 @@ public: using IqEncryptResult = std::variant<QByteArray, QXmppError>; using IqDecryptResult = std::variant<QDomElement, NotEncrypted, QXmppError>; - virtual QFuture<MessageEncryptResult> encryptMessage(QXmppMessage &&, const std::optional<QXmppSendStanzaParams> &) = 0; - virtual QFuture<MessageDecryptResult> decryptMessage(QXmppMessage &&) = 0; - virtual QFuture<IqEncryptResult> encryptIq(QXmppIq &&, const std::optional<QXmppSendStanzaParams> &) = 0; - virtual QFuture<IqDecryptResult> decryptIq(const QDomElement &) = 0; + virtual QXmppTask<MessageEncryptResult> encryptMessage(QXmppMessage &&, const std::optional<QXmppSendStanzaParams> &) = 0; + virtual QXmppTask<MessageDecryptResult> decryptMessage(QXmppMessage &&) = 0; + virtual QXmppTask<IqEncryptResult> encryptIq(QXmppIq &&, const std::optional<QXmppSendStanzaParams> &) = 0; + virtual QXmppTask<IqDecryptResult> 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<EntityTimeResult> +auto QXmppEntityTimeManager::requestEntityTime(const QString &jid) -> QXmppTask<EntityTimeResult> { 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 <variant> template<class T> -class QFuture; +class QXmppTask; class QXmppEntityTimeIq; /// @@ -27,7 +27,7 @@ public: QString requestTime(const QString &jid); using EntityTimeResult = std::variant<QXmppEntityTimeIq, QXmppStanza::Error>; - QFuture<EntityTimeResult> requestEntityTime(const QString &jid); + QXmppTask<EntityTimeResult> 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<QXmppHttpUpload> QXmppHttpUploadManager::uploadFile(std::unique_ } auto future = client()->findExtension<QXmppUploadRequestManager>()->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<QXmppHttpUpload> 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<QXmppE2eeMetadata> &e2eeMetadata, - QFuture<T> future) + QXmppTask<T> 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 <unordered_map> #include <QDomElement> -#include <QFuture> -#include <QFutureInterface> using namespace QXmpp::Private; struct RetrieveRequestState { - QFutureInterface<QXmppMamManager::RetrieveResult> interface; + QXmppPromise<QXmppMamManager::RetrieveResult> promise; QXmppMamResultIq iq; QVector<QXmppMessage> 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::RetrieveResult> QXmppMamManager::retrieveMessages(const QString &to, const QString &node, const QString &jid, const QDateTime &start, const QDateTime &end, const QXmppResultSetQuery &resultSetQuery) +QXmppTask<QXmppMamManager::RetrieveResult> 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::RetrieveResult> QXmppMamManager::retrieveMessages(const iq.parse(std::get<QDomElement>(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::RetrieveResult> 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::RetrieveResult> 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<QXmppError>(result)); - itr->second.interface.reportFinished(); + itr->second.promise.finish(std::get<QXmppError>(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 <QDateTime> template<typename T> -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<RetrieveResult> 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<RetrieveResult> 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 <QDomElement> 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 <QCryptographicHash> @@ -325,7 +326,7 @@ bool QXmppOutgoingClient::isStreamResumed() const /// /// \since QXmpp 1.5 /// -QFuture<QXmppStream::IqResult> QXmppOutgoingClient::sendIq(QXmppIq &&iq) +QXmppTask<QXmppStream::IqResult> 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<IqResult> sendIq(QXmppIq &&); + QXmppTask<IqResult> 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<T, QXmppStanza::Error>; using PublishResult = std::variant<QString, QXmppStanza::Error>; template<typename ItemT> -inline QFuture<GetResult<ItemT>> request(QXmppPubSubManager *pubSub, const QString &jid, const QString &nodeName, QObject *parent) +inline QXmppTask<GetResult<ItemT>> 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 <QDomElement> -#include <QFutureInterface> 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::FeaturesResult> QXmppPubSubManager::requestFeatures(const QString &serviceJid, ServiceType serviceType) +QXmppTask<QXmppPubSubManager::FeaturesResult> QXmppPubSubManager::requestFeatures(const QString &serviceJid, ServiceType serviceType) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); @@ -259,7 +258,7 @@ QFuture<QXmppPubSubManager::FeaturesResult> QXmppPubSubManager::requestFeatures( /// \param jid Jabber ID of the entity hosting the pubsub service /// \return /// -QFuture<QXmppPubSubManager::NodesResult> QXmppPubSubManager::requestNodes(const QString &jid) +QXmppTask<QXmppPubSubManager::NodesResult> QXmppPubSubManager::requestNodes(const QString &jid) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); @@ -293,7 +292,7 @@ QFuture<QXmppPubSubManager::NodesResult> QXmppPubSubManager::requestNodes(const /// \param nodeName the name of the node to be created /// \return /// -auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName) -> QFuture<Result> +auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName) -> QXmppTask<Result> { 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<Result> +auto QXmppPubSubManager::createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config) -> QXmppTask<Result> { 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::InstantNodeResult> QXmppPubSubManager::createInstantNode(const QString &jid) +QXmppTask<QXmppPubSubManager::InstantNodeResult> QXmppPubSubManager::createInstantNode(const QString &jid) { PubSubIq request; request.setType(QXmppIq::Set); @@ -360,7 +359,7 @@ QFuture<QXmppPubSubManager::InstantNodeResult> QXmppPubSubManager::createInstant /// \param config The configuration for the node /// \return /// -auto QXmppPubSubManager::createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config) -> QFuture<InstantNodeResult> +auto QXmppPubSubManager::createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config) -> QXmppTask<InstantNodeResult> { 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<Result> +auto QXmppPubSubManager::deleteNode(const QString &jid, const QString &nodeName) -> QXmppTask<Result> { 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::ItemIdsResult> QXmppPubSubManager::requestItemIds(const QString &serviceJid, const QString &nodeName) +QXmppTask<QXmppPubSubManager::ItemIdsResult> QXmppPubSubManager::requestItemIds(const QString &serviceJid, const QString &nodeName) { QXmppDiscoveryIq request; request.setType(QXmppIq::Get); @@ -430,7 +429,7 @@ QFuture<QXmppPubSubManager::ItemIdsResult> 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<Result> +auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName, const QString &itemId) -> QXmppTask<Result> { 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<Result> +auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId) -> QXmppTask<Result> { 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<Result> +auto QXmppPubSubManager::purgeItems(const QString &jid, const QString &nodeName) -> QXmppTask<Result> { 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::SubscriptionsResult> QXmppPubSubManager::requestSubscriptions(const QString &jid) +QXmppTask<QXmppPubSubManager::SubscriptionsResult> QXmppPubSubManager::requestSubscriptions(const QString &jid) { return requestSubscriptions(jid, {}); } @@ -491,7 +490,7 @@ QFuture<QXmppPubSubManager::SubscriptionsResult> QXmppPubSubManager::requestSubs /// \param nodeName Name of the node on the pubsub service /// \return /// -QFuture<QXmppPubSubManager::SubscriptionsResult> QXmppPubSubManager::requestSubscriptions(const QString &jid, const QString &nodeName) +QXmppTask<QXmppPubSubManager::SubscriptionsResult> QXmppPubSubManager::requestSubscriptions(const QString &jid, const QString &nodeName) { PubSubIq request; request.setType(QXmppIq::Get); @@ -515,7 +514,7 @@ QFuture<QXmppPubSubManager::SubscriptionsResult> QXmppPubSubManager::requestSubs /// \param nodeName Name of the pubsub node on the service. /// \return /// -QFuture<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestNodeAffiliations(const QString &jid, const QString &nodeName) +QXmppTask<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestNodeAffiliations(const QString &jid, const QString &nodeName) { PubSubIq request; request.setType(QXmppIq::Get); @@ -535,7 +534,7 @@ QFuture<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestNodeA /// \param jid JID of the pubsub service /// \return /// -QFuture<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestAffiliations(const QString &jid) +QXmppTask<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestAffiliations(const QString &jid) { return requestAffiliations(jid, {}); } @@ -547,7 +546,7 @@ QFuture<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestAffil /// \param nodeName Name of the pubsub node on the service. /// \return /// -QFuture<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestAffiliations(const QString &jid, const QString &nodeName) +QXmppTask<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestAffiliations(const QString &jid, const QString &nodeName) { PubSubIq request; request.setType(QXmppIq::Get); @@ -568,7 +567,7 @@ QFuture<QXmppPubSubManager::AffiliationsResult> QXmppPubSubManager::requestAffil /// \param nodeName Name of the pubsub node on the service. /// \return /// -QFuture<QXmppPubSubManager::OptionsResult> QXmppPubSubManager::requestSubscribeOptions(const QString &service, const QString &nodeName) +QXmppTask<QXmppPubSubManager::OptionsResult> QXmppPubSubManager::requestSubscribeOptions(const QString &service, const QString &nodeName) { return requestSubscribeOptions(service, nodeName, client()->configuration().jidBare()); } @@ -581,7 +580,7 @@ QFuture<QXmppPubSubManager::OptionsResult> QXmppPubSubManager::requestSubscribeO /// \param subscriberJid JID of the user to request the options for /// \return /// -QFuture<QXmppPubSubManager::OptionsResult> QXmppPubSubManager::requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid) +QXmppTask<QXmppPubSubManager::OptionsResult> QXmppPubSubManager::requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid) { PubSubIq request; request.setType(QXmppIq::Get); @@ -614,7 +613,7 @@ QFuture<QXmppPubSubManager::OptionsResult> QXmppPubSubManager::requestSubscribeO /// \param options The new options to be set /// \return /// -QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options) +QXmppTask<QXmppPubSubManager::Result> 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::Result> QXmppPubSubManager::setSubscribeOptions(cons /// \param subscriberJid The JID of the user /// \return /// -QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid) +QXmppTask<QXmppPubSubManager::Result> 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::Result> QXmppPubSubManager::setSubscribeOptions(cons /// \sa configureNode() /// \sa cancelNodeConfiguration() /// -QFuture<QXmppPubSubManager::NodeConfigResult> QXmppPubSubManager::requestNodeConfiguration(const QString &service, const QString &nodeName) +QXmppTask<QXmppPubSubManager::NodeConfigResult> QXmppPubSubManager::requestNodeConfiguration(const QString &service, const QString &nodeName) { using Error = QXmppStanza::Error; @@ -689,7 +688,7 @@ QFuture<QXmppPubSubManager::NodeConfigResult> QXmppPubSubManager::requestNodeCon /// /// \sa requestNodeConfiguration() /// -QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config) +QXmppTask<QXmppPubSubManager::Result> QXmppPubSubManager::configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config) { PubSubIq request; request.setType(QXmppIq::Set); @@ -710,7 +709,7 @@ QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::configureNode(const QStr /// /// \sa requestNodeConfiguration() /// -QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::cancelNodeConfiguration(const QString &service, const QString &nodeName) +QXmppTask<QXmppPubSubManager::Result> QXmppPubSubManager::cancelNodeConfiguration(const QString &service, const QString &nodeName) { PubSubIq request; request.setType(QXmppIq::Set); @@ -730,7 +729,7 @@ QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::cancelNodeConfiguration( /// \param nodeName name of the pubsub node being subscribed /// \param subscriberJid bare or full JID of the subscriber /// -QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid) +QXmppTask<QXmppPubSubManager::Result> QXmppPubSubManager::subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid) { PubSubIq request; request.setType(QXmppIq::Set); @@ -750,7 +749,7 @@ QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::subscribeToNode(const QS /// \param nodeName name of the pubsub node being subscribed /// \param subscriberJid bare or full JID of the subscriber /// -QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid) +QXmppTask<QXmppPubSubManager::Result> QXmppPubSubManager::unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid) { PubSubIq request; request.setType(QXmppIq::Set); @@ -785,7 +784,7 @@ QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::unsubscribeFromNode(cons /// /// -/// \fn QFuture<Result> QXmppPubSubManager::createOwnPepNode(const QString &nodeName) +/// \fn QXmppTask<Result> QXmppPubSubManager::createOwnPepNode(const QString &nodeName) /// /// Creates an empty PEP node with the default configuration. /// @@ -801,7 +800,7 @@ QFuture<QXmppPubSubManager::Result> QXmppPubSubManager::unsubscribeFromNode(cons /// /// -/// \fn QFuture<Result> QXmppPubSubManager::createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) +/// \fn QXmppTask<Result> 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<PublishItemResult> +auto QXmppPubSubManager::publishItem(PubSubIqBase &&request) -> QXmppTask<PublishItemResult> { request.setType(QXmppIq::Set); request.setQueryType(PubSubIqBase::Publish); @@ -1039,7 +1038,7 @@ auto QXmppPubSubManager::publishItem(PubSubIqBase &&request) -> QFuture<PublishI }); } -auto QXmppPubSubManager::publishItems(PubSubIqBase &&request) -> QFuture<PublishItemsResult> +auto QXmppPubSubManager::publishItems(PubSubIqBase &&request) -> QXmppTask<PublishItemsResult> { 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 <QFuture> -#include <QFutureWatcher> - class QXmppPubSubPublishOptions; class QXmppPubSubSubscribeOptions; @@ -75,73 +72,73 @@ public: ~QXmppPubSubManager(); // Generic PubSub (the PubSub service is the given entity) - QFuture<NodesResult> requestNodes(const QString &jid); - QFuture<Result> createNode(const QString &jid, const QString &nodeName); - QFuture<Result> createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config); - QFuture<InstantNodeResult> createInstantNode(const QString &jid); - QFuture<InstantNodeResult> createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config); - QFuture<Result> deleteNode(const QString &jid, const QString &nodeName); - QFuture<ItemIdsResult> requestItemIds(const QString &serviceJid, const QString &nodeName); + QXmppTask<NodesResult> requestNodes(const QString &jid); + QXmppTask<Result> createNode(const QString &jid, const QString &nodeName); + QXmppTask<Result> createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config); + QXmppTask<InstantNodeResult> createInstantNode(const QString &jid); + QXmppTask<InstantNodeResult> createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config); + QXmppTask<Result> deleteNode(const QString &jid, const QString &nodeName); + QXmppTask<ItemIdsResult> requestItemIds(const QString &serviceJid, const QString &nodeName); template<typename T = QXmppPubSubItem> - QFuture<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, const QString &itemId); + QXmppTask<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, const QString &itemId); template<typename T = QXmppPubSubItem> - QFuture<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId); + QXmppTask<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId); template<typename T = QXmppPubSubItem> - QFuture<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName); + QXmppTask<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName); template<typename T = QXmppPubSubItem> - QFuture<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds); + QXmppTask<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds); template<typename T> - QFuture<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item); + QXmppTask<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item); template<typename T> - QFuture<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); + QXmppTask<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); template<typename T> - QFuture<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items); + QXmppTask<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items); template<typename T> - QFuture<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions); - QFuture<Result> retractItem(const QString &jid, const QString &nodeName, const QString &itemId); - QFuture<Result> retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId); - QFuture<Result> purgeItems(const QString &jid, const QString &nodeName); - QFuture<SubscriptionsResult> requestSubscriptions(const QString &jid); - QFuture<SubscriptionsResult> requestSubscriptions(const QString &jid, const QString &nodeName); - QFuture<AffiliationsResult> requestNodeAffiliations(const QString &jid, const QString &nodeName); - QFuture<AffiliationsResult> requestAffiliations(const QString &jid); - QFuture<AffiliationsResult> requestAffiliations(const QString &jid, const QString &nodeName); - QFuture<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName); - QFuture<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid); - QFuture<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options); - QFuture<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid); - QFuture<NodeConfigResult> requestNodeConfiguration(const QString &service, const QString &nodeName); - QFuture<Result> configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config); - QFuture<Result> cancelNodeConfiguration(const QString &service, const QString &nodeName); - QFuture<Result> subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); - QFuture<Result> unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); + QXmppTask<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions); + QXmppTask<Result> retractItem(const QString &jid, const QString &nodeName, const QString &itemId); + QXmppTask<Result> retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId); + QXmppTask<Result> purgeItems(const QString &jid, const QString &nodeName); + QXmppTask<SubscriptionsResult> requestSubscriptions(const QString &jid); + QXmppTask<SubscriptionsResult> requestSubscriptions(const QString &jid, const QString &nodeName); + QXmppTask<AffiliationsResult> requestNodeAffiliations(const QString &jid, const QString &nodeName); + QXmppTask<AffiliationsResult> requestAffiliations(const QString &jid); + QXmppTask<AffiliationsResult> requestAffiliations(const QString &jid, const QString &nodeName); + QXmppTask<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName); + QXmppTask<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid); + QXmppTask<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options); + QXmppTask<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid); + QXmppTask<NodeConfigResult> requestNodeConfiguration(const QString &service, const QString &nodeName); + QXmppTask<Result> configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config); + QXmppTask<Result> cancelNodeConfiguration(const QString &service, const QString &nodeName); + QXmppTask<Result> subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); + QXmppTask<Result> unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); // PEP-specific (the PubSub service is the current account) - QFuture<NodesResult> requestOwnPepNodes() { return requestNodes(client()->configuration().jidBare()); }; - QFuture<Result> createOwnPepNode(const QString &nodeName) { return createNode(client()->configuration().jidBare(), nodeName); } - QFuture<Result> createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return createNode(client()->configuration().jidBare(), nodeName, config); } - QFuture<Result> deleteOwnPepNode(const QString &nodeName) { return deleteNode(client()->configuration().jidBare(), nodeName); } + QXmppTask<NodesResult> requestOwnPepNodes() { return requestNodes(client()->configuration().jidBare()); }; + QXmppTask<Result> createOwnPepNode(const QString &nodeName) { return createNode(client()->configuration().jidBare(), nodeName); } + QXmppTask<Result> createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return createNode(client()->configuration().jidBare(), nodeName, config); } + QXmppTask<Result> deleteOwnPepNode(const QString &nodeName) { return deleteNode(client()->configuration().jidBare(), nodeName); } template<typename T = QXmppPubSubItem> - QFuture<ItemResult<T>> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); } + QXmppTask<ItemResult<T>> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); } template<typename T = QXmppPubSubItem> - QFuture<ItemResult<T>> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); } + QXmppTask<ItemResult<T>> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); } template<typename T = QXmppPubSubItem> - QFuture<ItemsResult<T>> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); } - QFuture<ItemIdsResult> requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); } + QXmppTask<ItemsResult<T>> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); } + QXmppTask<ItemIdsResult> requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); } template<typename T> - QFuture<PublishItemResult> publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); + QXmppTask<PublishItemResult> publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); template<typename T> - QFuture<PublishItemResult> publishOwnPepItem(const QString &nodeName, const T &item); + QXmppTask<PublishItemResult> publishOwnPepItem(const QString &nodeName, const T &item); template<typename T> - QFuture<PublishItemsResult> publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions); + QXmppTask<PublishItemsResult> publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions); template<typename T> - QFuture<PublishItemsResult> publishOwnPepItems(const QString &nodeName, const QVector<T> &items); - QFuture<Result> retractOwnPepItem(const QString &nodeName, const QString &itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } - QFuture<Result> retractOwnPepItem(const QString &nodeName, StandardItemId itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } - QFuture<Result> purgeOwnPepItems(const QString &nodeName) { return purgeItems(client()->configuration().jidBare(), nodeName); } - QFuture<NodeConfigResult> requestOwnPepNodeConfiguration(const QString &nodeName) { return requestNodeConfiguration(client()->configuration().jidBare(), nodeName); } - QFuture<Result> configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return configureNode(client()->configuration().jidBare(), nodeName, config); } - QFuture<Result> cancelOwnPepNodeConfiguration(const QString &nodeName) { return cancelNodeConfiguration(client()->configuration().jidBare(), nodeName); } + QXmppTask<PublishItemsResult> publishOwnPepItems(const QString &nodeName, const QVector<T> &items); + QXmppTask<Result> retractOwnPepItem(const QString &nodeName, const QString &itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } + QXmppTask<Result> retractOwnPepItem(const QString &nodeName, StandardItemId itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } + QXmppTask<Result> purgeOwnPepItems(const QString &nodeName) { return purgeItems(client()->configuration().jidBare(), nodeName); } + QXmppTask<NodeConfigResult> requestOwnPepNodeConfiguration(const QString &nodeName) { return requestNodeConfiguration(client()->configuration().jidBare(), nodeName); } + QXmppTask<Result> configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return configureNode(client()->configuration().jidBare(), nodeName, config); } + QXmppTask<Result> 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<FeaturesResult> requestFeatures(const QString &serviceJid, ServiceType serviceType = PubSubOrPep); - QFuture<FeaturesResult> requestOwnPepFeatures() { return requestFeatures(client()->configuration().jidBare(), Pep); }; + QXmppTask<FeaturesResult> requestFeatures(const QString &serviceJid, ServiceType serviceType = PubSubOrPep); + QXmppTask<FeaturesResult> requestOwnPepFeatures() { return requestFeatures(client()->configuration().jidBare(), Pep); }; - QFuture<PublishItemResult> publishItem(QXmpp::Private::PubSubIqBase &&iq); - QFuture<PublishItemsResult> publishItems(QXmpp::Private::PubSubIqBase &&iq); + QXmppTask<PublishItemResult> publishItem(QXmpp::Private::PubSubIqBase &&iq); + QXmppTask<PublishItemsResult> 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<typename T> -QFuture<QXmppPubSubManager::ItemResult<T>> QXmppPubSubManager::requestItem(const QString &jid, - const QString &nodeName, - const QString &itemId) +QXmppTask<QXmppPubSubManager::ItemResult<T>> 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::ItemResult<T>> QXmppPubSubManager::requestItem(const /// \return /// template<typename T> -QFuture<QXmppPubSubManager::ItemResult<T>> QXmppPubSubManager::requestItem(const QString &jid, - const QString &nodeName, - StandardItemId itemId) +QXmppTask<QXmppPubSubManager::ItemResult<T>> QXmppPubSubManager::requestItem(const QString &jid, + const QString &nodeName, + StandardItemId itemId) { return requestItem<T>(jid, nodeName, standardItemIdToString(itemId)); } @@ -214,8 +211,8 @@ QFuture<QXmppPubSubManager::ItemResult<T>> QXmppPubSubManager::requestItem(const /// \return /// template<typename T> -QFuture<QXmppPubSubManager::ItemsResult<T>> QXmppPubSubManager::requestItems(const QString &jid, - const QString &nodeName) +QXmppTask<QXmppPubSubManager::ItemsResult<T>> QXmppPubSubManager::requestItems(const QString &jid, + const QString &nodeName) { return requestItems<T>(jid, nodeName, {}); } @@ -231,9 +228,9 @@ QFuture<QXmppPubSubManager::ItemsResult<T>> QXmppPubSubManager::requestItems(con /// \return /// template<typename T> -QFuture<QXmppPubSubManager::ItemsResult<T>> QXmppPubSubManager::requestItems(const QString &jid, - const QString &nodeName, - const QStringList &itemIds) +QXmppTask<QXmppPubSubManager::ItemsResult<T>> 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::ItemsResult<T>> QXmppPubSubManager::requestItems(con /// \return /// template<typename T> -QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishItem(const QString &jid, - const QString &nodeName, - const T &item) +QXmppTask<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishItem(const QString &jid, + const QString &nodeName, + const T &item) { QXmpp::Private::PubSubIq<T> request; request.setTo(jid); @@ -281,10 +278,10 @@ QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishItem(c /// \return /// template<typename T> -QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishItem(const QString &jid, - const QString &nodeName, - const T &item, - const QXmppPubSubPublishOptions &publishOptions) +QXmppTask<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishItem(const QString &jid, + const QString &nodeName, + const T &item, + const QXmppPubSubPublishOptions &publishOptions) { QXmpp::Private::PubSubIq<T> request; request.setTo(jid); @@ -303,9 +300,9 @@ QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishItem(c /// \return /// template<typename T> -QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishItems(const QString &jid, - const QString &nodeName, - const QVector<T> &items) +QXmppTask<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishItems(const QString &jid, + const QString &nodeName, + const QVector<T> &items) { QXmpp::Private::PubSubIq<T> request; request.setTo(jid); @@ -324,10 +321,10 @@ QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishItems /// \return /// template<typename T> -QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishItems(const QString &jid, - const QString &nodeName, - const QVector<T> &items, - const QXmppPubSubPublishOptions &publishOptions) +QXmppTask<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishItems(const QString &jid, + const QString &nodeName, + const QVector<T> &items, + const QXmppPubSubPublishOptions &publishOptions) { QXmpp::Private::PubSubIq<T> request; request.setTo(jid); @@ -346,7 +343,7 @@ QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishItems /// \return /// template<typename T> -QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions) +QXmppTask<QXmppPubSubManager::PublishItemResult> 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::PublishItemResult> QXmppPubSubManager::publishOwnPep /// \return /// template<typename T> -QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item) +QXmppTask<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item) { return publishItem(client()->configuration().jidBare(), nodeName, item); } @@ -374,7 +371,7 @@ QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishOwnPep /// \return /// template<typename T> -QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions) +QXmppTask<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions) { return publishItems(client()->configuration().jidBare(), nodeName, items, publishOptions); } @@ -387,7 +384,7 @@ QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishOwnPe /// \return /// template<typename T> -QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector<T> &items) +QXmppTask<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector<T> &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::Result> QXmppRosterManager::addRosterItem(const QString &bareJid, const QString &name, const QSet<QString> &groups) +QXmppTask<QXmppRosterManager::Result> QXmppRosterManager::addRosterItem(const QString &bareJid, const QString &name, const QSet<QString> &groups) { QXmppRosterIq::Item item; item.setBareJid(bareJid); @@ -280,7 +280,7 @@ QFuture<QXmppRosterManager::Result> QXmppRosterManager::addRosterItem(const QStr /// /// \since QXmpp 1.5 /// -QFuture<QXmppRosterManager::Result> QXmppRosterManager::removeRosterItem(const QString &bareJid) +QXmppTask<QXmppRosterManager::Result> QXmppRosterManager::removeRosterItem(const QString &bareJid) { QXmppRosterIq::Item item; item.setBareJid(bareJid); @@ -303,11 +303,11 @@ QFuture<QXmppRosterManager::Result> QXmppRosterManager::removeRosterItem(const Q /// /// \since QXmpp 1.5 /// -QFuture<QXmppRosterManager::Result> QXmppRosterManager::renameRosterItem(const QString &bareJid, const QString &name) +QXmppTask<QXmppRosterManager::Result> QXmppRosterManager::renameRosterItem(const QString &bareJid, const QString &name) { using Error = QXmppStanza::Error; if (!d->entries.contains(bareJid)) { - return QXmpp::Private::makeReadyFuture<Result>( + return QXmpp::Private::makeReadyTask<Result>( Error(Error::Modify, Error::ItemNotFound, QStringLiteral("The roster doesn't contain this user."))); } @@ -334,7 +334,7 @@ QFuture<QXmppRosterManager::Result> QXmppRosterManager::renameRosterItem(const Q /// /// \since QXmpp 1.5 /// -QFuture<QXmpp::SendResult> QXmppRosterManager::subscribeTo(const QString &bareJid, const QString &reason) +QXmppTask<QXmpp::SendResult> QXmppRosterManager::subscribeTo(const QString &bareJid, const QString &reason) { QXmppPresence packet; packet.setTo(QXmppUtils::jidToBareJid(bareJid)); @@ -351,7 +351,7 @@ QFuture<QXmpp::SendResult> QXmppRosterManager::subscribeTo(const QString &bareJi /// /// \since QXmpp 1.5 /// -QFuture<QXmpp::SendResult> QXmppRosterManager::unsubscribeFrom(const QString &bareJid, const QString &reason) +QXmppTask<QXmpp::SendResult> 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<QString> &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 <QStringList> template<typename T> -class QFuture; +class QXmppTask; class QXmppRosterManagerPrivate; /// @@ -73,11 +73,11 @@ public: QXmppPresence getPresence(const QString &bareJid, const QString &resource) const; - QFuture<Result> addRosterItem(const QString &bareJid, const QString &name = {}, const QSet<QString> &groups = {}); - QFuture<Result> removeRosterItem(const QString &bareJid); - QFuture<Result> renameRosterItem(const QString &bareJid, const QString &name); - QFuture<QXmpp::SendResult> subscribeTo(const QString &bareJid, const QString &reason = {}); - QFuture<QXmpp::SendResult> unsubscribeFrom(const QString &bareJid, const QString &reason = {}); + QXmppTask<Result> addRosterItem(const QString &bareJid, const QString &name = {}, const QSet<QString> &groups = {}); + QXmppTask<Result> removeRosterItem(const QString &bareJid); + QXmppTask<Result> renameRosterItem(const QString &bareJid, const QString &name); + QXmppTask<QXmpp::SendResult> subscribeTo(const QString &bareJid, const QString &reason = {}); + QXmppTask<QXmpp::SendResult> 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<void> QXmppTrustManager::setSecurityPolicy(const QString &encryption, TrustSecurityPolicy securityPolicy) +QXmppTask<void> QXmppTrustManager::setSecurityPolicy(const QString &encryption, TrustSecurityPolicy securityPolicy) { return m_trustStorage->setSecurityPolicy(encryption, securityPolicy); } @@ -50,7 +52,7 @@ QFuture<void> QXmppTrustManager::setSecurityPolicy(const QString &encryption, Tr /// /// \param encryption encryption protocol namespace /// -QFuture<void> QXmppTrustManager::resetSecurityPolicy(const QString &encryption) +QXmppTask<void> QXmppTrustManager::resetSecurityPolicy(const QString &encryption) { return m_trustStorage->resetSecurityPolicy(encryption); } @@ -62,7 +64,7 @@ QFuture<void> QXmppTrustManager::resetSecurityPolicy(const QString &encryption) /// /// \return the set security policy /// -QFuture<TrustSecurityPolicy> QXmppTrustManager::securityPolicy(const QString &encryption) +QXmppTask<TrustSecurityPolicy> QXmppTrustManager::securityPolicy(const QString &encryption) { return m_trustStorage->securityPolicy(encryption); } @@ -74,7 +76,7 @@ QFuture<TrustSecurityPolicy> QXmppTrustManager::securityPolicy(const QString &en /// \param encryption encryption protocol namespace /// \param keyId ID of the key /// -QFuture<void> QXmppTrustManager::setOwnKey(const QString &encryption, const QByteArray &keyId) +QXmppTask<void> QXmppTrustManager::setOwnKey(const QString &encryption, const QByteArray &keyId) { return m_trustStorage->setOwnKey(encryption, keyId); } @@ -85,7 +87,7 @@ QFuture<void> QXmppTrustManager::setOwnKey(const QString &encryption, const QByt /// /// \param encryption encryption protocol namespace /// -QFuture<void> QXmppTrustManager::resetOwnKey(const QString &encryption) +QXmppTask<void> QXmppTrustManager::resetOwnKey(const QString &encryption) { return m_trustStorage->resetOwnKey(encryption); } @@ -98,7 +100,7 @@ QFuture<void> QXmppTrustManager::resetOwnKey(const QString &encryption) /// /// \return the ID of the own key /// -QFuture<QByteArray> QXmppTrustManager::ownKey(const QString &encryption) +QXmppTask<QByteArray> QXmppTrustManager::ownKey(const QString &encryption) { return m_trustStorage->ownKey(encryption); } @@ -111,7 +113,7 @@ QFuture<QByteArray> QXmppTrustManager::ownKey(const QString &encryption) /// \param keyIds IDs of the keys /// \param trustLevel trust level of the keys /// -QFuture<void> QXmppTrustManager::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, TrustLevel trustLevel) +QXmppTask<void> QXmppTrustManager::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, TrustLevel trustLevel) { return m_trustStorage->addKeys(encryption, keyOwnerJid, keyIds, trustLevel); } @@ -122,7 +124,7 @@ QFuture<void> QXmppTrustManager::addKeys(const QString &encryption, const QStrin /// \param encryption encryption protocol namespace /// \param keyIds IDs of the keys /// -QFuture<void> QXmppTrustManager::removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) +QXmppTask<void> QXmppTrustManager::removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) { return m_trustStorage->removeKeys(encryption, keyIds); } @@ -133,7 +135,7 @@ QFuture<void> QXmppTrustManager::removeKeys(const QString &encryption, const QLi /// \param encryption encryption protocol namespace /// \param keyOwnerJid key owner's bare JID /// -QFuture<void> QXmppTrustManager::removeKeys(const QString &encryption, const QString &keyOwnerJid) +QXmppTask<void> QXmppTrustManager::removeKeys(const QString &encryption, const QString &keyOwnerJid) { return m_trustStorage->removeKeys(encryption, keyOwnerJid); } @@ -143,7 +145,7 @@ QFuture<void> QXmppTrustManager::removeKeys(const QString &encryption, const QSt /// /// \param encryption encryption protocol namespace /// -QFuture<void> QXmppTrustManager::removeKeys(const QString &encryption) +QXmppTask<void> QXmppTrustManager::removeKeys(const QString &encryption) { return m_trustStorage->removeKeys(encryption); } @@ -159,7 +161,7 @@ QFuture<void> QXmppTrustManager::removeKeys(const QString &encryption) /// /// \return the key owner JIDs mapped to their keys with specific trust levels /// -QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> QXmppTrustManager::keys(const QString &encryption, QXmpp::TrustLevels trustLevels) +QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> QXmppTrustManager::keys(const QString &encryption, QXmpp::TrustLevels trustLevels) { return m_trustStorage->keys(encryption, trustLevels); } @@ -177,7 +179,7 @@ QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> QXmppTrustMan /// /// \return the key IDs mapped to their trust levels for specific key owners /// -QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> QXmppTrustManager::keys(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevels trustLevels) +QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> QXmppTrustManager::keys(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevels trustLevels) { return m_trustStorage->keys(encryption, keyOwnerJids, trustLevels); } @@ -192,7 +194,7 @@ QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> QXmppTrustManager: /// /// \return whether a key of the key owner with a passed trust level is stored /// -QFuture<bool> QXmppTrustManager::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) +QXmppTask<bool> QXmppTrustManager::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) { return m_trustStorage->hasKey(encryption, keyOwnerJid, trustLevels); } @@ -206,17 +208,17 @@ QFuture<bool> 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<void> QXmppTrustManager::setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, TrustLevel trustLevel) +QXmppTask<void> QXmppTrustManager::setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, TrustLevel trustLevel) { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> promise; auto future = m_trustStorage->setTrustLevel(encryption, keyIds, trustLevel); - await(future, this, [=](QHash<QString, QMultiHash<QString, QByteArray>> modifiedKeys) mutable { + future.then(this, [=](QHash<QString, QMultiHash<QString, QByteArray>> modifiedKeys) mutable { Q_EMIT trustLevelsChanged(modifiedKeys); - interface.reportFinished(); + promise.finish(); }); - return interface.future(); + return promise.task(); } /// @@ -227,17 +229,16 @@ QFuture<void> QXmppTrustManager::setTrustLevel(const QString &encryption, const /// \param oldTrustLevel trust level being changed /// \param newTrustLevel trust level being set /// -QFuture<void> QXmppTrustManager::setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) +QXmppTask<void> QXmppTrustManager::setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> promise; + m_trustStorage->setTrustLevel(encryption, keyOwnerJids, oldTrustLevel, newTrustLevel) + .then(this, [=](QHash<QString, QMultiHash<QString, QByteArray>> modifiedKeys) mutable { + Q_EMIT trustLevelsChanged(modifiedKeys); + promise.finish(); + }); - auto future = m_trustStorage->setTrustLevel(encryption, keyOwnerJids, oldTrustLevel, newTrustLevel); - await(future, this, [=](QHash<QString, QMultiHash<QString, QByteArray>> modifiedKeys) mutable { - Q_EMIT trustLevelsChanged(modifiedKeys); - interface.reportFinished(); - }); - - return interface.future(); + return promise.task(); } /// @@ -251,7 +252,7 @@ QFuture<void> QXmppTrustManager::setTrustLevel(const QString &encryption, const /// /// \return the key's trust level /// -QFuture<TrustLevel> QXmppTrustManager::trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) +QXmppTask<TrustLevel> QXmppTrustManager::trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) { return m_trustStorage->trustLevel(encryption, keyOwnerJid, keyId); } @@ -261,7 +262,7 @@ QFuture<TrustLevel> QXmppTrustManager::trustLevel(const QString &encryption, con /// /// \param encryption encryption protocol namespace /// -QFuture<void> QXmppTrustManager::resetAll(const QString &encryption) +QXmppTask<void> 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 <QFuture> +template<typename T> +class QXmppTask; class QXmppTrustStorage; @@ -21,27 +22,27 @@ public: QXmppTrustManager(QXmppTrustStorage *trustStorage); ~QXmppTrustManager(); - QFuture<void> setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy); - QFuture<void> resetSecurityPolicy(const QString &encryption); - QFuture<QXmpp::TrustSecurityPolicy> securityPolicy(const QString &encryption); + QXmppTask<void> setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy); + QXmppTask<void> resetSecurityPolicy(const QString &encryption); + QXmppTask<QXmpp::TrustSecurityPolicy> securityPolicy(const QString &encryption); - QFuture<void> setOwnKey(const QString &encryption, const QByteArray &keyId); - QFuture<void> resetOwnKey(const QString &encryption); - QFuture<QByteArray> ownKey(const QString &encryption); + QXmppTask<void> setOwnKey(const QString &encryption, const QByteArray &keyId); + QXmppTask<void> resetOwnKey(const QString &encryption); + QXmppTask<QByteArray> ownKey(const QString &encryption); - QFuture<void> addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted); - QFuture<void> removeKeys(const QString &encryption, const QList<QByteArray> &keyIds); - QFuture<void> removeKeys(const QString &encryption, const QString &keyOwnerJid); - QFuture<void> removeKeys(const QString &encryption); - QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}); - QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}); - QFuture<bool> hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels); + QXmppTask<void> addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted); + QXmppTask<void> removeKeys(const QString &encryption, const QList<QByteArray> &keyIds); + QXmppTask<void> removeKeys(const QString &encryption, const QString &keyOwnerJid); + QXmppTask<void> removeKeys(const QString &encryption); + QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}); + QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}); + QXmppTask<bool> hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels); - QFuture<void> setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel); - QFuture<void> setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel); - QFuture<QXmpp::TrustLevel> trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId); + QXmppTask<void> setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel); + QXmppTask<void> setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel); + QXmppTask<QXmpp::TrustLevel> trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId); - QFuture<void> resetAll(const QString &encryption); + QXmppTask<void> resetAll(const QString &encryption); Q_SIGNAL void trustLevelsChanged(const QHash<QString, QMultiHash<QString, QByteArray>> &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<void> QXmppTrustMemoryStorage::setSecurityPolicy(const QString &encryption, TrustSecurityPolicy securityPolicy) +QXmppTask<void> QXmppTrustMemoryStorage::setSecurityPolicy(const QString &encryption, TrustSecurityPolicy securityPolicy) { d->securityPolicies.insert(encryption, securityPolicy); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppTrustMemoryStorage::resetSecurityPolicy(const QString &encryption) +QXmppTask<void> QXmppTrustMemoryStorage::resetSecurityPolicy(const QString &encryption) { d->securityPolicies.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<TrustSecurityPolicy> QXmppTrustMemoryStorage::securityPolicy(const QString &encryption) +QXmppTask<TrustSecurityPolicy> QXmppTrustMemoryStorage::securityPolicy(const QString &encryption) { - return makeReadyFuture(std::move(d->securityPolicies.value(encryption))); + return makeReadyTask(std::move(d->securityPolicies.value(encryption))); } -QFuture<void> QXmppTrustMemoryStorage::setOwnKey(const QString &encryption, const QByteArray &keyId) +QXmppTask<void> QXmppTrustMemoryStorage::setOwnKey(const QString &encryption, const QByteArray &keyId) { d->ownKeys.insert(encryption, keyId); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppTrustMemoryStorage::resetOwnKey(const QString &encryption) +QXmppTask<void> QXmppTrustMemoryStorage::resetOwnKey(const QString &encryption) { d->ownKeys.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<QByteArray> QXmppTrustMemoryStorage::ownKey(const QString &encryption) +QXmppTask<QByteArray> QXmppTrustMemoryStorage::ownKey(const QString &encryption) { auto key = d->ownKeys[encryption]; - return makeReadyFuture(std::move(key)); + return makeReadyTask(std::move(key)); } -QFuture<void> QXmppTrustMemoryStorage::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, TrustLevel trustLevel) +QXmppTask<void> QXmppTrustMemoryStorage::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, TrustLevel trustLevel) { for (const auto &keyId : keyIds) { Key key; @@ -98,10 +98,10 @@ QFuture<void> QXmppTrustMemoryStorage::addKeys(const QString &encryption, const d->keys.insert(encryption, key); } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) +QXmppTask<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) { for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption;) { @@ -112,10 +112,10 @@ QFuture<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption, con } } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QString &keyOwnerJid) +QXmppTask<void> 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<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption, con } } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption) +QXmppTask<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption) { d->keys.remove(encryption); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<QHash<TrustLevel, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage::keys(const QString &encryption, TrustLevels trustLevels) +QXmppTask<QHash<TrustLevel, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage::keys(const QString &encryption, TrustLevels trustLevels) { QHash<TrustLevel, QMultiHash<QString, QByteArray>> keys; @@ -147,10 +147,10 @@ QFuture<QHash<TrustLevel, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStor } } - return makeReadyFuture(std::move(keys)); + return makeReadyTask(std::move(keys)); } -QFuture<QHash<QString, QHash<QByteArray, TrustLevel>>> QXmppTrustMemoryStorage::keys(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevels trustLevels) +QXmppTask<QHash<QString, QHash<QByteArray, TrustLevel>>> QXmppTrustMemoryStorage::keys(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevels trustLevels) { QHash<QString, QHash<QByteArray, TrustLevel>> keys; @@ -163,22 +163,22 @@ QFuture<QHash<QString, QHash<QByteArray, TrustLevel>>> QXmppTrustMemoryStorage:: } } - return makeReadyFuture(std::move(keys)); + return makeReadyTask(std::move(keys)); } -QFuture<bool> QXmppTrustMemoryStorage::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) +QXmppTask<bool> 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<QHash<QString, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, TrustLevel trustLevel) +QXmppTask<QHash<QString, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, TrustLevel trustLevel) { QHash<QString, QMultiHash<QString, QByteArray>> modifiedKeys; @@ -215,10 +215,10 @@ QFuture<QHash<QString, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage } } - return makeReadyFuture(std::move(modifiedKeys)); + return makeReadyTask(std::move(modifiedKeys)); } -QFuture<QHash<QString, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) +QXmppTask<QHash<QString, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) { QHash<QString, QMultiHash<QString, QByteArray>> modifiedKeys; @@ -231,27 +231,27 @@ QFuture<QHash<QString, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage } } - return makeReadyFuture(std::move(modifiedKeys)); + return makeReadyTask(std::move(modifiedKeys)); } -QFuture<TrustLevel> QXmppTrustMemoryStorage::trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) +QXmppTask<TrustLevel> 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<void> QXmppTrustMemoryStorage::resetAll(const QString &encryption) +QXmppTask<void> 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<void> setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy) override; - QFuture<void> resetSecurityPolicy(const QString &encryption) override; - QFuture<QXmpp::TrustSecurityPolicy> securityPolicy(const QString &encryption) override; - - QFuture<void> setOwnKey(const QString &encryption, const QByteArray &keyId) override; - QFuture<void> resetOwnKey(const QString &encryption) override; - QFuture<QByteArray> ownKey(const QString &encryption) override; - - QFuture<void> addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted) override; - QFuture<void> removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) override; - QFuture<void> removeKeys(const QString &encryption, const QString &keyOwnerJid) override; - QFuture<void> removeKeys(const QString &encryption) override; - QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}) override; - QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}) override; - QFuture<bool> hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) override; - - QFuture<QHash<QString, QMultiHash<QString, QByteArray>>> setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel) override; - QFuture<QHash<QString, QMultiHash<QString, QByteArray>>> setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel) override; - QFuture<QXmpp::TrustLevel> trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) override; - - QFuture<void> resetAll(const QString &encryption) override; + QXmppTask<void> setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy) override; + QXmppTask<void> resetSecurityPolicy(const QString &encryption) override; + QXmppTask<QXmpp::TrustSecurityPolicy> securityPolicy(const QString &encryption) override; + + QXmppTask<void> setOwnKey(const QString &encryption, const QByteArray &keyId) override; + QXmppTask<void> resetOwnKey(const QString &encryption) override; + QXmppTask<QByteArray> ownKey(const QString &encryption) override; + + QXmppTask<void> addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted) override; + QXmppTask<void> removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) override; + QXmppTask<void> removeKeys(const QString &encryption, const QString &keyOwnerJid) override; + QXmppTask<void> removeKeys(const QString &encryption) override; + QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}) override; + QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}) override; + QXmppTask<bool> hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) override; + + QXmppTask<QHash<QString, QMultiHash<QString, QByteArray>>> setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel) override; + QXmppTask<QHash<QString, QMultiHash<QString, QByteArray>>> setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel) override; + QXmppTask<QXmpp::TrustLevel> trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) override; + + QXmppTask<void> 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 <QFuture> +template<typename T> +class QXmppTask; class QXMPP_EXPORT QXmppTrustStorage { public: virtual ~QXmppTrustStorage() = default; - virtual QFuture<void> setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy) = 0; - virtual QFuture<void> resetSecurityPolicy(const QString &encryption) = 0; - virtual QFuture<QXmpp::TrustSecurityPolicy> securityPolicy(const QString &encryption) = 0; + virtual QXmppTask<void> setSecurityPolicy(const QString &encryption, QXmpp::TrustSecurityPolicy securityPolicy) = 0; + virtual QXmppTask<void> resetSecurityPolicy(const QString &encryption) = 0; + virtual QXmppTask<QXmpp::TrustSecurityPolicy> securityPolicy(const QString &encryption) = 0; - virtual QFuture<void> setOwnKey(const QString &encryption, const QByteArray &keyId) = 0; - virtual QFuture<void> resetOwnKey(const QString &encryption) = 0; - virtual QFuture<QByteArray> ownKey(const QString &encryption) = 0; + virtual QXmppTask<void> setOwnKey(const QString &encryption, const QByteArray &keyId) = 0; + virtual QXmppTask<void> resetOwnKey(const QString &encryption) = 0; + virtual QXmppTask<QByteArray> ownKey(const QString &encryption) = 0; - virtual QFuture<void> addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted) = 0; - virtual QFuture<void> removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) = 0; - virtual QFuture<void> removeKeys(const QString &encryption, const QString &keyOwnerJid) = 0; - virtual QFuture<void> removeKeys(const QString &encryption) = 0; - virtual QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}) = 0; - virtual QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}) = 0; - virtual QFuture<bool> hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) = 0; + virtual QXmppTask<void> addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, QXmpp::TrustLevel trustLevel = QXmpp::TrustLevel::AutomaticallyDistrusted) = 0; + virtual QXmppTask<void> removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) = 0; + virtual QXmppTask<void> removeKeys(const QString &encryption, const QString &keyOwnerJid) = 0; + virtual QXmppTask<void> removeKeys(const QString &encryption) = 0; + virtual QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(const QString &encryption, QXmpp::TrustLevels trustLevels = {}) = 0; + virtual QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevels trustLevels = {}) = 0; + virtual QXmppTask<bool> hasKey(const QString &encryption, const QString &keyOwnerJid, QXmpp::TrustLevels trustLevels) = 0; - virtual QFuture<QHash<QString, QMultiHash<QString, QByteArray>>> setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel) = 0; - virtual QFuture<QHash<QString, QMultiHash<QString, QByteArray>>> setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel) = 0; - virtual QFuture<QXmpp::TrustLevel> trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) = 0; + virtual QXmppTask<QHash<QString, QMultiHash<QString, QByteArray>>> setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel) = 0; + virtual QXmppTask<QHash<QString, QMultiHash<QString, QByteArray>>> setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, QXmpp::TrustLevel oldTrustLevel, QXmpp::TrustLevel newTrustLevel) = 0; + virtual QXmppTask<QXmpp::TrustLevel> trustLevel(const QString &encryption, const QString &keyOwnerJid, const QByteArray &keyId) = 0; - virtual QFuture<void> resetAll(const QString &encryption) = 0; + virtual QXmppTask<void> 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<SlotResult> + const QString &uploadService) -> QXmppTask<SlotResult> { 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<SlotResult> + const QString &uploadService) -> QXmppTask<SlotResult> { 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<SlotResult> + const QString &uploadService) -> QXmppTask<SlotResult> { 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<typename T> -class QFuture; +class QXmppTask; class QMimeType; class QXmppHttpUploadRequestIq; class QXmppHttpUploadSlotIq; @@ -98,15 +98,15 @@ public: const QString &uploadService = QString()); using SlotResult = std::variant<QXmppHttpUploadSlotIq, QXmppStanza::Error>; - QFuture<SlotResult> requestSlot(const QFileInfo &file, - const QString &uploadService = {}); - QFuture<SlotResult> requestSlot(const QFileInfo &file, - const QString &customFileName, - const QString &uploadService = {}); - QFuture<SlotResult> requestSlot(const QString &fileName, - qint64 fileSize, - const QMimeType &mimeType, - const QString &uploadService = {}); + QXmppTask<SlotResult> requestSlot(const QFileInfo &file, + const QString &uploadService = {}); + QXmppTask<SlotResult> requestSlot(const QFileInfo &file, + const QString &customFileName, + const QString &uploadService = {}); + QXmppTask<SlotResult> 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<GetResult> + -> QXmppTask<GetResult> { return Pep::request<Item>(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<PublishResult> + -> QXmppTask<PublishResult> { 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 <variant> template<typename T> -class QFuture; +class QXmppTask; class QXmppGeolocItem; class QXMPP_EXPORT QXmppUserLocationManager : public QXmppClientExtension, public QXmppPubSubEventHandler @@ -28,8 +28,8 @@ public: QStringList discoveryFeatures() const override; - QFuture<GetResult> request(const QString &jid); - QFuture<PublishResult> publish(const Item &); + QXmppTask<GetResult> request(const QString &jid); + QXmppTask<PublishResult> 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<GetResult> + -> QXmppTask<GetResult> { return Pep::request<Item>(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<PublishResult> + -> QXmppTask<PublishResult> { 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<typename T> -class QFuture; +class QXmppTask; class QXMPP_EXPORT QXmppUserTuneManager : public QXmppClientExtension, public QXmppPubSubEventHandler { @@ -27,8 +27,8 @@ public: QStringList discoveryFeatures() const override; - QFuture<GetResult> request(const QString &jid); - QFuture<PublishResult> publish(const QXmppTuneItem &); + QXmppTask<GetResult> request(const QString &jid); + QXmppTask<PublishResult> 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<bool> Manager::load() +QXmppTask<bool> Manager::load() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; auto future = d->omemoStorage->allData(); - await(future, this, [=](QXmppOmemoStorage::OmemoData omemoData) mutable { + future.then(this, [=](QXmppOmemoStorage::OmemoData omemoData) mutable { const auto &optionalOwnDevice = omemoData.ownDevice; if (optionalOwnDevice) { d->ownDevice = *optionalOwnDevice; } else { debug("Device could not be loaded because it is not stored"); - reportFinishedResult(interface, false); + interface.finish(false); return; } const auto &signedPreKeyPairs = omemoData.signedPreKeyPairs; if (signedPreKeyPairs.isEmpty()) { warning("Signed Pre keys could not be loaded because none is stored"); - reportFinishedResult(interface, false); + interface.finish(false); return; } else { d->signedPreKeyPairs = signedPreKeyPairs; @@ -378,7 +378,7 @@ QFuture<bool> Manager::load() const auto &preKeyPairs = omemoData.preKeyPairs; if (preKeyPairs.isEmpty()) { warning("Pre keys could not be loaded because none is stored"); - reportFinishedResult(interface, false); + interface.finish(false); return; } else { d->preKeyPairs = preKeyPairs; @@ -387,10 +387,11 @@ QFuture<bool> Manager::load() d->devices = omemoData.devices; d->removeDevicesRemovedFromServer(); - reportFinishedResult(interface, d->isStarted = true); + d->isStarted = true; + interface.finish(true); }); - return interface.future(); + return interface.task(); } /// @@ -400,12 +401,12 @@ QFuture<bool> Manager::load() /// /// \return whether everything is set up successfully /// -QFuture<bool> Manager::setUp() +QXmppTask<bool> Manager::setUp() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; auto future = d->setUpDeviceId(); - await(future, this, [=](bool isDeviceIdSetUp) mutable { + future.then(this, [=](bool isDeviceIdSetUp) mutable { if (isDeviceIdSetUp) { // The identity key pair in its deserialized form is not stored as a // member variable because it is only needed by @@ -416,21 +417,22 @@ QFuture<bool> Manager::setUp() d->updateSignedPreKeyPair(identityKeyPair.get()) && d->updatePreKeyPairs(PRE_KEY_INITIAL_CREATION_COUNT)) { auto future = d->omemoStorage->setOwnDevice(d->ownDevice); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = d->publishOmemoData(); - await(future, this, [=](bool isPublished) mutable { - reportFinishedResult(interface, d->isStarted = isPublished); + future.then(this, [=](bool isPublished) mutable { + d->isStarted = isPublished; + interface.finish(std::move(isPublished)); }); }); } else { - reportFinishedResult(interface, false); + interface.finish(false); } } else { - reportFinishedResult(interface, false); + interface.finish(false); } }); - return interface.future(); + return interface.task(); } /// @@ -438,7 +440,7 @@ QFuture<bool> Manager::setUp() /// /// \return the own key /// -QFuture<QByteArray> Manager::ownKey() +QXmppTask<QByteArray> Manager::ownKey() { return d->trustManager->ownKey(ns_omemo_2); } @@ -457,7 +459,7 @@ QFuture<QByteArray> Manager::ownKey() /// /// \return the key owner JIDs mapped to their keys with specific trust levels /// -QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> Manager::keys(QXmpp::TrustLevels trustLevels) +QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> Manager::keys(QXmpp::TrustLevels trustLevels) { return d->trustManager->keys(ns_omemo_2, trustLevels); } @@ -477,7 +479,7 @@ QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> Manager::keys /// /// \return the key IDs mapped to their trust levels for specific key owners /// -QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> Manager::keys(const QList<QString> &jids, QXmpp::TrustLevels trustLevels) +QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> Manager::keys(const QList<QString> &jids, QXmpp::TrustLevels trustLevels) { return d->trustManager->keys(ns_omemo_2, jids, trustLevels); } @@ -496,7 +498,7 @@ QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> Manager::keys(cons /// /// \return whether the action was successful /// -QFuture<bool> Manager::changeDeviceLabel(const QString &deviceLabel) +QXmppTask<bool> Manager::changeDeviceLabel(const QString &deviceLabel) { return d->changeDeviceLabel(deviceLabel); } @@ -564,13 +566,14 @@ void Manager::setMaximumDevicesPerStanza(int maximum) /// /// \return the results of the requests for each JID /// -QFuture<QVector<Manager::DevicesResult>> Manager::requestDeviceLists(const QList<QString> &jids) +QXmppTask<QVector<Manager::DevicesResult>> Manager::requestDeviceLists(const QList<QString> &jids) { if (const auto jidsCount = jids.size()) { - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface<QVector<Manager::DevicesResult>> interface; + QXmppPromise<QVector<Manager::DevicesResult>> interface; QVector<Manager::DevicesResult> devicesResults; }; @@ -581,21 +584,20 @@ QFuture<QVector<Manager::DevicesResult>> Manager::requestDeviceLists(const QList Q_ASSERT_X(jid != d->ownBareJid(), "Requesting contact's device list", "Own JID passed"); auto future = d->requestDeviceList(jid); - await(future, this, [jid, state](auto result) mutable { + future.then(this, [jid, state](auto result) mutable { state->devicesResults << DevicesResult { jid, mapSuccess(std::move(result), [](QXmppOmemoDeviceListItem) { return Success(); }) }; if (++(state->processed) == state->jidsCount) { - state->interface.reportResult(state->devicesResults); - state->interface.reportFinished(); + state->interface.finish(std::move(state->devicesResults)); } }); } - return state->interface.future(); + return state->interface.task(); } - return makeReadyFuture(QVector<Manager::DevicesResult>()); + return makeReadyTask(QVector<Manager::DevicesResult>()); } /// @@ -612,13 +614,14 @@ QFuture<QVector<Manager::DevicesResult>> Manager::requestDeviceLists(const QList /// /// \return the results of the subscription for each JID /// -QFuture<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const QList<QString> &jids) +QXmppTask<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const QList<QString> &jids) { if (const auto jidsCount = jids.size()) { - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface<QVector<Manager::DevicesResult>> interface; + QXmppPromise<QVector<Manager::DevicesResult>> interface; QVector<Manager::DevicesResult> devicesResults; }; @@ -627,21 +630,20 @@ QFuture<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const Q for (const auto &jid : jids) { auto future = d->subscribeToDeviceList(jid); - await(future, this, [state, jid](QXmppPubSubManager::Result result) mutable { + future.then(this, [state, jid](QXmppPubSubManager::Result result) mutable { Manager::DevicesResult devicesResult; devicesResult.jid = jid; devicesResult.result = result; state->devicesResults << devicesResult; if (++(state->processed) == state->jidsCount) { - state->interface.reportResult(state->devicesResults); - state->interface.reportFinished(); + state->interface.finish(std::move(state->devicesResults)); } }); } - return state->interface.future(); + return state->interface.task(); } - return makeReadyFuture(QVector<Manager::DevicesResult>()); + return makeReadyTask(QVector<Manager::DevicesResult>()); } /// @@ -653,7 +655,7 @@ QFuture<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const Q /// /// \return the results of the unsubscription for each JID /// -QFuture<QVector<Manager::DevicesResult>> Manager::unsubscribeFromDeviceLists() +QXmppTask<QVector<Manager::DevicesResult>> Manager::unsubscribeFromDeviceLists() { return d->unsubscribeFromDeviceLists(d->jidsOfManuallySubscribedDevices); } @@ -684,7 +686,7 @@ QXmppOmemoOwnDevice Manager::ownDevice() /// /// /\return all devices except the own device /// -QFuture<QVector<QXmppOmemoDevice>> Manager::devices() +QXmppTask<QVector<QXmppOmemoDevice>> Manager::devices() { return devices(d->devices.keys()); } @@ -702,12 +704,12 @@ QFuture<QVector<QXmppOmemoDevice>> Manager::devices() /// /// \return all devices of the passed JIDs /// -QFuture<QVector<QXmppOmemoDevice>> Manager::devices(const QList<QString> &jids) +QXmppTask<QVector<QXmppOmemoDevice>> Manager::devices(const QList<QString> &jids) { - QFutureInterface<QVector<QXmppOmemoDevice>> interface(QFutureInterfaceBase::Started); + QXmppPromise<QVector<QXmppOmemoDevice>> interface; auto future = keys(jids); - await(future, this, [=](QHash<QString, QHash<QByteArray, TrustLevel>> keys) mutable { + future.then(this, [=](QHash<QString, QHash<QByteArray, TrustLevel>> keys) mutable { QVector<QXmppOmemoDevice> devices; for (const auto &jid : jids) { @@ -730,10 +732,10 @@ QFuture<QVector<QXmppOmemoDevice>> Manager::devices(const QList<QString> &jids) } } - reportFinishedResult(interface, devices); + interface.finish(std::move(devices)); }); - return interface.future(); + return interface.task(); } /// @@ -749,32 +751,32 @@ QFuture<QVector<QXmppOmemoDevice>> Manager::devices(const QList<QString> &jids) /// /// \return the result of the contact device removals /// -QFuture<QXmppPubSubManager::Result> Manager::removeContactDevices(const QString &jid) +QXmppTask<QXmppPubSubManager::Result> Manager::removeContactDevices(const QString &jid) { - QFutureInterface<QXmppPubSubManager::Result> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppPubSubManager::Result> interface; Q_ASSERT_X(jid != d->ownBareJid(), "Removing contact device", "Own JID passed"); auto future = d->unsubscribeFromDeviceList(jid); - await(future, this, [=](QXmppPubSubManager::Result result) mutable { + future.then(this, [=](QXmppPubSubManager::Result result) mutable { if (std::holds_alternative<QXmppStanza::Error>(result)) { warning("Contact '" % jid % "' could not be removed because the device list subscription could not be removed"); - reportFinishedResult(interface, result); + interface.finish(std::move(result)); } else { d->devices.remove(jid); auto future = d->omemoStorage->removeDevices(jid); - await(future, this, [=]() mutable { + future.then(this, [=]() mutable { auto future = d->trustManager->removeKeys(ns_omemo_2, jid); - await(future, this, [=]() mutable { - reportFinishedResult(interface, result); + future.then(this, [=]() mutable { + interface.finish(std::move(result)); Q_EMIT devicesRemoved(jid); }); }); } }); - return interface.future(); + return interface.task(); } /// @@ -851,9 +853,9 @@ bool Manager::isNewDeviceAutoSessionBuildingEnabled() /// /// \param jids JIDs of the device owners for whom the sessions are built /// -QFuture<void> Manager::buildMissingSessions(const QList<QString> &jids) +QXmppTask<void> Manager::buildMissingSessions(const QList<QString> &jids) { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> interface; auto &devices = d->devices; auto devicesCount = 0; @@ -883,21 +885,18 @@ QFuture<void> Manager::buildMissingSessions(const QList<QString> &jids) if (device.session.isEmpty()) { auto future = d->buildSessionWithDeviceBundle(jid, deviceId, device); - await(future, this, [=](auto) mutable { + future.then(this, [=](auto) mutable { if (++(*processedDevicesCount) == devicesCount) { - interface.reportFinished(); } }); } else if (++(*processedDevicesCount) == devicesCount) { - interface.reportFinished(); } } } } else { - interface.reportFinished(); } - return interface.future(); + return interface.task(); } /// @@ -916,7 +915,7 @@ QFuture<void> Manager::buildMissingSessions(const QList<QString> &jids) /// Existing sessions are reset, which might lead to undecryptable incoming /// stanzas until everything is set up again. /// -QFuture<bool> Manager::resetOwnDevice() +QXmppTask<bool> Manager::resetOwnDevice() { return d->resetOwnDevice(); } @@ -938,7 +937,7 @@ QFuture<bool> Manager::resetOwnDevice() /// Existing sessions are reset, which might lead to undecryptable incoming /// stanzas until everything is set up again. /// -QFuture<bool> Manager::resetAll() +QXmppTask<bool> Manager::resetAll() { return d->resetAll(); } @@ -948,7 +947,7 @@ QFuture<bool> Manager::resetAll() /// /// \param securityPolicy security policy being set /// -QFuture<void> Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy) +QXmppTask<void> Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy) { return d->trustManager->setSecurityPolicy(ns_omemo_2, securityPolicy); } @@ -958,7 +957,7 @@ QFuture<void> Manager::setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPoli /// /// \return the used security policy /// -QFuture<QXmpp::TrustSecurityPolicy> Manager::securityPolicy() +QXmppTask<QXmpp::TrustSecurityPolicy> Manager::securityPolicy() { return d->trustManager->securityPolicy(ns_omemo_2); } @@ -971,7 +970,7 @@ QFuture<QXmpp::TrustSecurityPolicy> Manager::securityPolicy() /// \param keyIds key owners' bare JIDs mapped to the IDs of their keys /// \param trustLevel trust level being set /// -QFuture<void> Manager::setTrustLevel(const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel) +QXmppTask<void> Manager::setTrustLevel(const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel) { return d->trustManager->setTrustLevel(ns_omemo_2, keyIds, trustLevel); } @@ -986,13 +985,13 @@ QFuture<void> Manager::setTrustLevel(const QMultiHash<QString, QByteArray> &keyI /// /// \return the key's trust level /// -QFuture<QXmpp::TrustLevel> Manager::trustLevel(const QString &keyOwnerJid, const QByteArray &keyId) +QXmppTask<QXmpp::TrustLevel> Manager::trustLevel(const QString &keyOwnerJid, const QByteArray &keyId) { return d->trustManager->trustLevel(ns_omemo_2, keyOwnerJid, keyId); } /// \cond -QFuture<QXmppE2eeExtension::MessageEncryptResult> Manager::encryptMessage(QXmppMessage &&message, const std::optional<QXmppSendStanzaParams> ¶ms) +QXmppTask<QXmppE2eeExtension::MessageEncryptResult> Manager::encryptMessage(QXmppMessage &&message, const std::optional<QXmppSendStanzaParams> ¶ms) { QVector<QString> recipientJids; std::optional<TrustLevels> acceptedTrustLevels; @@ -1013,17 +1012,17 @@ QFuture<QXmppE2eeExtension::MessageEncryptResult> Manager::encryptMessage(QXmppM return d->encryptMessageForRecipients(std::move(message), recipientJids, *acceptedTrustLevels); } -QFuture<QXmppE2eeExtension::MessageDecryptResult> QXmppOmemoManager::decryptMessage(QXmppMessage &&message) +QXmppTask<QXmppE2eeExtension::MessageDecryptResult> QXmppOmemoManager::decryptMessage(QXmppMessage &&message) { if (!d->isStarted) { - return makeReadyFuture<MessageDecryptResult>(QXmppError { + return makeReadyTask<MessageDecryptResult>(QXmppError { QStringLiteral("OMEMO manager must be started before decrypting"), SendError::EncryptionError }); } auto omemoElement = message.omemoElement(); if (!omemoElement) { - return makeReadyFuture<MessageDecryptResult>(NotEncrypted()); + return makeReadyTask<MessageDecryptResult>(NotEncrypted()); } return chain<MessageDecryptResult>(d->decryptMessage(message), this, [](std::optional<QXmppMessage> message) -> MessageDecryptResult { @@ -1037,15 +1036,14 @@ QFuture<QXmppE2eeExtension::MessageDecryptResult> QXmppOmemoManager::decryptMess }); } -QFuture<QXmppE2eeExtension::IqEncryptResult> Manager::encryptIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) +QXmppTask<QXmppE2eeExtension::IqEncryptResult> Manager::encryptIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) { - QFutureInterface<QXmppE2eeExtension::IqEncryptResult> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppE2eeExtension::IqEncryptResult> interface; if (!d->isStarted) { - interface.reportResult(QXmppError { + interface.finish(QXmppError { QStringLiteral("OMEMO manager must be started before encrypting"), SendError::EncryptionError }); - interface.reportFinished(); } else { std::optional<TrustLevels> acceptedTrustLevels; @@ -1058,12 +1056,12 @@ QFuture<QXmppE2eeExtension::IqEncryptResult> Manager::encryptIq(QXmppIq &&iq, co } auto future = d->encryptStanza(iq, { QXmppUtils::jidToBareJid(iq.to()) }, *acceptedTrustLevels); - await(future, this, [=, iq = std::move(iq)](std::optional<QXmppOmemoElement> omemoElement) mutable { + future.then(this, [=, iq = std::move(iq)](std::optional<QXmppOmemoElement> omemoElement) mutable { if (!omemoElement) { - interface.reportResult(QXmppError { + interface.finish(QXmppError { QStringLiteral("OMEMO element could not be created"), SendError::EncryptionError }); - interface.reportFinished(); + } else { QXmppOmemoIq omemoIq; omemoIq.setId(iq.id()); @@ -1077,19 +1075,19 @@ QFuture<QXmppE2eeExtension::IqEncryptResult> Manager::encryptIq(QXmppIq &&iq, co QXmlStreamWriter writer(&serializedEncryptedIq); omemoIq.toXml(&writer); - reportFinishedResult(interface, { serializedEncryptedIq }); + interface.finish(serializedEncryptedIq); } }); } - return interface.future(); + return interface.task(); } -QFuture<QXmppE2eeExtension::IqDecryptResult> Manager::decryptIq(const QDomElement &element) +QXmppTask<QXmppE2eeExtension::IqDecryptResult> Manager::decryptIq(const QDomElement &element) { if (!d->isStarted) { // TODO: Add decryption queue to avoid this error - return makeReadyFuture<IqDecryptResult>(QXmppError { + return makeReadyTask<IqDecryptResult>(QXmppError { QStringLiteral("OMEMO manager must be started before decrypting"), SendError::EncryptionError }); } @@ -1107,7 +1105,7 @@ QFuture<QXmppE2eeExtension::IqDecryptResult> Manager::decryptIq(const QDomElemen }); } - return makeReadyFuture<IqDecryptResult>(NotEncrypted()); + return makeReadyTask<IqDecryptResult>(NotEncrypted()); } bool QXmppOmemoManager::isEncrypted(const QDomElement &el) @@ -1152,7 +1150,7 @@ bool Manager::handleStanza(const QDomElement &stanza) return false; } - await(d->decryptIq(stanza), this, [=](auto result) { + d->decryptIq(stanza).then(this, [=](auto result) { if (result) { injectIq(result->iq, result->e2eeMetadata); } else { @@ -1166,7 +1164,7 @@ bool Manager::handleMessage(const QXmppMessage &message) { if (d->isStarted && message.omemoElement()) { auto future = d->decryptMessage(message); - await(future, this, [=](std::optional<QXmppMessage> optionalDecryptedMessage) mutable { + future.then(this, [=](std::optional<QXmppMessage> optionalDecryptedMessage) mutable { if (optionalDecryptedMessage) { injectMessage(std::move(*optionalDecryptedMessage)); } diff --git a/src/omemo/QXmppOmemoManager.h b/src/omemo/QXmppOmemoManager.h index 5852b950..d7b34a9c 100644 --- a/src/omemo/QXmppOmemoManager.h +++ b/src/omemo/QXmppOmemoManager.h @@ -9,7 +9,6 @@ #include "QXmppE2eeExtension.h" #include "QXmppMessageHandler.h" #include "QXmppPubSubEventHandler.h" -#include "QXmppPubSubManager.h" #include "QXmppTrustSecurityPolicy.h" #include "qxmppomemo_export.h" @@ -82,14 +81,14 @@ public: explicit QXmppOmemoManager(QXmppOmemoStorage *omemoStorage); ~QXmppOmemoManager() override; - QFuture<bool> load(); - QFuture<bool> setUp(); + QXmppTask<bool> load(); + QXmppTask<bool> setUp(); - QFuture<QByteArray> ownKey(); - QFuture<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(QXmpp::TrustLevels trustLevels = {}); - QFuture<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QList<QString> &jids, QXmpp::TrustLevels trustLevels = {}); + QXmppTask<QByteArray> ownKey(); + QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> keys(QXmpp::TrustLevels trustLevels = {}); + QXmppTask<QHash<QString, QHash<QByteArray, QXmpp::TrustLevel>>> keys(const QList<QString> &jids, QXmpp::TrustLevels trustLevels = {}); - QFuture<bool> changeDeviceLabel(const QString &deviceLabel = {}); + QXmppTask<bool> changeDeviceLabel(const QString &deviceLabel = {}); int maximumDevicesPerJid() const; void setMaximumDevicesPerJid(int maximum); @@ -97,14 +96,14 @@ public: int maximumDevicesPerStanza() const; void setMaximumDevicesPerStanza(int maximum); - QFuture<QVector<DevicesResult>> requestDeviceLists(const QList<QString> &jids); - QFuture<QVector<DevicesResult>> subscribeToDeviceLists(const QList<QString> &jids); - QFuture<QVector<DevicesResult>> unsubscribeFromDeviceLists(); + QXmppTask<QVector<DevicesResult>> requestDeviceLists(const QList<QString> &jids); + QXmppTask<QVector<DevicesResult>> subscribeToDeviceLists(const QList<QString> &jids); + QXmppTask<QVector<DevicesResult>> unsubscribeFromDeviceLists(); QXmppOmemoOwnDevice ownDevice(); - QFuture<QVector<QXmppOmemoDevice>> devices(); - QFuture<QVector<QXmppOmemoDevice>> devices(const QList<QString> &jids); - QFuture<QXmppPubSubManager::Result> removeContactDevices(const QString &jid); + QXmppTask<QVector<QXmppOmemoDevice>> devices(); + QXmppTask<QVector<QXmppOmemoDevice>> devices(const QList<QString> &jids); + QXmppTask<Result> removeContactDevices(const QString &jid); void setAcceptedSessionBuildingTrustLevels(QXmpp::TrustLevels trustLevels); QXmpp::TrustLevels acceptedSessionBuildingTrustLevels(); @@ -112,23 +111,23 @@ public: void setNewDeviceAutoSessionBuildingEnabled(bool isNewDeviceAutoSessionBuildingEnabled); bool isNewDeviceAutoSessionBuildingEnabled(); - QFuture<void> buildMissingSessions(const QList<QString> &jids); + QXmppTask<void> buildMissingSessions(const QList<QString> &jids); - QFuture<bool> resetOwnDevice(); - QFuture<bool> resetAll(); + QXmppTask<bool> resetOwnDevice(); + QXmppTask<bool> resetAll(); - QFuture<void> setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy); - QFuture<QXmpp::TrustSecurityPolicy> securityPolicy(); + QXmppTask<void> setSecurityPolicy(QXmpp::TrustSecurityPolicy securityPolicy); + QXmppTask<QXmpp::TrustSecurityPolicy> securityPolicy(); - QFuture<void> setTrustLevel(const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel); - QFuture<QXmpp::TrustLevel> trustLevel(const QString &keyOwnerJid, const QByteArray &keyId); + QXmppTask<void> setTrustLevel(const QMultiHash<QString, QByteArray> &keyIds, QXmpp::TrustLevel trustLevel); + QXmppTask<QXmpp::TrustLevel> trustLevel(const QString &keyOwnerJid, const QByteArray &keyId); /// \cond - QFuture<MessageEncryptResult> encryptMessage(QXmppMessage &&message, const std::optional<QXmppSendStanzaParams> ¶ms) override; - QFuture<MessageDecryptResult> decryptMessage(QXmppMessage &&message) override; + QXmppTask<MessageEncryptResult> encryptMessage(QXmppMessage &&message, const std::optional<QXmppSendStanzaParams> ¶ms) override; + QXmppTask<MessageDecryptResult> decryptMessage(QXmppMessage &&message) override; - QFuture<IqEncryptResult> encryptIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) override; - QFuture<IqDecryptResult> decryptIq(const QDomElement &element) override; + QXmppTask<IqEncryptResult> encryptIq(QXmppIq &&iq, const std::optional<QXmppSendStanzaParams> ¶ms) override; + QXmppTask<IqDecryptResult> decryptIq(const QDomElement &element) override; bool isEncrypted(const QDomElement &) override; bool isEncrypted(const QXmppMessage &) override; diff --git a/src/omemo/QXmppOmemoManager_p.cpp b/src/omemo/QXmppOmemoManager_p.cpp index 722211a8..b5ccac90 100644 --- a/src/omemo/QXmppOmemoManager_p.cpp +++ b/src/omemo/QXmppOmemoManager_p.cpp @@ -614,10 +614,10 @@ signal_protocol_session_store ManagerPrivate::createSessionStore() const // // \return whether it succeeded // -QFuture<bool> ManagerPrivate::setUpDeviceId() +QXmppTask<bool> ManagerPrivate::setUpDeviceId() { auto future = pubSubManager->requestOwnPepItemIds(ns_omemo_2_bundles); - return chain<bool>(future, q, [this](QXmppPubSubManager::ItemIdsResult result) mutable { + return chain<bool>(std::move(future), q, [this](QXmppPubSubManager::ItemIdsResult result) mutable { // There can be the following cases: // 1. There is no PubSub node for device bundles: XEP-0030 states that a server must // respond with an error (at least ejabberd 22.05 responds with an empty node instead). @@ -1026,27 +1026,27 @@ bool ManagerPrivate::generateIdentityKeyPair(ratchet_identity_key_pair **identit // // \return the result of the encryption // -QFuture<QXmppE2eeExtension::MessageEncryptResult> ManagerPrivate::encryptMessageForRecipients(QXmppMessage &&message, QVector<QString> recipientJids, TrustLevels acceptedTrustLevels) +QXmppTask<QXmppE2eeExtension::MessageEncryptResult> ManagerPrivate::encryptMessageForRecipients(QXmppMessage &&message, QVector<QString> recipientJids, TrustLevels acceptedTrustLevels) { - QFutureInterface<QXmppE2eeExtension::MessageEncryptResult> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppE2eeExtension::MessageEncryptResult> interface; if (!isStarted) { QXmppError error { QStringLiteral("OMEMO manager must be started before encrypting"), SendError::EncryptionError }; - reportFinishedResult(interface, { error }); + interface.finish(error); } else { recipientJids.append(ownBareJid()); auto future = encryptStanza(message, recipientJids, acceptedTrustLevels); - await(future, q, [=, message = std::move(message)](std::optional<QXmppOmemoElement> omemoElement) mutable { + future.then(q, [=, message = std::move(message)](std::optional<QXmppOmemoElement> omemoElement) mutable { if (!omemoElement) { QXmppError error { QStringLiteral("OMEMO element could not be created"), QXmpp::SendError::EncryptionError, }; - reportFinishedResult(interface, { error }); + interface.finish(error); } else { const auto areDeliveryReceiptsUsed = message.isReceiptRequested() || !message.receiptId().isEmpty(); @@ -1080,12 +1080,12 @@ QFuture<QXmppE2eeExtension::MessageEncryptResult> ManagerPrivate::encryptMessage QXmlStreamWriter writer(&serializedEncryptedMessage); message.toXml(&writer, QXmpp::ScePublic); - reportFinishedResult(interface, { serializedEncryptedMessage }); + interface.finish(serializedEncryptedMessage); } }); } - return interface.future(); + return interface.task(); } // @@ -1100,11 +1100,11 @@ QFuture<QXmppE2eeExtension::MessageEncryptResult> ManagerPrivate::encryptMessage // successful, otherwise none // template<typename T> -QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T &stanza, const QVector<QString> &recipientJids, TrustLevels acceptedTrustLevels) +QXmppTask<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T &stanza, const QVector<QString> &recipientJids, TrustLevels acceptedTrustLevels) { Q_ASSERT_X(!recipientJids.isEmpty(), "Creating OMEMO envelope", "OMEMO element could not be created because no recipient JIDs are passed"); - QFutureInterface<std::optional<QXmppOmemoElement>> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<QXmppOmemoElement>> interface; if (const auto optionalPayloadEncryptionResult = encryptPayload(createSceEnvelope(stanza))) { const auto &payloadEncryptionResult = *optionalPayloadEncryptionResult; @@ -1141,7 +1141,7 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T if (++(*skippedDevicesCount) == devicesCount) { warning("OMEMO element could not be created because no recipient device responded to " % QString::number(unrespondedSentStanzasCount) % " sent stanzas"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } continue; @@ -1156,11 +1156,11 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T if (*successfullyProcessedDevicesCount == 0) { warning("OMEMO element could not be created because no recipient " "devices with keys having accepted trust levels could be found"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { omemoElement->setSenderDeviceId(ownDevice.id); omemoElement->setPayload(payloadEncryptionResult.encryptedPayload); - reportFinishedResult(interface, { *omemoElement }); + interface.finish(*omemoElement); } } }; @@ -1217,7 +1217,7 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T // determined and the session built. if (device.keyId.isEmpty()) { auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { + future.then(q, [=](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { // Process the device bundle only if one could be fetched and the // corresponding device has not been removed by another method in // the meantime. @@ -1228,12 +1228,12 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T deviceBeingModified.keyId = createKeyId(key); auto future = q->trustLevel(jid, deviceBeingModified.keyId); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { // Store the retrieved key's trust level if it is not stored // yet. if (trustLevel == TrustLevel::Undecided) { auto future = storeKeyDependingOnSecurityPolicy(jid, key); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { omemoStorage->addDevice(jid, deviceId, deviceBeingModified); Q_EMIT q->deviceChanged(jid, deviceId); buildSessionDependingOnTrustLevel(deviceBundle, trustLevel); @@ -1251,7 +1251,7 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T }); } else { auto future = q->trustLevel(jid, device.keyId); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { // Create only OMEMO envelopes for devices that have keys with // specific trust levels. if (acceptedTrustLevels.testFlag(trustLevel)) { @@ -1259,7 +1259,7 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T // Otherwise, use the existing session. if (device.session.isEmpty()) { auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { + future.then(q, [=](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { if (optionalDeviceBundle) { const auto &deviceBundle = *optionalDeviceBundle; buildSessionDependingOnTrustLevel(deviceBundle, trustLevel); @@ -1284,18 +1284,18 @@ QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const T } } else { warning("OMEMO element could not be created because no recipient devices could be found"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } } else { warning("OMEMO payload could not be encrypted"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } - return interface.future(); + return interface.task(); } -template QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza<QXmppIq>(const QXmppIq &, const QVector<QString> &, TrustLevels); -template QFuture<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza<QXmppMessage>(const QXmppMessage &, const QVector<QString> &, TrustLevels); +template QXmppTask<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza<QXmppIq>(const QXmppIq &, const QVector<QString> &, TrustLevels); +template QXmppTask<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza<QXmppMessage>(const QXmppMessage &, const QVector<QString> &, TrustLevels); // // Encrypts a payload symmetrically. @@ -1440,9 +1440,9 @@ QByteArray ManagerPrivate::createOmemoEnvelopeData(const signal_protocol_address // // \return the decrypted stanza if it could be decrypted // -QFuture<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage stanza) +QXmppTask<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage stanza) { - QFutureInterface<std::optional<QXmppMessage>> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<QXmppMessage>> interface; // At this point, the stanza has always an OMEMO element. const auto omemoElement = *stanza.omemoElement(); @@ -1460,18 +1460,20 @@ QFuture<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage // with this device. if (omemoPayload.isEmpty()) { auto future = extractPayloadDecryptionData(senderJid, senderDeviceId, omemoEnvelope); - await(future, q, [=](QCA::SecureArray payloadDecryptionData) mutable { - if (payloadDecryptionData.isEmpty()) { + future.then(q, [=](std::optional<QCA::SecureArray> payloadDecryptionData) mutable { + if (!payloadDecryptionData) { + warning("Empty OMEMO message could not be successfully processed"); + } else if (payloadDecryptionData->isEmpty()) { warning("Empty OMEMO message could not be successfully processed"); } else { q->debug("Successfully processed empty OMEMO message"); } - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); }); } else { auto future = decryptStanza(stanza, senderJid, senderDeviceId, omemoEnvelope, omemoPayload); - await(future, q, [=](std::optional<DecryptionResult> optionalDecryptionResult) mutable { + future.then(q, [=](std::optional<DecryptionResult> optionalDecryptionResult) mutable { if (optionalDecryptionResult) { const auto decryptionResult = std::move(*optionalDecryptionResult); stanza.parseExtensions(decryptionResult.sceContent, SceSensitive); @@ -1482,15 +1484,15 @@ QFuture<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage stanza.setE2eeMetadata(decryptionResult.e2eeMetadata); - reportFinishedResult(interface, { stanza }); + interface.finish(stanza); } else { - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } }); } } - return interface.future(); + return interface.task(); } // @@ -1503,7 +1505,7 @@ QFuture<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage // // \return the serialized decrypted stanza if it could be decrypted // -QFuture<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomElement &iqElement) +QXmppTask<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomElement &iqElement) { using Result = std::optional<IqDecryptionResult>; @@ -1518,7 +1520,7 @@ QFuture<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomE subscribeToNewDeviceLists(senderJid, senderDeviceId); auto future = decryptStanza(iq, senderJid, senderDeviceId, *envelope, omemoElement.payload(), false); - return chain<Result>(future, q, [iqElement](auto result) -> Result { + return chain<Result>(std::move(future), q, [iqElement](auto result) -> Result { if (result) { auto decryptedElement = iqElement.cloneNode(true).toElement(); replaceChildElements(decryptedElement, result->sceContent); @@ -1528,7 +1530,7 @@ QFuture<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomE return {}; }); } - return makeReadyFuture<Result>(std::nullopt); + return makeReadyTask<Result>(std::nullopt); } // @@ -1549,15 +1551,15 @@ QFuture<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDomE // \return the result of the decryption if it succeeded // template<typename T> -QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) +QXmppTask<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) { - QFutureInterface<std::optional<DecryptionResult>> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<DecryptionResult>> interface; auto future = extractSceEnvelope(senderJid, senderDeviceId, omemoEnvelope, omemoPayload, isMessageStanza); - await(future, q, [=](QByteArray serializedSceEnvelope) mutable { + future.then(q, [=](QByteArray serializedSceEnvelope) mutable { if (serializedSceEnvelope.isEmpty()) { warning("SCE envelope could not be extracted"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { QDomDocument document; document.setContent(serializedSceEnvelope, true); @@ -1565,7 +1567,7 @@ QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, if (sceEnvelopeReader.from() != senderJid) { warning("Sender '" % senderJid % "' of stanza does not match SCE 'from' affix element '" % sceEnvelopeReader.from() % "'"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { const auto recipientJid = QXmppUtils::jidToBareJid(stanza.to()); auto isSceAffixElementValid = true; @@ -1583,7 +1585,7 @@ QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, } if (!isSceAffixElementValid) { - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { auto &device = devices[senderJid][senderDeviceId]; device.unrespondedSentStanzasCount = 0; @@ -1603,13 +1605,13 @@ QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, const auto &senderDevice = devices.value(senderJid).value(senderDeviceId); e2eeMetadata.setSenderKey(senderDevice.keyId); - reportFinishedResult(interface, { { sceEnvelopeReader.contentElement(), e2eeMetadata } }); + interface.finish(DecryptionResult { sceEnvelopeReader.contentElement(), e2eeMetadata }); } } } }); - return interface.future(); + return interface.task(); } // @@ -1627,21 +1629,24 @@ QFuture<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanza, // \return the serialized SCE envelope if it could be extracted, otherwise a // default-constructed byte array // -QFuture<QByteArray> ManagerPrivate::extractSceEnvelope(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) +QXmppTask<QByteArray> ManagerPrivate::extractSceEnvelope(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, const QByteArray &omemoPayload, bool isMessageStanza) { - QFutureInterface<QByteArray> interface(QFutureInterfaceBase::Started); + QXmppPromise<QByteArray> interface; auto future = extractPayloadDecryptionData(senderJid, senderDeviceId, omemoEnvelope, isMessageStanza); - await(future, q, [=](QCA::SecureArray payloadDecryptionData) mutable { - if (payloadDecryptionData.isEmpty()) { + future.then(q, [=](std::optional<QCA::SecureArray> payloadDecryptionData) mutable { + if (!payloadDecryptionData) { + warning("Data for decrypting OMEMO payload could not be extracted"); + interface.finish(QByteArray()); + } else if (payloadDecryptionData->isEmpty()) { warning("Data for decrypting OMEMO payload could not be extracted"); - reportFinishedResult(interface, {}); + interface.finish(QByteArray()); } else { - reportFinishedResult(interface, decryptPayload(payloadDecryptionData, omemoPayload)); + interface.finish(decryptPayload(*payloadDecryptionData, omemoPayload)); } }); - return interface.future(); + return interface.task(); } // @@ -1657,9 +1662,9 @@ QFuture<QByteArray> ManagerPrivate::extractSceEnvelope(const QString &senderJid, // \return the serialized payload decryption data if it could be extracted, otherwise a // default-constructed secure array // -QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, bool isMessageStanza) +QXmppTask<std::optional<QCA::SecureArray>> ManagerPrivate::extractPayloadDecryptionData(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, bool isMessageStanza) { - QFutureInterface<QCA::SecureArray> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<QCA::SecureArray>> interface; SessionCipherPtr sessionCipher; const auto address = Address(senderJid, senderDeviceId); @@ -1667,7 +1672,7 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt if (session_cipher_create(sessionCipher.ptrRef(), storeContext.get(), &addressData, globalContext.get()) < 0) { warning("Session cipher could not be created"); - return {}; + return makeReadyTask<std::optional<QCA::SecureArray>>(std::nullopt); } session_cipher_set_version(sessionCipher.get(), CIPHERTEXT_OMEMO_VERSION); @@ -1682,7 +1687,7 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt auto payloadDecryptionData = QCA::SecureArray(payloadDecryptionDataBufferSize); std::copy_n(payloadDecryptionDataPointer, payloadDecryptionDataBufferSize, payloadDecryptionData.data()); - reportFinishedResult(interface, payloadDecryptionData); + interface.finish(std::move(payloadDecryptionData)); }; // There are three cases: @@ -1702,13 +1707,13 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt senderDeviceId, globalContext.get()) < 0) { warning("OMEMO envelope data could not be deserialized"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { BufferPtr publicIdentityKeyBuffer; if (ec_public_key_serialize(publicIdentityKeyBuffer.ptrRef(), pre_key_signal_message_get_identity_key(omemoEnvelopeData.get())) < 0) { warning("Public Identity key could not be retrieved"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { const auto key = publicIdentityKeyBuffer.toByteArray(); auto &device = devices[senderJid][senderDeviceId]; @@ -1726,30 +1731,30 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt switch (session_cipher_decrypt_pre_key_signal_message(sessionCipher.get(), omemoEnvelopeData.get(), nullptr, payloadDecryptionDataBuffer.ptrRef())) { case SG_ERR_INVALID_MESSAGE: warning("OMEMO envelope data for key exchange is not valid"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_DUPLICATE_MESSAGE: warning("OMEMO envelope data for key exchange is already received"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_LEGACY_MESSAGE: warning("OMEMO envelope data for key exchange format is deprecated"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_INVALID_KEY_ID: { const auto preKeyId = QString::number(pre_key_signal_message_get_pre_key_id(omemoEnvelopeData.get())); warning("Pre key with ID '" % preKeyId % "' of OMEMO envelope data for key exchange could not be found locally"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; } case SG_ERR_INVALID_KEY: warning("OMEMO envelope data for key exchange is incorrectly formatted"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_UNTRUSTED_IDENTITY: warning("Identity key of OMEMO envelope data for key exchange is not trusted by OMEMO library"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_SUCCESS: reportResult(payloadDecryptionDataBuffer); @@ -1764,14 +1769,14 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt // Store the key's trust level if it is not stored yet. auto future = q->trustLevel(senderJid, storedKeyId); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { if (trustLevel == TrustLevel::Undecided) { auto future = storeKeyDependingOnSecurityPolicy(senderJid, key); - await(future, q, [=](auto) mutable { - interface.reportFinished(); + future.then(q, [=](auto) mutable { + interface.finish(std::nullopt); }); } else { - interface.reportFinished(); + interface.finish(std::nullopt); } }); } @@ -1782,8 +1787,8 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt "sending device, new session is being built"); auto future = buildSessionWithDeviceBundle(senderJid, senderDeviceId, device); - await(future, q, [=](auto) mutable { - reportFinishedResult(interface, {}); + future.then(q, [=](auto) mutable { + interface.finish(std::nullopt); }); } else { RefCountedPtr<signal_message> omemoEnvelopeData; @@ -1791,32 +1796,32 @@ QFuture<QCA::SecureArray> ManagerPrivate::extractPayloadDecryptionData(const QSt if (signal_message_deserialize_omemo(omemoEnvelopeData.ptrRef(), reinterpret_cast<const uint8_t *>(serializedOmemoEnvelopeData.data()), serializedOmemoEnvelopeData.size(), globalContext.get()) < 0) { warning("OMEMO envelope data could not be deserialized"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { // Decrypt the OMEMO envelope data. switch (session_cipher_decrypt_signal_message(sessionCipher.get(), omemoEnvelopeData.get(), nullptr, payloadDecryptionDataBuffer.ptrRef())) { case SG_ERR_INVALID_MESSAGE: warning("OMEMO envelope data is not valid"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_DUPLICATE_MESSAGE: warning("OMEMO envelope data is already received"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_LEGACY_MESSAGE: warning("OMEMO envelope data format is deprecated"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); break; case SG_ERR_NO_SESSION: warning("Session for OMEMO envelope data could not be found"); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); case SG_SUCCESS: reportResult(payloadDecryptionDataBuffer); } } } - return interface.future(); + return interface.task(); } // @@ -1881,16 +1886,16 @@ QByteArray ManagerPrivate::decryptPayload(const QCA::SecureArray &payloadDecrypt // // \return whether it succeeded // -QFuture<bool> ManagerPrivate::publishOmemoData() +QXmppTask<bool> ManagerPrivate::publishOmemoData() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; auto future = pubSubManager->requestOwnPepFeatures(); - await(future, q, [=](QXmppPubSubManager::FeaturesResult result) mutable { + future.then(q, [=](QXmppPubSubManager::FeaturesResult result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Features of PEP service '" % ownBareJid() % "' could not be retrieved: " % errorToString(*error)); warning("Device bundle and device list could not be published"); - reportFinishedResult(interface, false); + interface.finish(false); } else { const auto &pepServiceFeatures = std::get<QVector<QString>>(result); @@ -1904,13 +1909,13 @@ QFuture<bool> ManagerPrivate::publishOmemoData() // if (pepServiceFeatures.contains(ns_pubsub_publish) && pepServiceFeatures.contains(ns_pubsub_multi_items)) { if (pepServiceFeatures.contains(ns_pubsub_publish)) { auto future = pubSubManager->requestOwnPepNodes(); - await(future, q, [=](QXmppPubSubManager::NodesResult result) mutable { + future.then(q, [=](QXmppPubSubManager::NodesResult result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Nodes of JID '" % ownBareJid() % "' could not be fetched to check if nodes '" % QString(ns_omemo_2_bundles) % "' and '" % QString(ns_omemo_2_devices) % "' exist: " % errorToString(*error)); warning("Device bundle and device list could not be published"); - reportFinishedResult(interface, false); + interface.finish(false); } else { const auto &nodes = std::get<QVector<QString>>(result); @@ -1943,11 +1948,11 @@ QFuture<bool> ManagerPrivate::publishOmemoData() if (!isPublished) { warning("Device element could not be published"); } - reportFinishedResult(interface, isPublished); + interface.finish(std::move(isPublished)); }); } else { warning("Device bundle could not be published"); - reportFinishedResult(interface, false); + interface.finish(false); } }; publishDeviceBundle(nodes.contains(ns_omemo_2_bundles), @@ -1963,12 +1968,12 @@ QFuture<bool> ManagerPrivate::publishOmemoData() } else { warning("Publishing (multiple) items to PEP node '" % ownBareJid() % "' is not supported"); warning("Device bundle and device list could not be published"); - reportFinishedResult(interface, false); + interface.finish(false); } } }); - return interface.future(); + return interface.task(); } // @@ -2310,23 +2315,23 @@ QXmppOmemoDeviceBundleItem ManagerPrivate::deviceBundleItem() const // // \return the device bundle on success, otherwise a nullptr // -QFuture<std::optional<QXmppOmemoDeviceBundle>> ManagerPrivate::requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const +QXmppTask<std::optional<QXmppOmemoDeviceBundle>> ManagerPrivate::requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const { - QFutureInterface<std::optional<QXmppOmemoDeviceBundle>> interface(QFutureInterfaceBase::Started); + QXmppPromise<std::optional<QXmppOmemoDeviceBundle>> interface; auto future = pubSubManager->requestItem<QXmppOmemoDeviceBundleItem>(deviceOwnerJid, ns_omemo_2_bundles, QString::number(deviceId)); - await(future, q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceBundleItem> result) mutable { + future.then(q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceBundleItem> result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device bundle for JID '" % deviceOwnerJid % "' and device ID '" % QString::number(deviceId) % "' could not be retrieved: " % errorToString(*error)); - reportFinishedResult(interface, {}); + interface.finish(std::nullopt); } else { const auto &item = std::get<QXmppOmemoDeviceBundleItem>(result); - reportFinishedResult(interface, { item.deviceBundle() }); + interface.finish(item.deviceBundle()); } }); - return interface.future(); + return interface.task(); } // @@ -2620,7 +2625,7 @@ void ManagerPrivate::updateOwnDevicesLocally(bool isDeviceListNodeExistent, Func { if (isDeviceListNodeExistent && otherOwnDevices().isEmpty()) { auto future = pubSubManager->requestOwnPepItem<QXmppOmemoDeviceListItem>(ns_omemo_2_devices, QXmppPubSubManager::Current); - await(future, q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable { + future.then(q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device list for JID '" % ownBareJid() % "' could not be retrieved and thus not updated: " % @@ -2656,9 +2661,9 @@ void ManagerPrivate::updateOwnDevicesLocally(bool isDeviceListNodeExistent, Func device.label = deviceElement.label(); auto future = omemoStorage->addDevice(jid, deviceId, device); - await(future, q, [=, &device]() mutable { + future.then(q, [=, &device]() mutable { auto future = buildSessionForNewDevice(jid, deviceId, device); - await(future, q, [=](auto) mutable { + future.then(q, [=](auto) mutable { Q_EMIT q->deviceAdded(jid, deviceId); if (++(*processedDevicesCount) == devicesCount) { @@ -2805,7 +2810,7 @@ void ManagerPrivate::updateDevices(const QString &deviceOwnerJid, const QXmppOme omemoStorage->addDevice(deviceOwnerJid, deviceId, device); auto future = buildSessionForNewDevice(deviceOwnerJid, deviceId, device); - await(future, q, [=](auto) { + future.then(q, [=](auto) { Q_EMIT q->deviceAdded(deviceOwnerJid, deviceId); }); } @@ -2839,14 +2844,14 @@ void ManagerPrivate::handleIrregularDeviceListChanges(const QString &deviceOwner // item is removed, if their device list node is removed or if all // the node's items are removed. auto future = pubSubManager->deleteOwnPepNode(ns_omemo_2_devices); - await(future, q, [=](QXmppPubSubManager::Result result) { + future.then(q, [=](QXmppPubSubManager::Result result) { if (const auto error = std::get_if<Error>(&result)) { warning("Node '" % QString(ns_omemo_2_devices) % "' of JID '" % deviceOwnerJid % "' could not be deleted in order to recover from an inconsistent node: " % errorToString(*error)); } else { auto future = pubSubManager->requestOwnPepFeatures(); - await(future, q, [=](QXmppPubSubManager::FeaturesResult result) { + future.then(q, [=](QXmppPubSubManager::FeaturesResult result) { if (const auto error = std::get_if<Error>(&result)) { warning("Features of PEP service '" % deviceOwnerJid % "' could not be retrieved: " % errorToString(*error)); @@ -2979,7 +2984,7 @@ template<typename Function> void ManagerPrivate::deleteNode(const QString &node, Function continuation) { auto future = pubSubManager->deleteOwnPepNode(node); - await(future, q, [=, continuation = std::move(continuation)](QXmppPubSubManager::Result result) mutable { + future.then(q, [=, continuation = std::move(continuation)](QXmppPubSubManager::Result result) mutable { const auto error = std::get_if<Error>(&result); if (error) { const auto errorType = error->type(); @@ -3040,9 +3045,9 @@ void ManagerPrivate::publishItem(const QString &node, const T &item, const QXmpp // \param continuation function to be called after the PubSub query // template<typename T, typename Function> -void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QFuture<T> future, const QString &errorMessage, Function continuation) +void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QXmppTask<T> future, const QString &errorMessage, Function continuation) { - await(future, q, [this, errorMessage, continuation = std::move(continuation)](auto result) mutable { + future.then(q, [this, errorMessage, continuation = std::move(continuation)](auto result) mutable { if (auto error = std::get_if<Error>(&result)) { warning(errorMessage % u": " % errorToString(*error)); continuation(false); @@ -3053,24 +3058,24 @@ void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QFuture<T> future, } // See QXmppOmemoManager for documentation -QFuture<bool> ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) +QXmppTask<bool> ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; ownDevice.label = deviceLabel; if (isStarted) { auto future = omemoStorage->setOwnDevice(ownDevice); - await(future, q, [=]() mutable { + future.then(q, [=]() mutable { publishDeviceListItem(true, [=](bool isPublished) mutable { - reportFinishedResult(interface, isPublished); + interface.finish(std::move(isPublished)); }); }); } else { - reportFinishedResult(interface, true); + interface.finish(true); } - return interface.future(); + return interface.task(); } // @@ -3084,10 +3089,10 @@ QFuture<bool> ManagerPrivate::changeDeviceLabel(const QString &deviceLabel) // // \return the result of the request // -QFuture<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> ManagerPrivate::requestDeviceList(const QString &jid) +QXmppTask<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> ManagerPrivate::requestDeviceList(const QString &jid) { auto future = pubSubManager->requestItem<QXmppOmemoDeviceListItem>(jid, ns_omemo_2_devices, QXmppPubSubManager::Current); - await(future, q, [this, jid](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable { + future.then(q, [this, jid](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device list for JID '" % jid % "' could not be retrieved: " % errorToString(*error)); } else { @@ -3122,26 +3127,26 @@ void ManagerPrivate::subscribeToNewDeviceLists(const QString &jid, uint32_t devi // // \return the result of the subscription and manual request // -QFuture<QXmppPubSubManager::Result> ManagerPrivate::subscribeToDeviceList(const QString &jid) +QXmppTask<QXmppPubSubManager::Result> ManagerPrivate::subscribeToDeviceList(const QString &jid) { - QFutureInterface<QXmppPubSubManager::Result> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppPubSubManager::Result> interface; auto future = pubSubManager->subscribeToNode(jid, ns_omemo_2_devices, ownFullJid()); - await(future, q, [=](QXmppPubSubManager::Result result) mutable { + future.then(q, [=](QXmppPubSubManager::Result result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device list for JID '" % jid % "' could not be subscribed: " % errorToString(*error)); - reportFinishedResult(interface, { *error }); + interface.finish(*error); } else { jidsOfManuallySubscribedDevices.append(jid); auto future = requestDeviceList(jid); - await(future, q, [=](auto result) mutable { - reportFinishedResult(interface, mapToSuccess(std::move(result))); + future.then(q, [=](auto result) mutable { + interface.finish(mapToSuccess(std::move(result))); }); } }); - return interface.future(); + return interface.task(); } // @@ -3154,16 +3159,17 @@ QFuture<QXmppPubSubManager::Result> ManagerPrivate::subscribeToDeviceList(const // // \return the results of each unsubscribe request // -QFuture<QVector<Manager::DevicesResult>> ManagerPrivate::unsubscribeFromDeviceLists(const QList<QString> &jids) +QXmppTask<QVector<Manager::DevicesResult>> ManagerPrivate::unsubscribeFromDeviceLists(const QList<QString> &jids) { if (jids.isEmpty()) { - return makeReadyFuture(QVector<Manager::DevicesResult>()); + return makeReadyTask(QVector<Manager::DevicesResult>()); } - struct State { + struct State + { int processed = 0; int jidsCount = 0; - QFutureInterface<QVector<Manager::DevicesResult>> interface; + QXmppPromise<QVector<Manager::DevicesResult>> interface; QVector<Manager::DevicesResult> devicesResults; }; @@ -3171,19 +3177,18 @@ QFuture<QVector<Manager::DevicesResult>> ManagerPrivate::unsubscribeFromDeviceLi state->jidsCount = jids.count(); for (const auto &jid : jids) { - await(unsubscribeFromDeviceList(jid), q, [jid, state](QXmppPubSubManager::Result result) mutable { + unsubscribeFromDeviceList(jid).then(q, [jid, state](QXmppPubSubManager::Result result) mutable { state->devicesResults << Manager::DevicesResult { jid, result }; if (++(state->processed) == state->jidsCount) { - state->interface.reportResult(state->devicesResults); - state->interface.reportFinished(); + state->interface.finish(std::move(state->devicesResults)); } }); } - return state->interface.future(); + return state->interface.task(); } // @@ -3195,35 +3200,35 @@ QFuture<QVector<Manager::DevicesResult>> ManagerPrivate::unsubscribeFromDeviceLi // // \return the result of the unsubscription // -QFuture<QXmppPubSubManager::Result> ManagerPrivate::unsubscribeFromDeviceList(const QString &jid) +QXmppTask<QXmppPubSubManager::Result> ManagerPrivate::unsubscribeFromDeviceList(const QString &jid) { - QFutureInterface<QXmppPubSubManager::Result> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmppPubSubManager::Result> interface; auto future = pubSubManager->unsubscribeFromNode(jid, ns_omemo_2_devices, ownFullJid()); - await(future, q, [=](QXmppPubSubManager::Result result) mutable { + future.then(q, [=](QXmppPubSubManager::Result result) mutable { if (const auto error = std::get_if<Error>(&result)) { warning("Device list for JID '" % jid % "' could not be unsubscribed: " % errorToString(*error)); } else { jidsOfManuallySubscribedDevices.removeAll(jid); } - reportFinishedResult(interface, result); + interface.finish(std::move(result)); }); - return interface.future(); + return interface.task(); } // See QXmppOmemoManager for documentation -QFuture<bool> ManagerPrivate::resetOwnDevice() +QXmppTask<bool> ManagerPrivate::resetOwnDevice() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; isStarted = false; auto future = trustManager->resetAll(ns_omemo_2); - await(future, q, [=]() mutable { + future.then(q, [=]() mutable { auto future = omemoStorage->resetAll(); - await(future, q, [=]() mutable { + future.then(q, [=]() mutable { deleteDeviceElement([=](bool isDeviceElementDeleted) mutable { if (isDeviceElementDeleted) { deleteDeviceBundle([=](bool isDeviceBundleDeleted) mutable { @@ -3237,29 +3242,29 @@ QFuture<bool> ManagerPrivate::resetOwnDevice() Q_EMIT q->allDevicesRemoved(); } - reportFinishedResult(interface, isDeviceBundleDeleted); + interface.finish(std::move(isDeviceBundleDeleted)); }); } else { - reportFinishedResult(interface, false); + interface.finish(false); } }); }); }); - return interface.future(); + return interface.task(); } // See QXmppOmemoManager for documentation -QFuture<bool> ManagerPrivate::resetAll() +QXmppTask<bool> ManagerPrivate::resetAll() { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; isStarted = false; auto future = trustManager->resetAll(ns_omemo_2); - await(future, q, [this, interface]() mutable { + future.then(q, [this, interface]() mutable { auto future = omemoStorage->resetAll(); - await(future, q, [this, interface]() mutable { + future.then(q, [this, interface]() mutable { deleteNode(ns_omemo_2_devices, [this, interface](bool isDevicesNodeDeleted) mutable { if (isDevicesNodeDeleted) { deleteNode(ns_omemo_2_bundles, [this, interface](bool isBundlesNodeDeleted) mutable { @@ -3273,16 +3278,16 @@ QFuture<bool> ManagerPrivate::resetAll() Q_EMIT q->allDevicesRemoved(); } - reportFinishedResult(interface, isBundlesNodeDeleted); + interface.finish(std::move(isBundlesNodeDeleted)); }); } else { - reportFinishedResult(interface, false); + interface.finish(false); } }); }); }); - return interface.future(); + return interface.task(); } // @@ -3297,12 +3302,12 @@ QFuture<bool> ManagerPrivate::resetAll() // \return true if a session could be built or it is not enabled, otherwise // false // -QFuture<bool> ManagerPrivate::buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) +QXmppTask<bool> ManagerPrivate::buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) { if (isNewDeviceAutoSessionBuildingEnabled) { return buildSessionWithDeviceBundle(jid, deviceId, device); } else { - return makeReadyFuture(true); + return makeReadyTask(true); } } @@ -3315,19 +3320,19 @@ QFuture<bool> ManagerPrivate::buildSessionForNewDevice(const QString &jid, uint3 // // \return whether a session could be built // -QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) +QXmppTask<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device) { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; auto future = requestDeviceBundle(jid, deviceId); - await(future, q, [=, &device](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { + future.then(q, [=, &device](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable { if (optionalDeviceBundle) { const auto &deviceBundle = *optionalDeviceBundle; const auto key = deviceBundle.publicIdentityKey(); device.keyId = createKeyId(key); auto future = q->trustLevel(jid, device.keyId); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { auto buildSessionDependingOnTrustLevel = [=](TrustLevel trustLevel) mutable { // Build a session if the device's key has a specific trust // level and send an empty OMEMO (key exchange) message to @@ -3336,20 +3341,20 @@ QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u warning("Session could not be created for JID '" % jid % "' with device ID '" % QString::number(deviceId) % "' because its key's trust level '" % QString::number(int(trustLevel)) % "' is not accepted"); - reportFinishedResult(interface, false); + interface.finish(false); } else if (const auto address = Address(jid, deviceId); !buildSession(address.data(), deviceBundle)) { warning("Session could not be created for JID '" % jid % "' and device ID '" % QString::number(deviceId) % "'"); - reportFinishedResult(interface, false); + interface.finish(false); } else { auto future = sendEmptyMessage(jid, deviceId, true); - await(future, q, [=](QXmpp::SendResult result) mutable { + future.then(q, [=](QXmpp::SendResult result) mutable { if (std::holds_alternative<QXmppError>(result)) { warning("Session could be created but empty message could not be sent to JID '" % jid % "' and device ID '" % QString::number(deviceId) % "'"); - reportFinishedResult(interface, false); + interface.finish(false); } else { - reportFinishedResult(interface, true); + interface.finish(true); } }); } @@ -3358,7 +3363,7 @@ QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u if (trustLevel == TrustLevel::Undecided) { // Store the key's trust level if it is not stored yet. auto future = storeKeyDependingOnSecurityPolicy(jid, key); - await(future, q, [=](TrustLevel trustLevel) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { buildSessionDependingOnTrustLevel(trustLevel); }); } else { @@ -3369,11 +3374,11 @@ QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u warning("Session could not be created because no device bundle could be fetched for " "JID '" % jid % "' and device ID '" % QString::number(deviceId) % "'"); - reportFinishedResult(interface, false); + interface.finish(false); } }); - return interface.future(); + return interface.task(); } // @@ -3388,7 +3393,7 @@ QFuture<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid, u // bool ManagerPrivate::buildSession(signal_protocol_address address, const QXmppOmemoDeviceBundle &deviceBundle) { - QFutureInterface<bool> interface(QFutureInterfaceBase::Started); + QXmppPromise<bool> interface; // Choose a pre key randomly. const auto publicPreKeys = deviceBundle.publicPreKeys(); @@ -3577,9 +3582,9 @@ bool ManagerPrivate::deserializePublicPreKey(ec_public_key **publicPreKey, const // // \return the result of the sending // -QFuture<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange) const +QXmppTask<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange) const { - QFutureInterface<QXmpp::SendResult> interface(QFutureInterfaceBase::Started); + QXmppPromise<QXmpp::SendResult> interface; const auto address = Address(recipientJid, recipientDeviceId); const auto decryptionData = QCA::SecureArray(EMPTY_MESSAGE_DECRYPTION_DATA_SIZE); @@ -3592,7 +3597,7 @@ QFuture<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recip QStringLiteral("OMEMO envelope could not be created"), SendError::EncryptionError }; - reportFinishedResult(interface, { error }); + interface.finish(error); } else { QXmppOmemoEnvelope omemoEnvelope; omemoEnvelope.setRecipientDeviceId(recipientDeviceId); @@ -3611,12 +3616,12 @@ QFuture<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recip message.setOmemoElement(omemoElement); auto future = q->client()->sendUnencrypted(std::move(message)); - await(future, q, [=](QXmpp::SendResult result) mutable { - reportFinishedResult(interface, result); + future.then(q, [=](QXmpp::SendResult result) mutable { + interface.finish(std::move(result)); }); } - return interface.future(); + return interface.task(); } // @@ -3627,16 +3632,16 @@ QFuture<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &recip // It corresponds to the fingerprint shown to users which also does not contain // the first byte. // -QFuture<void> ManagerPrivate::storeOwnKey() const +QXmppTask<void> ManagerPrivate::storeOwnKey() const { - QFutureInterface<void> interface(QFutureInterfaceBase::Started); + QXmppPromise<void> interface; auto future = trustManager->setOwnKey(ns_omemo_2, createKeyId(ownDevice.publicIdentityKey)); - await(future, q, [=]() mutable { - interface.reportFinished(); + future.then(q, [=]() mutable { + interface.finish(); }); - return interface.future(); + return interface.task(); } // @@ -3648,18 +3653,18 @@ QFuture<void> ManagerPrivate::storeOwnKey() const // // \return the trust level of the stored key // -QFuture<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key) +QXmppTask<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key) { - QFutureInterface<TrustLevel> interface(QFutureInterfaceBase::Started); + QXmppPromise<TrustLevel> interface; - auto awaitStoreKey = [=](const QFuture<TrustLevel> &future) mutable { - await(future, q, [=](TrustLevel trustLevel) mutable { - reportFinishedResult(interface, trustLevel); + auto awaitStoreKey = [=](QXmppTask<TrustLevel> &future) mutable { + future.then(q, [=](TrustLevel trustLevel) mutable { + interface.finish(std::move(trustLevel)); }); }; auto future = q->securityPolicy(); - await(future, q, [=](TrustSecurityPolicy securityPolicy) mutable { + future.then(q, [=](TrustSecurityPolicy securityPolicy) mutable { switch (securityPolicy) { case NoSecurityPolicy: { auto future = storeKey(keyOwnerJid, key); @@ -3668,7 +3673,7 @@ QFuture<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QStr } case Toakafa: { auto future = trustManager->hasKey(ns_omemo_2, keyOwnerJid, TrustLevel::Authenticated); - await(future, q, [=](bool hasAuthenticatedKey) mutable { + future.then(q, [=](bool hasAuthenticatedKey) mutable { if (hasAuthenticatedKey) { // If there is at least one authenticated key, add the // new key as an automatically distrusted one. @@ -3688,7 +3693,7 @@ QFuture<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QStr } }); - return interface.future(); + return interface.task(); } // @@ -3700,17 +3705,17 @@ QFuture<TrustLevel> ManagerPrivate::storeKeyDependingOnSecurityPolicy(const QStr // // \return the trust level of the stored key // -QFuture<TrustLevel> ManagerPrivate::storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel) const +QXmppTask<TrustLevel> ManagerPrivate::storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel) const { - QFutureInterface<TrustLevel> interface(QFutureInterfaceBase::Started); + QXmppPromise<TrustLevel> interface; auto future = trustManager->addKeys(ns_omemo_2, keyOwnerJid, { createKeyId(key) }, trustLevel); - await(future, q, [=]() mutable { + future.then(q, [=]() mutable { Q_EMIT q->trustLevelsChanged({ { keyOwnerJid, key } }); - reportFinishedResult(interface, trustLevel); + interface.finish(std::move(trustLevel)); }); - return interface.future(); + return interface.task(); } // diff --git a/src/omemo/QXmppOmemoManager_p.h b/src/omemo/QXmppOmemoManager_p.h index 78cf482f..bce22042 100644 --- a/src/omemo/QXmppOmemoManager_p.h +++ b/src/omemo/QXmppOmemoManager_p.h @@ -10,6 +10,7 @@ #include "QXmppOmemoDeviceBundle_p.h" #include "QXmppOmemoManager.h" #include "QXmppOmemoStorage.h" +#include "QXmppPubSubManager.h" #include "OmemoLibWrappers.h" #include "QcaInitializer_p.h" @@ -177,7 +178,7 @@ public: signal_protocol_pre_key_store createPreKeyStore() const; signal_protocol_session_store createSessionStore() const; - QFuture<bool> setUpDeviceId(); + QXmppTask<bool> setUpDeviceId(); std::optional<uint32_t> generateDeviceId(); std::optional<uint32_t> generateDeviceId(const QVector<QString> &existingIds); bool setUpIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair); @@ -189,37 +190,37 @@ public: void removeDevicesRemovedFromServer(); bool generateIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair) const; - QFuture<QXmppE2eeExtension::MessageEncryptResult> encryptMessageForRecipients(QXmppMessage &&message, - QVector<QString> recipientJids, - TrustLevels acceptedTrustLevels); + QXmppTask<QXmppE2eeExtension::MessageEncryptResult> encryptMessageForRecipients(QXmppMessage &&message, + QVector<QString> recipientJids, + TrustLevels acceptedTrustLevels); template<typename T> - QFuture<std::optional<QXmppOmemoElement>> encryptStanza(const T &stanza, const QVector<QString> &recipientJids, TrustLevels acceptedTrustLevels); + QXmppTask<std::optional<QXmppOmemoElement>> encryptStanza(const T &stanza, const QVector<QString> &recipientJids, TrustLevels acceptedTrustLevels); std::optional<PayloadEncryptionResult> encryptPayload(const QByteArray &payload) const; template<typename T> QByteArray createSceEnvelope(const T &stanza); QByteArray createOmemoEnvelopeData(const signal_protocol_address &address, const QCA::SecureArray &payloadDecryptionData) const; - QFuture<std::optional<QXmppMessage>> decryptMessage(QXmppMessage stanza); - QFuture<std::optional<IqDecryptionResult>> decryptIq(const QDomElement &iqElement); + QXmppTask<std::optional<QXmppMessage>> decryptMessage(QXmppMessage stanza); + QXmppTask<std::optional<IqDecryptionResult>> decryptIq(const QDomElement &iqElement); template<typename T> - QFuture<std::optional<DecryptionResult>> decryptStanza(T stanza, - const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - const QByteArray &omemoPayload, - bool isMessageStanza = true); - QFuture<QByteArray> extractSceEnvelope(const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - const QByteArray &omemoPayload, - bool isMessageStanza); - QFuture<QCA::SecureArray> extractPayloadDecryptionData(const QString &senderJid, - uint32_t senderDeviceId, - const QXmppOmemoEnvelope &omemoEnvelope, - bool isMessageStanza = true); + QXmppTask<std::optional<DecryptionResult>> decryptStanza(T stanza, + const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + const QByteArray &omemoPayload, + bool isMessageStanza = true); + QXmppTask<QByteArray> extractSceEnvelope(const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + const QByteArray &omemoPayload, + bool isMessageStanza); + QXmppTask<std::optional<QCA::SecureArray>> extractPayloadDecryptionData(const QString &senderJid, + uint32_t senderDeviceId, + const QXmppOmemoEnvelope &omemoEnvelope, + bool isMessageStanza = true); QByteArray decryptPayload(const QCA::SecureArray &payloadDecryptionData, const QByteArray &payload) const; - QFuture<bool> publishOmemoData(); + QXmppTask<bool> publishOmemoData(); template<typename Function> void publishDeviceBundle(bool isDeviceBundlesNodeExistent, @@ -250,7 +251,7 @@ public: template<typename Function> void publishDeviceBundleItemWithOptions(Function continuation); QXmppOmemoDeviceBundleItem deviceBundleItem() const; - QFuture<std::optional<QXmppOmemoDeviceBundle>> requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const; + QXmppTask<std::optional<QXmppOmemoDeviceBundle>> requestDeviceBundle(const QString &deviceOwnerJid, uint32_t deviceId) const; template<typename Function> void deleteDeviceBundle(Function continuation); @@ -305,21 +306,21 @@ public: void publishItem(const QString &node, const T &item, const QXmppPubSubPublishOptions &publishOptions, Function continuation); template<typename T, typename Function> - void runPubSubQueryWithContinuation(QFuture<T> future, const QString &errorMessage, Function continuation); + void runPubSubQueryWithContinuation(QXmppTask<T> future, const QString &errorMessage, Function continuation); - QFuture<bool> changeDeviceLabel(const QString &deviceLabel); + QXmppTask<bool> changeDeviceLabel(const QString &deviceLabel); - QFuture<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> requestDeviceList(const QString &jid); + QXmppTask<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> requestDeviceList(const QString &jid); void subscribeToNewDeviceLists(const QString &jid, uint32_t deviceId); - QFuture<Result> subscribeToDeviceList(const QString &jid); - QFuture<QVector<QXmppOmemoManager::DevicesResult>> unsubscribeFromDeviceLists(const QList<QString> &jids); - QFuture<Result> unsubscribeFromDeviceList(const QString &jid); + QXmppTask<Result> subscribeToDeviceList(const QString &jid); + QXmppTask<QVector<QXmppOmemoManager::DevicesResult>> unsubscribeFromDeviceLists(const QList<QString> &jids); + QXmppTask<Result> unsubscribeFromDeviceList(const QString &jid); - QFuture<bool> resetOwnDevice(); - QFuture<bool> resetAll(); + QXmppTask<bool> resetOwnDevice(); + QXmppTask<bool> resetAll(); - QFuture<bool> buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); - QFuture<bool> buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); + QXmppTask<bool> buildSessionForNewDevice(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); + QXmppTask<bool> buildSessionWithDeviceBundle(const QString &jid, uint32_t deviceId, QXmppOmemoStorage::Device &device); bool buildSession(signal_protocol_address address, const QXmppOmemoDeviceBundle &deviceBundle); bool createSessionBundle(session_pre_key_bundle **sessionBundle, const QByteArray &serializedPublicIdentityKey, @@ -332,10 +333,10 @@ public: bool deserializeSignedPublicPreKey(ec_public_key **signedPublicPreKey, const QByteArray &serializedSignedPublicPreKey) const; bool deserializePublicPreKey(ec_public_key **publicPreKey, const QByteArray &serializedPublicPreKey) const; - QFuture<QXmpp::SendResult> sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange = false) const; - QFuture<void> storeOwnKey() const; - QFuture<TrustLevel> storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key); - QFuture<TrustLevel> storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel = TrustLevel::AutomaticallyDistrusted) const; + QXmppTask<QXmpp::SendResult> sendEmptyMessage(const QString &recipientJid, uint32_t recipientDeviceId, bool isKeyExchange = false) const; + QXmppTask<void> storeOwnKey() const; + QXmppTask<TrustLevel> storeKeyDependingOnSecurityPolicy(const QString &keyOwnerJid, const QByteArray &key); + QXmppTask<TrustLevel> storeKey(const QString &keyOwnerJid, const QByteArray &key, TrustLevel trustLevel = TrustLevel::AutomaticallyDistrusted) const; QString ownBareJid() const; QString ownFullJid() const; QHash<uint32_t, QXmppOmemoStorage::Device> otherOwnDevices(); diff --git a/src/omemo/QXmppOmemoMemoryStorage.cpp b/src/omemo/QXmppOmemoMemoryStorage.cpp index 6ff81002..6ccf7332 100644 --- a/src/omemo/QXmppOmemoMemoryStorage.cpp +++ b/src/omemo/QXmppOmemoMemoryStorage.cpp @@ -47,51 +47,51 @@ QXmppOmemoMemoryStorage::QXmppOmemoMemoryStorage() QXmppOmemoMemoryStorage::~QXmppOmemoMemoryStorage() = default; /// \cond -QFuture<QXmppOmemoStorage::OmemoData> QXmppOmemoMemoryStorage::allData() +QXmppTask<QXmppOmemoStorage::OmemoData> QXmppOmemoMemoryStorage::allData() { - return makeReadyFuture(std::move(OmemoData { d->ownDevice, - d->signedPreKeyPairs, - d->preKeyPairs, - d->devices })); + return makeReadyTask(std::move(OmemoData { d->ownDevice, + d->signedPreKeyPairs, + d->preKeyPairs, + d->devices })); } -QFuture<void> QXmppOmemoMemoryStorage::setOwnDevice(const std::optional<OwnDevice> &device) +QXmppTask<void> QXmppOmemoMemoryStorage::setOwnDevice(const std::optional<OwnDevice> &device) { d->ownDevice = device; - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::addSignedPreKeyPair(const uint32_t keyId, const SignedPreKeyPair &keyPair) +QXmppTask<void> QXmppOmemoMemoryStorage::addSignedPreKeyPair(const uint32_t keyId, const SignedPreKeyPair &keyPair) { d->signedPreKeyPairs.insert(keyId, keyPair); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::removeSignedPreKeyPair(const uint32_t keyId) +QXmppTask<void> QXmppOmemoMemoryStorage::removeSignedPreKeyPair(const uint32_t keyId) { d->signedPreKeyPairs.remove(keyId); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) +QXmppTask<void> QXmppOmemoMemoryStorage::addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) { d->preKeyPairs.insert(keyPairs); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::removePreKeyPair(const uint32_t keyId) +QXmppTask<void> QXmppOmemoMemoryStorage::removePreKeyPair(const uint32_t keyId) { d->preKeyPairs.remove(keyId); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::addDevice(const QString &jid, const uint32_t deviceId, const QXmppOmemoStorage::Device &device) +QXmppTask<void> QXmppOmemoMemoryStorage::addDevice(const QString &jid, const uint32_t deviceId, const QXmppOmemoStorage::Device &device) { d->devices[jid].insert(deviceId, device); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const uint32_t deviceId) +QXmppTask<void> QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const uint32_t deviceId) { auto &devices = d->devices[jid]; devices.remove(deviceId); @@ -102,18 +102,18 @@ QFuture<void> QXmppOmemoMemoryStorage::removeDevice(const QString &jid, const ui d->devices.remove(jid); } - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::removeDevices(const QString &jid) +QXmppTask<void> QXmppOmemoMemoryStorage::removeDevices(const QString &jid) { d->devices.remove(jid); - return makeReadyFuture(); + return makeReadyTask(); } -QFuture<void> QXmppOmemoMemoryStorage::resetAll() +QXmppTask<void> QXmppOmemoMemoryStorage::resetAll() { d.reset(new QXmppOmemoMemoryStoragePrivate()); - return makeReadyFuture(); + return makeReadyTask(); } /// \endcond diff --git a/src/omemo/QXmppOmemoMemoryStorage.h b/src/omemo/QXmppOmemoMemoryStorage.h index 9e2c89c6..f9d9b8a1 100644 --- a/src/omemo/QXmppOmemoMemoryStorage.h +++ b/src/omemo/QXmppOmemoMemoryStorage.h @@ -6,6 +6,7 @@ #define QXMPPOMEMOMEMORYSTORAGE_H #include "QXmppOmemoStorage.h" +#include "QXmppTask.h" #include "qxmppomemo_export.h" #include <memory> @@ -19,21 +20,21 @@ public: ~QXmppOmemoMemoryStorage() override; /// \cond - QFuture<OmemoData> allData() override; + QXmppTask<OmemoData> allData() override; - QFuture<void> setOwnDevice(const std::optional<OwnDevice> &device) override; + QXmppTask<void> setOwnDevice(const std::optional<OwnDevice> &device) override; - QFuture<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) override; - QFuture<void> removeSignedPreKeyPair(uint32_t keyId) override; + QXmppTask<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) override; + QXmppTask<void> removeSignedPreKeyPair(uint32_t keyId) override; - QFuture<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) override; - QFuture<void> removePreKeyPair(uint32_t keyId) override; + QXmppTask<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) override; + QXmppTask<void> removePreKeyPair(uint32_t keyId) override; - QFuture<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) override; - QFuture<void> removeDevice(const QString &jid, uint32_t deviceId) override; - QFuture<void> removeDevices(const QString &jid) override; + QXmppTask<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) override; + QXmppTask<void> removeDevice(const QString &jid, uint32_t deviceId) override; + QXmppTask<void> removeDevices(const QString &jid) override; - QFuture<void> resetAll() override; + QXmppTask<void> resetAll() override; /// \endcond private: diff --git a/src/omemo/QXmppOmemoStorage.h b/src/omemo/QXmppOmemoStorage.h index e3139544..3049c0df 100644 --- a/src/omemo/QXmppOmemoStorage.h +++ b/src/omemo/QXmppOmemoStorage.h @@ -5,6 +5,7 @@ #ifndef QXMPPOMEMOSTORAGE_H #define QXMPPOMEMOSTORAGE_H +#include "QXmppTask.h" #include "qxmppomemo_export.h" #include <optional> @@ -154,21 +155,21 @@ public: virtual ~QXmppOmemoStorage() = default; - virtual QFuture<OmemoData> allData() = 0; + virtual QXmppTask<OmemoData> allData() = 0; - virtual QFuture<void> setOwnDevice(const std::optional<OwnDevice> &device) = 0; + virtual QXmppTask<void> setOwnDevice(const std::optional<OwnDevice> &device) = 0; - virtual QFuture<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) = 0; - virtual QFuture<void> removeSignedPreKeyPair(uint32_t keyId) = 0; + virtual QXmppTask<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) = 0; + virtual QXmppTask<void> removeSignedPreKeyPair(uint32_t keyId) = 0; - virtual QFuture<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) = 0; - virtual QFuture<void> removePreKeyPair(uint32_t keyId) = 0; + virtual QXmppTask<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) = 0; + virtual QXmppTask<void> removePreKeyPair(uint32_t keyId) = 0; - virtual QFuture<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) = 0; - virtual QFuture<void> removeDevice(const QString &jid, uint32_t deviceId) = 0; - virtual QFuture<void> removeDevices(const QString &jid) = 0; + virtual QXmppTask<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) = 0; + virtual QXmppTask<void> removeDevice(const QString &jid, uint32_t deviceId) = 0; + virtual QXmppTask<void> removeDevices(const QString &jid) = 0; - virtual QFuture<void> resetAll() = 0; + virtual QXmppTask<void> resetAll() = 0; }; #endif // QXMPPOMEMOSTORAGE_H |
