Index: webrtc/libjingle/xmpp/xmpptask.h |
diff --git a/webrtc/libjingle/xmpp/xmpptask.h b/webrtc/libjingle/xmpp/xmpptask.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3f3a39c791cb295d8630eeb680a198362d4d16de |
--- /dev/null |
+++ b/webrtc/libjingle/xmpp/xmpptask.h |
@@ -0,0 +1,175 @@ |
+/* |
+ * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#ifndef WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_ |
+#define WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_ |
+ |
+#include <deque> |
+#include <memory> |
+#include <string> |
+ |
+#include "webrtc/libjingle/xmpp/xmppengine.h" |
+#include "webrtc/base/constructormagic.h" |
+#include "webrtc/base/sigslot.h" |
+#include "webrtc/base/task.h" |
+#include "webrtc/base/taskparent.h" |
+ |
+namespace buzz { |
+ |
+///////////////////////////////////////////////////////////////////// |
+// |
+// XMPPTASK |
+// |
+///////////////////////////////////////////////////////////////////// |
+// |
+// See Task and XmppClient first. |
+// |
+// XmppTask is a task that is designed to go underneath XmppClient and be |
+// useful there. It has a way of finding its XmppClient parent so you |
+// can have it nested arbitrarily deep under an XmppClient and it can |
+// still find the XMPP services. |
+// |
+// Tasks register themselves to listen to particular kinds of stanzas |
+// that are sent out by the client. Rather than processing stanzas |
+// right away, they should decide if they own the sent stanza, |
+// and if so, queue it and Wake() the task, or if a stanza does not belong |
+// to you, return false right away so the next XmppTask can take a crack. |
+// This technique (synchronous recognize, but asynchronous processing) |
+// allows you to have arbitrary logic for recognizing stanzas yet still, |
+// for example, disconnect a client while processing a stanza - |
+// without reentrancy problems. |
+// |
+///////////////////////////////////////////////////////////////////// |
+ |
+class XmppTask; |
+ |
+// XmppClientInterface is an abstract interface for sending and |
+// handling stanzas. It can be implemented for unit tests or |
+// different network environments. It will usually be implemented by |
+// XmppClient. |
+class XmppClientInterface { |
+ public: |
+ XmppClientInterface(); |
+ virtual ~XmppClientInterface(); |
+ |
+ virtual XmppEngine::State GetState() const = 0; |
+ virtual const Jid& jid() const = 0; |
+ virtual std::string NextId() = 0; |
+ virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0; |
+ virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza, |
+ XmppStanzaError error_code, |
+ const std::string& message) = 0; |
+ virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0; |
+ virtual void RemoveXmppTask(XmppTask* task) = 0; |
+ sigslot::signal0<> SignalDisconnected; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(XmppClientInterface); |
+}; |
+ |
+// XmppTaskParentInterface is the interface require for any parent of |
+// an XmppTask. It needs, for example, a way to get an |
+// XmppClientInterface. |
+ |
+// We really ought to inherit from a TaskParentInterface, but we tried |
+// that and it's way too complicated to change |
+// Task/TaskParent/TaskRunner. For now, this works. |
+class XmppTaskParentInterface : public rtc::Task { |
+ public: |
+ explicit XmppTaskParentInterface(rtc::TaskParent* parent) |
+ : Task(parent) { |
+ } |
+ virtual ~XmppTaskParentInterface() {} |
+ |
+ virtual XmppClientInterface* GetClient() = 0; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(XmppTaskParentInterface); |
+}; |
+ |
+class XmppTaskBase : public XmppTaskParentInterface { |
+ public: |
+ explicit XmppTaskBase(XmppTaskParentInterface* parent) |
+ : XmppTaskParentInterface(parent), |
+ parent_(parent) { |
+ } |
+ virtual ~XmppTaskBase() {} |
+ |
+ virtual XmppClientInterface* GetClient() { |
+ return parent_->GetClient(); |
+ } |
+ |
+ protected: |
+ XmppTaskParentInterface* parent_; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(XmppTaskBase); |
+}; |
+ |
+class XmppTask : public XmppTaskBase, |
+ public XmppStanzaHandler, |
+ public sigslot::has_slots<> |
+{ |
+ public: |
+ XmppTask(XmppTaskParentInterface* parent, |
+ XmppEngine::HandlerLevel level = XmppEngine::HL_NONE); |
+ virtual ~XmppTask(); |
+ |
+ std::string task_id() const { return id_; } |
+ void set_task_id(std::string id) { id_ = id; } |
+ |
+#if !defined(NDEBUG) |
+ void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; } |
+#endif |
+ |
+ virtual bool HandleStanza(const XmlElement* stanza) { return false; } |
+ |
+ protected: |
+ XmppReturnStatus SendStanza(const XmlElement* stanza); |
+ XmppReturnStatus SetResult(const std::string& code); |
+ XmppReturnStatus SendStanzaError(const XmlElement* element_original, |
+ XmppStanzaError code, |
+ const std::string& text); |
+ |
+ virtual void Stop(); |
+ virtual void OnDisconnect(); |
+ |
+ virtual void QueueStanza(const XmlElement* stanza); |
+ const XmlElement* NextStanza(); |
+ |
+ bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid); |
+ |
+ bool MatchResponseIq(const XmlElement* stanza, const Jid& to, |
+ const std::string& task_id); |
+ |
+ static bool MatchRequestIq(const XmlElement* stanza, const std::string& type, |
+ const QName& qn); |
+ static XmlElement *MakeIqResult(const XmlElement* query); |
+ static XmlElement *MakeIq(const std::string& type, |
+ const Jid& to, const std::string& task_id); |
+ |
+ // Returns true if the task is under the specified rate limit and updates the |
+ // rate limit accordingly |
+ bool VerifyTaskRateLimit(const std::string task_name, int max_count, |
+ int per_x_seconds); |
+ |
+private: |
+ void StopImpl(); |
+ |
+ bool stopped_; |
+ std::deque<XmlElement*> stanza_queue_; |
+ std::unique_ptr<XmlElement> next_stanza_; |
+ std::string id_; |
+ |
+#if !defined(NDEBUG) |
+ bool debug_force_timeout_; |
+#endif |
+}; |
+ |
+} // namespace buzz |
+ |
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_ |