diff options
-rw-r--r-- | lib/eventitem.h | 7 | ||||
-rw-r--r-- | lib/events/callanswerevent.cpp | 32 | ||||
-rw-r--r-- | lib/events/callanswerevent.h | 33 | ||||
-rw-r--r-- | lib/events/callcandidatesevent.cpp | 27 | ||||
-rw-r--r-- | lib/events/callcandidatesevent.h | 31 | ||||
-rw-r--r-- | lib/events/callhangupevent.cpp | 11 | ||||
-rw-r--r-- | lib/events/callhangupevent.h | 20 | ||||
-rw-r--r-- | lib/events/callinviteevent.cpp | 20 | ||||
-rw-r--r-- | lib/events/callinviteevent.h | 41 | ||||
-rw-r--r-- | lib/events/event.h | 17 | ||||
-rw-r--r-- | lib/events/roomevent.cpp | 22 | ||||
-rw-r--r-- | lib/events/roomevent.h | 14 | ||||
-rw-r--r-- | lib/room.cpp | 62 | ||||
-rw-r--r-- | lib/room.h | 6 |
14 files changed, 129 insertions, 214 deletions
diff --git a/lib/eventitem.h b/lib/eventitem.h index 6bec5a7f..5f1d10c9 100644 --- a/lib/eventitem.h +++ b/lib/eventitem.h @@ -98,6 +98,13 @@ namespace QMatrixClient : nullptr; } + template<> + inline const CallEventBase* EventItemBase::viewAs<CallEventBase>() const + { + return evt->isCallEvent() ? weakPtrCast<const CallEventBase>(evt) + : nullptr; + } + class PendingEventItem : public EventItemBase { Q_GADGET diff --git a/lib/events/callanswerevent.cpp b/lib/events/callanswerevent.cpp index c28ad305..d2862241 100644 --- a/lib/events/callanswerevent.cpp +++ b/lib/events/callanswerevent.cpp @@ -48,29 +48,25 @@ m.call.answer using namespace QMatrixClient; CallAnswerEvent::CallAnswerEvent(const QJsonObject& obj) - : RoomEvent(typeId(), obj) - , _lifetime(contentJson()["lifetime"].toInt()) - , _sdp(contentJson()["answer"].toObject()["sdp"].toString()) - , _callId(contentJson()["call_id"].toString()) - , _version(contentJson()["version"].toInt()) + : CallEventBase(typeId(), obj) { qCDebug(EVENTS) << "Call Answer event"; } CallAnswerEvent::CallAnswerEvent(const QString& callId, const int lifetime, const QString& sdp) - : RoomEvent(typeId(), NULL) -{ - _version = 0; - _callId = callId; - _lifetime = lifetime; - _sdp = sdp; -} + : CallEventBase(typeId(), matrixTypeId(), callId, 0, + { { QStringLiteral("lifetime"), lifetime } + , { QStringLiteral("answer"), QJsonObject { + { QStringLiteral("type"), QStringLiteral("answer") }, + { QStringLiteral("sdp"), sdp } } } + }) +{ } CallAnswerEvent::CallAnswerEvent(const QString& callId, const QString& sdp) - : RoomEvent(typeId(), NULL) -{ - _version = 0; - _callId = callId; - _sdp = sdp; -} + : CallEventBase(typeId(), matrixTypeId(), callId, 0, + { { QStringLiteral("answer"), QJsonObject { + { QStringLiteral("type"), QStringLiteral("answer") }, + { QStringLiteral("sdp"), sdp } } } + }) +{ } diff --git a/lib/events/callanswerevent.h b/lib/events/callanswerevent.h index b5b47899..2d9e5bb0 100644 --- a/lib/events/callanswerevent.h +++ b/lib/events/callanswerevent.h @@ -22,7 +22,7 @@ namespace QMatrixClient { - class CallAnswerEvent: public RoomEvent + class CallAnswerEvent: public CallEventBase { public: DEFINE_EVENT_TYPEID("m.call.answer", CallAnswerEvent) @@ -33,34 +33,11 @@ namespace QMatrixClient const QString& sdp); explicit CallAnswerEvent(const QString& callId, const QString& sdp); - bool isStateEvent() const override { return true; } - - const int lifetime() const { return _lifetime; } - const QString& sdp() const { return _sdp; } - const QString& callId() const { return _callId; } - const int version() const { return _version; } - - QJsonObject toJson() const - { - QJsonObject answer; - answer.insert("sdp", _sdp); - answer.insert("type", QStringLiteral("answer")); - - QJsonObject obj; - obj.insert("call_id", _callId); - obj.insert("version", _version); - if (_lifetime != NULL) - obj.insert("lifetime", _lifetime); - obj.insert("answer", answer); - return obj; + int lifetime() const { return content<int>("lifetime"_ls); } // FIXME: Omittable<>? + QString sdp() const { + return contentJson()["answer"_ls].toObject() + .value("sdp"_ls).toString(); } - - private: - int _lifetime; - QJsonObject _answer; - QString _sdp; - QString _callId; - int _version; }; REGISTER_EVENT_TYPE(CallAnswerEvent) diff --git a/lib/events/callcandidatesevent.cpp b/lib/events/callcandidatesevent.cpp index 40d9ce05..52cd1856 100644 --- a/lib/events/callcandidatesevent.cpp +++ b/lib/events/callcandidatesevent.cpp @@ -18,12 +18,6 @@ #include "callcandidatesevent.h" -#include "event.h" - -#include "logging.h" - -#include <QtCore/QJsonDocument> - /* m.call.candidates { @@ -46,24 +40,3 @@ m.call.candidates "type": "m.call.candidates" } */ - -using namespace QMatrixClient; - - -CallCandidatesEvent::CallCandidatesEvent(const QJsonObject& obj) - : RoomEvent(typeId(), obj) - , _candidates(contentJson()["candidates"].toArray()) - , _callId(contentJson()["call_id"].toString()) - , _version(contentJson()["version"].toInt()) -{ - qCDebug(EVENTS) << "Call Candidates event"; -} - -CallCandidatesEvent::CallCandidatesEvent(const QString& callId, - const QJsonArray& candidates) - : RoomEvent(typeId(), NULL) -{ - _version = 0; - _callId = callId; - _candidates = candidates; -} diff --git a/lib/events/callcandidatesevent.h b/lib/events/callcandidatesevent.h index 8e66499d..4618832c 100644 --- a/lib/events/callcandidatesevent.h +++ b/lib/events/callcandidatesevent.h @@ -19,39 +19,28 @@ #pragma once #include "roomevent.h" -#include <QtCore/QJsonArray> namespace QMatrixClient { - class CallCandidatesEvent: public RoomEvent + class CallCandidatesEvent: public CallEventBase { public: DEFINE_EVENT_TYPEID("m.call.candidates", CallCandidatesEvent) - explicit CallCandidatesEvent(const QJsonObject& obj); + explicit CallCandidatesEvent(const QJsonObject& obj) + : CallEventBase(typeId(), obj) + { } explicit CallCandidatesEvent(const QString& callId, - const QJsonArray& candidates); + const QJsonArray& candidates) + : CallEventBase(typeId(), matrixTypeId(), callId, 0, + {{ QStringLiteral("candidates"), candidates }}) + { } - bool isStateEvent() const override { return true; } - - const QJsonArray& candidates() const { return _candidates; } - const QString& callId() const { return _callId; } - const int version() const { return _version; } - - QJsonObject toJson() const + QJsonArray candidates() const { - QJsonObject obj; - obj.insert("call_id", _callId); - obj.insert("version", _version); - obj.insert("candidates", _candidates); - return obj; + return content<QJsonArray>("candidates"_ls); } - - private: - QJsonArray _candidates; - QString _callId; - int _version; }; REGISTER_EVENT_TYPE(CallCandidatesEvent) diff --git a/lib/events/callhangupevent.cpp b/lib/events/callhangupevent.cpp index 27f41a5f..b1154806 100644 --- a/lib/events/callhangupevent.cpp +++ b/lib/events/callhangupevent.cpp @@ -44,16 +44,11 @@ using namespace QMatrixClient; CallHangupEvent::CallHangupEvent(const QJsonObject& obj) - : RoomEvent(typeId(), obj) - , _callId(contentJson()["call_id"].toString()) - , _version(contentJson()["version"].toInt()) + : CallEventBase(typeId(), obj) { qCDebug(EVENTS) << "Call Hangup event"; } CallHangupEvent::CallHangupEvent(const QString& callId) - : RoomEvent(typeId(), NULL) -{ - _version = 0; - _callId = callId; -} + : CallEventBase(typeId(), matrixTypeId(), callId, 0) +{ } diff --git a/lib/events/callhangupevent.h b/lib/events/callhangupevent.h index 57e565a6..c74e20d5 100644 --- a/lib/events/callhangupevent.h +++ b/lib/events/callhangupevent.h @@ -22,31 +22,13 @@ namespace QMatrixClient { - class CallHangupEvent: public RoomEvent + class CallHangupEvent: public CallEventBase { public: DEFINE_EVENT_TYPEID("m.call.hangup", CallHangupEvent) explicit CallHangupEvent(const QJsonObject& obj); - explicit CallHangupEvent(const QString& callId); - - bool isStateEvent() const override { return true; } - - const QString& callId() const { return _callId; } - const int version() const { return _version; } - - QJsonObject toJson() const - { - QJsonObject obj; - obj.insert("call_id", _callId); - obj.insert("version", _version); - return obj; - } - - private: - QString _callId; - int _version; }; REGISTER_EVENT_TYPE(CallHangupEvent) diff --git a/lib/events/callinviteevent.cpp b/lib/events/callinviteevent.cpp index 71c49d66..bca3f296 100644 --- a/lib/events/callinviteevent.cpp +++ b/lib/events/callinviteevent.cpp @@ -48,21 +48,17 @@ m.call.invite using namespace QMatrixClient; CallInviteEvent::CallInviteEvent(const QJsonObject& obj) - : RoomEvent(typeId(), obj) - , _lifetime(contentJson()["lifetime"].toInt()) - , _sdp(contentJson()["offer"].toObject()["sdp"].toString()) - , _callId(contentJson()["call_id"].toString()) - , _version(contentJson()["version"].toInt()) + : CallEventBase(typeId(), obj) { qCDebug(EVENTS) << "Call Invite event"; } CallInviteEvent::CallInviteEvent(const QString& callId, const int lifetime, const QString& sdp) - : RoomEvent(typeId(), NULL) -{ - _version = 0; - _callId = callId; - _lifetime = lifetime; - _sdp = sdp; -} + : CallEventBase(typeId(), matrixTypeId(), callId, lifetime, + { { QStringLiteral("lifetime"), lifetime } + , { QStringLiteral("offer"), QJsonObject { + { QStringLiteral("type"), QStringLiteral("offer") }, + { QStringLiteral("sdp"), sdp } } + }}) +{ } diff --git a/lib/events/callinviteevent.h b/lib/events/callinviteevent.h index 029b2e3d..d5315309 100644 --- a/lib/events/callinviteevent.h +++ b/lib/events/callinviteevent.h @@ -22,42 +22,21 @@ namespace QMatrixClient { - class CallInviteEvent: public RoomEvent + class CallInviteEvent: public CallEventBase { public: - DEFINE_EVENT_TYPEID("m.call.invite", CallInviteEvent) + DEFINE_EVENT_TYPEID("m.call.invite", CallInviteEvent) - explicit CallInviteEvent(const QJsonObject& obj); + explicit CallInviteEvent(const QJsonObject& obj); - explicit CallInviteEvent(const QString& callId, const int lifetime, - const QString& sdp); + explicit CallInviteEvent(const QString& callId, const int lifetime, + const QString& sdp); - bool isStateEvent() const override { return true; } - - const int lifetime() const { return _lifetime; } - const QString& sdp() const { return _sdp; } - const QString& callId() const { return _callId; } - const int version() const { return _version; } - - QJsonObject toJson() const - { - QJsonObject offer; - offer.insert("sdp", _sdp); - offer.insert("type", QStringLiteral("offer")); - - QJsonObject obj; - obj.insert("call_id", _callId); - obj.insert("version", _version); - obj.insert("lifetime", _lifetime); - obj.insert("offer", offer); - return obj; - } - - private: - int _lifetime; - QString _sdp; - QString _callId; - int _version; + int lifetime() const { return content<int>("lifetime"_ls); } // FIXME: Omittable<>? + QString sdp() const { + return contentJson()["offer"_ls].toObject() + .value("sdp"_ls).toString(); + } }; REGISTER_EVENT_TYPE(CallInviteEvent) diff --git a/lib/events/event.h b/lib/events/event.h index 9ba4b85a..cd23a818 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -18,11 +18,9 @@ #pragma once -#include "util.h" +#include "converters.h" #include "logging.h" -#include <QtCore/QJsonObject> - #ifndef DISABLE_EVENTTYPE #define USE_EVENTTYPE 1 #endif @@ -247,7 +245,20 @@ namespace QMatrixClient const QJsonObject contentJson() const; const QJsonObject unsignedJson() const; + template <typename T> + T content(const QString& key) const + { + return fromJson<T>(contentJson()[key]); + } + + template <typename T> + T content(const QLatin1String& key) const + { + return fromJson<T>(contentJson()[key]); + } + virtual bool isStateEvent() const { return false; } + virtual bool isCallEvent() const { return false; } protected: QJsonObject& editJson() { return _json; } diff --git a/lib/events/roomevent.cpp b/lib/events/roomevent.cpp index e9d74cf6..80d121de 100644 --- a/lib/events/roomevent.cpp +++ b/lib/events/roomevent.cpp @@ -101,3 +101,25 @@ void RoomEvent::addId(const QString& newId) qCDebug(EVENTS) << "Event txnId -> id:" << transactionId() << "->" << id(); Q_ASSERT(id() == newId); } + +QJsonObject makeCallContentJson(const QString& callId, int version, + QJsonObject content) +{ + content.insert(QStringLiteral("call_id"), callId); + content.insert(QStringLiteral("version"), version); + return content; +} + +CallEventBase::CallEventBase(Type type, event_mtype_t matrixType, + const QString& callId, int version, + const QJsonObject& contentJson) + : RoomEvent(type, matrixType, + makeCallContentJson(callId, version, contentJson)) +{ } + +CallEventBase::CallEventBase(Event::Type type, const QJsonObject& json) + : RoomEvent(type, json) +{ + if (callId().isEmpty()) + qCWarning(EVENTS) << id() << "is a call event with an empty call id"; +} diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index f057753f..ce96174e 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -87,6 +87,20 @@ namespace QMatrixClient using RoomEventPtr = event_ptr_tt<RoomEvent>; using RoomEvents = EventsArray<RoomEvent>; using RoomEventsRange = Range<RoomEvents>; + + class CallEventBase: public RoomEvent + { + public: + CallEventBase(Type type, event_mtype_t matrixType, + const QString& callId, int version, + const QJsonObject& contentJson = {}); + CallEventBase(Type type, const QJsonObject& json); + ~CallEventBase() override = default; + bool isCallEvent() const override { return true; } + + QString callId() const { return content<QString>("call_id"_ls); } + int version() const { return content<int>("version"_ls); } + }; } // namespace QMatrixClient Q_DECLARE_METATYPE(QMatrixClient::RoomEvent*) Q_DECLARE_METATYPE(const QMatrixClient::RoomEvent*) diff --git a/lib/room.cpp b/lib/room.cpp index ee2e2b8e..2253c636 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -1300,58 +1300,42 @@ bool isEchoEvent(const RoomEventPtr& le, const PendingEventItem& re) return le->contentJson() == re->contentJson(); } -bool Room::processCall(Room* room, const RoomEvent* event) -{ - if (!room->isCallSupported()) { - qCDebug(MAIN) << "Got call event in room with more then two" - << "members, Ignoring this event!"; - return false; - } - emit callEvent(room, event); - return false; -} - -bool Room::isCallSupported() const +bool Room::supportsCalls() const { return d->membersMap.size() == 2; } void Room::inviteCall(const QString& callId, const int lifetime, - const QString& sdp) + const QString& sdp) { - Q_ASSERT(isCallSupported()); - auto *evt = new CallInviteEvent(callId, lifetime, sdp); - postEvent(evt); + Q_ASSERT(supportsCalls()); + postEvent(new CallInviteEvent(callId, lifetime, sdp)); } -void Room::callCandidates(const QString& callId, - const QJsonArray& candidates) +void Room::sendCallCandidates(const QString& callId, + const QJsonArray& candidates) { - Q_ASSERT(isCallSupported()); - auto *evt = new CallCandidatesEvent(callId, candidates); - postEvent(evt); + Q_ASSERT(supportsCalls()); + postEvent(new CallCandidatesEvent(callId, candidates)); } void Room::answerCall(const QString& callId, const int lifetime, - const QString& sdp) + const QString& sdp) { - Q_ASSERT(isCallSupported()); - auto *evt = new CallAnswerEvent(callId, lifetime, sdp); - postEvent(evt); + Q_ASSERT(supportsCalls()); + postEvent(new CallAnswerEvent(callId, lifetime, sdp)); } void Room::answerCall(const QString& callId, const QString& sdp) { - Q_ASSERT(isCallSupported()); - auto *evt = new CallAnswerEvent(callId, sdp); - postEvent(evt); + Q_ASSERT(supportsCalls()); + postEvent(new CallAnswerEvent(callId, sdp)); } void Room::hangupCall(const QString& callId) { - Q_ASSERT(isCallSupported()); - auto *evt = new CallHangupEvent(callId); - postEvent(evt); + Q_ASSERT(supportsCalls()); + postEvent(new CallHangupEvent(callId)); } void Room::getPreviousContent(int limit) @@ -1701,6 +1685,10 @@ void Room::Private::addNewMessageEvents(RoomEvents&& events) } emit q->pendingEventMerged(); } + if (q->supportsCalls()) + for (const auto& evt: RoomEventsRange(events.begin(), newEnd)) + if (evt->isCallEvent()) + emit q->callEvent(q, weakPtrCast<CallEventBase>(evt)); if (totalInserted > 0) { @@ -1829,18 +1817,6 @@ bool Room::processStateEvent(const RoomEvent& e) } return false; } - , [this] (const CallAnswerEvent& evt) { - return processCall(this, &evt); - } - , [this] (const CallCandidatesEvent& evt) { - return processCall(this, &evt); - } - , [this] (const CallHangupEvent& evt) { - return processCall(this, &evt); - } - , [this] (const CallInviteEvent& evt) { - return processCall(this, &evt); - } , [this] (const EncryptionEvent& evt) { d->encryptionAlgorithm = evt.algorithm(); qCDebug(MAIN) << "Encryption switched on in room" << id() @@ -305,14 +305,14 @@ namespace QMatrixClient Q_INVOKABLE void inviteCall(const QString& callId, const int lifetime, const QString& sdp); - Q_INVOKABLE void callCandidates(const QString& callId, + Q_INVOKABLE void sendCallCandidates(const QString& callId, const QJsonArray& candidates); Q_INVOKABLE void answerCall(const QString& callId, const int lifetime, const QString& sdp); Q_INVOKABLE void answerCall(const QString& callId, const QString& sdp); Q_INVOKABLE void hangupCall(const QString& callId); - Q_INVOKABLE bool isCallSupported() const; + Q_INVOKABLE bool supportsCalls() const; public slots: QString postMessage(const QString& plainText, MessageEventType type); @@ -437,8 +437,6 @@ namespace QMatrixClient const RoomEvent& /*after*/) { } private: - bool processCall(Room* room, const RoomEvent* event); - class Private; Private* d; }; |