summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-23 16:35:44 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-23 16:35:44 +0000
commit512ac40edc7551c76bbd9bf288afee209f6bba15 (patch)
tree1ff85ae2cf2b7d65fef41729225a62b9ecc1d1f1
parent590742dc369f718055cded657f197d154639493e (diff)
downloadchromium_src-512ac40edc7551c76bbd9bf288afee209f6bba15.zip
chromium_src-512ac40edc7551c76bbd9bf288afee209f6bba15.tar.gz
chromium_src-512ac40edc7551c76bbd9bf288afee209f6bba15.tar.bz2
Refactoring around SignalStrategy interface.
- Added AddListener/RemoveListener in the SignalStrategy interface. - Remove dependancy on JavascriptIqRequest from JingleSignalingConnector. BUG=None TEST=Chromoting client still works Review URL: http://codereview.chromium.org/7239005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90219 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--remoting/jingle_glue/javascript_iq_request.cc61
-rw-r--r--remoting/jingle_glue/javascript_iq_request.h41
-rw-r--r--remoting/jingle_glue/javascript_signal_strategy.cc54
-rw-r--r--remoting/jingle_glue/javascript_signal_strategy.h15
-rw-r--r--remoting/jingle_glue/jingle_signaling_connector.cc31
-rw-r--r--remoting/jingle_glue/jingle_signaling_connector.h13
-rw-r--r--remoting/jingle_glue/mock_objects.h2
-rw-r--r--remoting/jingle_glue/signal_strategy.h18
-rw-r--r--remoting/jingle_glue/xmpp_signal_strategy.cc25
-rw-r--r--remoting/jingle_glue/xmpp_signal_strategy.h11
10 files changed, 159 insertions, 112 deletions
diff --git a/remoting/jingle_glue/javascript_iq_request.cc b/remoting/jingle_glue/javascript_iq_request.cc
index 8b63dcc..4867ecf 100644
--- a/remoting/jingle_glue/javascript_iq_request.cc
+++ b/remoting/jingle_glue/javascript_iq_request.cc
@@ -4,15 +4,16 @@
#include "remoting/jingle_glue/javascript_iq_request.h"
+#include "base/logging.h"
#include "base/string_number_conversions.h"
+#include "remoting/jingle_glue/signal_strategy.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
#include "third_party/libjingle/source/talk/xmpp/constants.h"
namespace remoting {
JavascriptIqRegistry::JavascriptIqRegistry()
- : current_id_(0),
- default_handler_(NULL) {
+ : current_id_(0) {
}
JavascriptIqRegistry::~JavascriptIqRegistry() {
@@ -29,23 +30,10 @@ void JavascriptIqRegistry::RemoveAllRequests(JavascriptIqRequest* request) {
}
}
-void JavascriptIqRegistry::SetDefaultHandler(JavascriptIqRequest* new_handler) {
- // Should only allow a new handler if |default_handler_| is NULL.
- CHECK(default_handler_ == NULL || !new_handler);
- default_handler_ = new_handler;
-}
-
-void JavascriptIqRegistry::OnIq(const std::string& response_xml) {
+void JavascriptIqRegistry::OnIncomingStanza(const buzz::XmlElement* stanza) {
// TODO(ajwong): Can we cleanup this dispatch at all? The send is from
// JavascriptIqRequest but the return is in JavascriptIqRegistry.
- scoped_ptr<buzz::XmlElement> stanza(buzz::XmlElement::ForStr(response_xml));
- if (!stanza.get()) {
- LOG(WARNING) << "Malformed XML received" << response_xml;
- return;
- }
-
- LOG(ERROR) << "IQ Received: " << stanza->Str();
if (stanza->Name() != buzz::QN_IQ) {
LOG(WARNING) << "Received unexpected non-IQ packet" << stanza->Str();
return;
@@ -60,16 +48,7 @@ void JavascriptIqRegistry::OnIq(const std::string& response_xml) {
IqRequestMap::iterator it = requests_.find(id);
if (it == requests_.end()) {
- if (!default_handler_) {
- VLOG(1) << "Dropping IQ packet with no request id: " << stanza->Str();
- } else {
- if (default_handler_->callback_.get()) {
- default_handler_->callback_->Run(stanza.get());
- } else {
- VLOG(1) << "default handler has no callback, so dropping: "
- << stanza->Str();
- }
- }
+ VLOG(1) << "Dropping IQ packet with no request id: " << stanza->Str();
} else {
// TODO(ajwong): We should look at the logic inside libjingle's
// XmppTask::MatchResponseIq() and make sure we're fully in sync.
@@ -80,7 +59,7 @@ void JavascriptIqRegistry::OnIq(const std::string& response_xml) {
// JavascriptIqRegistry::OnIq(). We should try to keep the
// registration/deregistration in one spot.
if (it->second->callback_.get()) {
- it->second->callback_->Run(stanza.get());
+ it->second->callback_->Run(stanza);
} else {
VLOG(1) << "No callback, so dropping: " << stanza->Str();
}
@@ -97,37 +76,21 @@ std::string JavascriptIqRegistry::RegisterRequest(
return id_as_string;
}
-JavascriptIqRequest::JavascriptIqRequest(JavascriptIqRegistry* registry,
- scoped_refptr<XmppProxy> xmpp_proxy)
- : xmpp_proxy_(xmpp_proxy),
- registry_(registry),
- is_default_handler_(false) {
+JavascriptIqRequest::JavascriptIqRequest(SignalStrategy* signal_strategy,
+ JavascriptIqRegistry* registry)
+ : signal_strategy_(signal_strategy),
+ registry_(registry) {
}
JavascriptIqRequest::~JavascriptIqRequest() {
registry_->RemoveAllRequests(this);
- if (is_default_handler_) {
- registry_->SetDefaultHandler(NULL);
- }
}
void JavascriptIqRequest::SendIq(const std::string& type,
const std::string& addressee,
buzz::XmlElement* iq_body) {
- scoped_ptr<buzz::XmlElement> stanza(
- MakeIqStanza(type, addressee, iq_body,
- registry_->RegisterRequest(this)));
-
- xmpp_proxy_->SendIq(stanza->Str());
-}
-
-void JavascriptIqRequest::SendRawIq(buzz::XmlElement* stanza) {
- xmpp_proxy_->SendIq(stanza->Str());
-}
-
-void JavascriptIqRequest::BecomeDefaultHandler() {
- is_default_handler_ = true;
- registry_->SetDefaultHandler(this);
+ signal_strategy_->SendStanza(
+ MakeIqStanza(type, addressee, iq_body, registry_->RegisterRequest(this)));
}
void JavascriptIqRequest::set_callback(ReplyCallback* callback) {
diff --git a/remoting/jingle_glue/javascript_iq_request.h b/remoting/jingle_glue/javascript_iq_request.h
index 0de9574..84bc9b2 100644
--- a/remoting/jingle_glue/javascript_iq_request.h
+++ b/remoting/jingle_glue/javascript_iq_request.h
@@ -10,13 +10,13 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "remoting/jingle_glue/iq_request.h"
-#include "remoting/jingle_glue/xmpp_proxy.h"
namespace remoting {
class JavascriptIqRequest;
+class SignalStrategy;
-class JavascriptIqRegistry : public XmppProxy::ResponseCallback {
+class JavascriptIqRegistry {
public:
JavascriptIqRegistry();
virtual ~JavascriptIqRegistry();
@@ -35,12 +35,12 @@ class JavascriptIqRegistry : public XmppProxy::ResponseCallback {
void SetDefaultHandler(JavascriptIqRequest* default_request);
+ // Called by JavascriptSignalStrategy.
+ void OnIncomingStanza(const buzz::XmlElement* stanza);
+
private:
typedef std::map<std::string, JavascriptIqRequest*> IqRequestMap;
- // XmppProxy::ResponseCallback interface.
- virtual void OnIq(const std::string& response_xml);
-
IqRequestMap requests_;
int current_id_;
JavascriptIqRequest* default_handler_;
@@ -51,34 +51,10 @@ class JavascriptIqRegistry : public XmppProxy::ResponseCallback {
// This call must only be used on the thread it was created on.
class JavascriptIqRequest : public IqRequest {
public:
- JavascriptIqRequest(JavascriptIqRegistry* registry,
- scoped_refptr<XmppProxy> xmpp_proxy);
+ JavascriptIqRequest(SignalStrategy* signal_strategy,
+ JavascriptIqRegistry* registry);
virtual ~JavascriptIqRequest();
- // Similar to SendIq(), but has 3 major differences:
- //
- // (1) It does absoluately no error checking. Caller is responsible for
- // validity.
- // (2) It doesn't add an Iq envelope. Caller is again responsible.
- // (3) BecomeDefaultHandler() must have been called.
- //
- // TODO(ajwong): We need to rationalize the semantics of these two
- // APIs. SendRawIq() is a hack for JingleSignalingConnector which
- // uses a different memory management convention.
- void SendRawIq(buzz::XmlElement* stanza);
-
- // This function is a hack to support SessionStartRequest. It registers the
- // current JavascriptIqRequest instance to be the single passthrough filter
- // for the associated JavascriptIqRegistry. What this means is that any IQ
- // packet that does not match a previous respone packet will be funneled
- // through to this JavascriptIqRegistry instance (basically a default
- // handler). It also means that the registry will not be tracking any of the
- // packets sent from this JavascriptIqRegistry instance.
- //
- // TODO(ajwong): We need to take a high-level look at IqRequest to understand
- // how to make this API cleaner.
- void BecomeDefaultHandler();
-
// IqRequest interface.
virtual void SendIq(const std::string& type, const std::string& addressee,
buzz::XmlElement* iq_body) OVERRIDE;
@@ -88,9 +64,8 @@ class JavascriptIqRequest : public IqRequest {
friend class JavascriptIqRegistry;
scoped_ptr<ReplyCallback> callback_;
- scoped_refptr<XmppProxy> xmpp_proxy_;
+ SignalStrategy* signal_strategy_;
JavascriptIqRegistry* registry_;
- bool is_default_handler_;
FRIEND_TEST_ALL_PREFIXES(IqRequestTest, MakeIqStanza);
};
diff --git a/remoting/jingle_glue/javascript_signal_strategy.cc b/remoting/jingle_glue/javascript_signal_strategy.cc
index 2f5b64f..6227b5e 100644
--- a/remoting/jingle_glue/javascript_signal_strategy.cc
+++ b/remoting/jingle_glue/javascript_signal_strategy.cc
@@ -4,26 +4,35 @@
#include "remoting/jingle_glue/javascript_signal_strategy.h"
+#include <algorithm>
+
+#include "base/logging.h"
#include "remoting/jingle_glue/iq_request.h"
#include "remoting/jingle_glue/jingle_signaling_connector.h"
#include "remoting/jingle_glue/xmpp_proxy.h"
+#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
namespace remoting {
JavascriptSignalStrategy::JavascriptSignalStrategy(const std::string& your_jid)
- : your_jid_(your_jid) {
+ : your_jid_(your_jid),
+ listener_(NULL) {
}
JavascriptSignalStrategy::~JavascriptSignalStrategy() {
+ jingle_signaling_connector_.reset();
+ DCHECK(listener_ == NULL);
}
void JavascriptSignalStrategy::AttachXmppProxy(
scoped_refptr<XmppProxy> xmpp_proxy) {
xmpp_proxy_ = xmpp_proxy;
- xmpp_proxy_->AttachCallback(iq_registry_.AsWeakPtr());
+ xmpp_proxy_->AttachCallback(AsWeakPtr());
}
void JavascriptSignalStrategy::Init(StatusObserver* observer) {
+ DCHECK(CalledOnValidThread());
+
// Blast through each state since for a JavascriptSignalStrategy, we're
// already connected.
//
@@ -35,22 +44,55 @@ void JavascriptSignalStrategy::Init(StatusObserver* observer) {
observer->OnStateChange(StatusObserver::CONNECTED);
}
+void JavascriptSignalStrategy::SetListener(Listener* listener) {
+ DCHECK(CalledOnValidThread());
+
+ // Don't overwrite an listener without explicitly going
+ // through "NULL" first.
+ DCHECK(listener_ == NULL || listener == NULL);
+ listener_ = listener;
+}
+
+void JavascriptSignalStrategy::SendStanza(buzz::XmlElement* stanza) {
+ DCHECK(CalledOnValidThread());
+
+ xmpp_proxy_->SendIq(stanza->Str());
+ delete stanza;
+}
+
void JavascriptSignalStrategy::StartSession(
cricket::SessionManager* session_manager) {
+ DCHECK(CalledOnValidThread());
+
jingle_signaling_connector_.reset(
- new JingleSignalingConnector(CreateIqRequest(), session_manager));
- jingle_signaling_connector_->Run();
+ new JingleSignalingConnector(this, session_manager));
}
void JavascriptSignalStrategy::EndSession() {
+ DCHECK(CalledOnValidThread());
+
if (xmpp_proxy_) {
xmpp_proxy_->DetachCallback();
}
xmpp_proxy_ = NULL;
}
-JavascriptIqRequest* JavascriptSignalStrategy::CreateIqRequest() {
- return new JavascriptIqRequest(&iq_registry_, xmpp_proxy_);
+IqRequest* JavascriptSignalStrategy::CreateIqRequest() {
+ DCHECK(CalledOnValidThread());
+
+ return new JavascriptIqRequest(this, &iq_registry_);
+}
+
+void JavascriptSignalStrategy::OnIq(const std::string& stanza_str) {
+ scoped_ptr<buzz::XmlElement> stanza(buzz::XmlElement::ForStr(stanza_str));
+
+ if (!stanza.get()) {
+ LOG(WARNING) << "Malformed XMPP stanza received: " << stanza_str;
+ return;
+ }
+
+ listener_->OnIncomingStanza(stanza.get());
+ iq_registry_.OnIncomingStanza(stanza.get());
}
} // namespace remoting
diff --git a/remoting/jingle_glue/javascript_signal_strategy.h b/remoting/jingle_glue/javascript_signal_strategy.h
index 033ba0e..3cebf05 100644
--- a/remoting/jingle_glue/javascript_signal_strategy.h
+++ b/remoting/jingle_glue/javascript_signal_strategy.h
@@ -10,14 +10,18 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/threading/non_thread_safe.h"
#include "remoting/jingle_glue/javascript_iq_request.h"
+#include "remoting/jingle_glue/xmpp_proxy.h"
namespace remoting {
class JingleSignalingConnector;
class XmppProxy;
-class JavascriptSignalStrategy : public SignalStrategy {
+class JavascriptSignalStrategy : public SignalStrategy,
+ public XmppProxy::ResponseCallback,
+ public base::NonThreadSafe {
public:
explicit JavascriptSignalStrategy(const std::string& your_jid);
virtual ~JavascriptSignalStrategy();
@@ -26,9 +30,14 @@ class JavascriptSignalStrategy : public SignalStrategy {
// SignalStrategy interface.
virtual void Init(StatusObserver* observer) OVERRIDE;
+ virtual void SetListener(Listener* listener) OVERRIDE;
+ virtual void SendStanza(buzz::XmlElement* stanza) OVERRIDE;
virtual void StartSession(cricket::SessionManager* session_manager) OVERRIDE;
virtual void EndSession() OVERRIDE;
- virtual JavascriptIqRequest* CreateIqRequest() OVERRIDE;
+ virtual IqRequest* CreateIqRequest() OVERRIDE;
+
+ // XmppProxy::ResponseCallback interface.
+ virtual void OnIq(const std::string& stanza);
private:
std::string your_jid_;
@@ -36,6 +45,8 @@ class JavascriptSignalStrategy : public SignalStrategy {
JavascriptIqRegistry iq_registry_;
scoped_ptr<JingleSignalingConnector> jingle_signaling_connector_;
+ Listener* listener_;
+
DISALLOW_COPY_AND_ASSIGN(JavascriptSignalStrategy);
};
diff --git a/remoting/jingle_glue/jingle_signaling_connector.cc b/remoting/jingle_glue/jingle_signaling_connector.cc
index f2666d2..a094569 100644
--- a/remoting/jingle_glue/jingle_signaling_connector.cc
+++ b/remoting/jingle_glue/jingle_signaling_connector.cc
@@ -4,6 +4,7 @@
#include "remoting/jingle_glue/jingle_signaling_connector.h"
+#include "base/logging.h"
#include "remoting/jingle_glue/javascript_iq_request.h"
#include "third_party/libjingle/source/talk/p2p/base/sessionmanager.h"
#include "third_party/libjingle/source/talk/xmpp/constants.h"
@@ -12,28 +13,27 @@
namespace remoting {
JingleSignalingConnector::JingleSignalingConnector(
- JavascriptIqRequest* request,
+ SignalStrategy* signal_strategy,
cricket::SessionManager* session_manager)
- : request_(request),
+ : signal_strategy_(signal_strategy),
session_manager_(session_manager) {
- request_->set_callback(
- NewCallback(this, &JingleSignalingConnector::OnResponse));
-}
-JingleSignalingConnector::~JingleSignalingConnector() {
-}
-
-void JingleSignalingConnector::Run() {
session_manager_->SignalOutgoingMessage.connect(
this, &JingleSignalingConnector::OnOutgoingMessage);
- // TODO(ajwong): Why are we connecting SessionManager to itself?
+ signal_strategy_->SetListener(this);
+
+ // Assume that signaling is ready from the beginning.
session_manager_->SignalRequestSignaling.connect(
session_manager_, &cricket::SessionManager::OnSignalingReady);
- request_->BecomeDefaultHandler();
}
-void JingleSignalingConnector::OnResponse(const buzz::XmlElement* response) {
+JingleSignalingConnector::~JingleSignalingConnector() {
+ signal_strategy_->SetListener(NULL);
+}
+
+void JingleSignalingConnector::OnIncomingStanza(
+ const buzz::XmlElement* stanza) {
// TODO(ajwong): Techncially, when SessionManager sends IQ packets, it
// actually expects a response in SessionSendTask(). However, if you look in
// SessionManager::OnIncomingResponse(), it does nothing with the response.
@@ -44,18 +44,17 @@ void JingleSignalingConnector::OnResponse(const buzz::XmlElement* response) {
// messages outside of the request/reply framework to
// SessionManager::OnIncomingMessage.
- if (session_manager_->IsSessionMessage(response)) {
- session_manager_->OnIncomingMessage(response);
+ if (session_manager_->IsSessionMessage(stanza)) {
+ session_manager_->OnIncomingMessage(stanza);
}
}
void JingleSignalingConnector::OnOutgoingMessage(
cricket::SessionManager* session_manager,
const buzz::XmlElement* stanza) {
- // TODO(ajwong): Are we just supposed to not use |session_manager|?
DCHECK_EQ(session_manager, session_manager_);
scoped_ptr<buzz::XmlElement> stanza_copy(new buzz::XmlElement(*stanza));
- request_->SendRawIq(stanza_copy.get());
+ signal_strategy_->SendStanza(stanza_copy.release());
}
} // namespace remoting
diff --git a/remoting/jingle_glue/jingle_signaling_connector.h b/remoting/jingle_glue/jingle_signaling_connector.h
index 74e872e..2f783f5 100644
--- a/remoting/jingle_glue/jingle_signaling_connector.h
+++ b/remoting/jingle_glue/jingle_signaling_connector.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
+#include "remoting/jingle_glue/signal_strategy.h"
#include "third_party/libjingle/source/talk/base/sigslot.h"
namespace buzz {
@@ -33,13 +34,15 @@ class JavascriptIqRequest;
//
// TODO(sergeyu): This class should not depend on JavascriptIqRequest:
// it should work with SignalStrategy instead.
-class JingleSignalingConnector : public sigslot::has_slots<> {
+class JingleSignalingConnector : public SignalStrategy::Listener,
+ public sigslot::has_slots<> {
public:
- JingleSignalingConnector(JavascriptIqRequest* request,
- cricket::SessionManager* session_manager);
+ JingleSignalingConnector(SignalStrategy* signal_strategy,
+ cricket::SessionManager* session_manager);
virtual ~JingleSignalingConnector();
- void Run();
+ // SignalStrategy::Listener interface.
+ virtual void OnIncomingStanza(const buzz::XmlElement* stanza) OVERRIDE;
private:
void OnResponse(const buzz::XmlElement* stanza);
@@ -47,7 +50,7 @@ class JingleSignalingConnector : public sigslot::has_slots<> {
void OnOutgoingMessage(cricket::SessionManager* manager,
const buzz::XmlElement* stanza);
- scoped_ptr<JavascriptIqRequest> request_;
+ SignalStrategy* signal_strategy_;
cricket::SessionManager* session_manager_;
DISALLOW_COPY_AND_ASSIGN(JingleSignalingConnector);
diff --git a/remoting/jingle_glue/mock_objects.h b/remoting/jingle_glue/mock_objects.h
index ef7e543..8889f47 100644
--- a/remoting/jingle_glue/mock_objects.h
+++ b/remoting/jingle_glue/mock_objects.h
@@ -16,6 +16,8 @@ class MockSignalStrategy : public SignalStrategy {
MOCK_METHOD1(Init, void(StatusObserver*));
MOCK_METHOD0(port_allocator, cricket::BasicPortAllocator*());
MOCK_METHOD2(ConfigureAllocator, void(cricket::HttpPortAllocator*, Task*));
+ MOCK_METHOD1(SetListener, void(Listener* listener));
+ MOCK_METHOD1(SendStanza, void(buzz::XmlElement* stanza));
MOCK_METHOD1(StartSession, void(cricket::SessionManager*));
MOCK_METHOD0(EndSession, void());
MOCK_METHOD0(CreateIqRequest, IqRequest*());
diff --git a/remoting/jingle_glue/signal_strategy.h b/remoting/jingle_glue/signal_strategy.h
index d4f3332..d4093b78 100644
--- a/remoting/jingle_glue/signal_strategy.h
+++ b/remoting/jingle_glue/signal_strategy.h
@@ -9,6 +9,10 @@
#include "base/basictypes.h"
+namespace buzz {
+class XmlElement;
+} // namespace buzz
+
namespace cricket {
class SessionManager;
} // namespace cricket
@@ -33,10 +37,24 @@ class SignalStrategy {
virtual void OnJidChange(const std::string& full_jid) = 0;
};
+ class Listener {
+ public:
+ virtual void OnIncomingStanza(const buzz::XmlElement* stanza) = 0;
+ };
+
SignalStrategy() {}
virtual ~SignalStrategy() {}
virtual void Init(StatusObserver* observer) = 0;
+ // Set a listener that can listen to all incoming messages. Doesn't
+ // take ownership of the |listener|. Can be called with |listener|
+ // set to NULL to unset current listener. It must be unset before
+ // object is destroyed.
+ virtual void SetListener(Listener* listener) = 0;
+
+ // Sends a raw XMPP stanza. Takes ownership of the |stanza|.
+ virtual void SendStanza(buzz::XmlElement* stanza) = 0;
+
// TODO(sergeyu): Do these methods belong to this interface?
virtual void StartSession(cricket::SessionManager* session_manager) = 0;
virtual void EndSession() = 0;
diff --git a/remoting/jingle_glue/xmpp_signal_strategy.cc b/remoting/jingle_glue/xmpp_signal_strategy.cc
index 9f177fe..a8a8008 100644
--- a/remoting/jingle_glue/xmpp_signal_strategy.cc
+++ b/remoting/jingle_glue/xmpp_signal_strategy.cc
@@ -4,6 +4,7 @@
#include "remoting/jingle_glue/xmpp_signal_strategy.h"
+#include "base/logging.h"
#include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/jingle_glue/xmpp_iq_request.h"
@@ -21,6 +22,7 @@ XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread,
const std::string& auth_token,
const std::string& auth_token_service)
: thread_(jingle_thread),
+ listener_(NULL),
username_(username),
auth_token_(auth_token),
auth_token_service_(auth_token_service),
@@ -29,6 +31,10 @@ XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread,
}
XmppSignalStrategy::~XmppSignalStrategy() {
+ if (xmpp_client_)
+ xmpp_client_->engine()->RemoveStanzaHandler(this);
+
+ DCHECK(listener_ == NULL);
}
void XmppSignalStrategy::Init(StatusObserver* observer) {
@@ -51,9 +57,21 @@ void XmppSignalStrategy::Init(StatusObserver* observer) {
xmpp_client_->Connect(settings, "", socket, CreatePreXmppAuth(settings));
xmpp_client_->SignalStateChange.connect(
this, &XmppSignalStrategy::OnConnectionStateChanged);
+ xmpp_client_->engine()->AddStanzaHandler(this, buzz::XmppEngine::HL_PEEK);
xmpp_client_->Start();
}
+void XmppSignalStrategy::SetListener(Listener* listener) {
+ // Don't overwrite an listener without explicitly going
+ // through "NULL" first.
+ DCHECK(listener_ == NULL || listener == NULL);
+ listener_ = listener;
+}
+
+void XmppSignalStrategy::SendStanza(buzz::XmlElement* stanza) {
+ xmpp_client_->SendStanza(stanza);
+}
+
void XmppSignalStrategy::StartSession(
cricket::SessionManager* session_manager) {
cricket::SessionManagerTask* receiver =
@@ -64,6 +82,7 @@ void XmppSignalStrategy::StartSession(
void XmppSignalStrategy::EndSession() {
if (xmpp_client_) {
+ xmpp_client_->engine()->RemoveStanzaHandler(this);
xmpp_client_->Disconnect();
// Client is deleted by TaskRunner.
xmpp_client_ = NULL;
@@ -74,6 +93,11 @@ IqRequest* XmppSignalStrategy::CreateIqRequest() {
return new XmppIqRequest(thread_->message_loop(), xmpp_client_);
}
+bool XmppSignalStrategy::HandleStanza(const buzz::XmlElement* stanza) {
+ listener_->OnIncomingStanza(stanza);
+ return false;
+}
+
void XmppSignalStrategy::OnConnectionStateChanged(
buzz::XmppEngine::State state) {
switch (state) {
@@ -99,6 +123,7 @@ void XmppSignalStrategy::OnConnectionStateChanged(
}
}
+// static
buzz::PreXmppAuth* XmppSignalStrategy::CreatePreXmppAuth(
const buzz::XmppClientSettings& settings) {
buzz::Jid jid(settings.user(), settings.host(), buzz::STR_EMPTY);
diff --git a/remoting/jingle_glue/xmpp_signal_strategy.h b/remoting/jingle_glue/xmpp_signal_strategy.h
index 1becac7..b09a6fc 100644
--- a/remoting/jingle_glue/xmpp_signal_strategy.h
+++ b/remoting/jingle_glue/xmpp_signal_strategy.h
@@ -20,7 +20,9 @@ namespace remoting {
class JingleThread;
-class XmppSignalStrategy : public SignalStrategy, public sigslot::has_slots<> {
+class XmppSignalStrategy : public SignalStrategy,
+ public buzz::XmppStanzaHandler,
+ public sigslot::has_slots<> {
public:
XmppSignalStrategy(JingleThread* thread,
const std::string& username,
@@ -30,10 +32,15 @@ class XmppSignalStrategy : public SignalStrategy, public sigslot::has_slots<> {
// SignalStrategy interface.
virtual void Init(StatusObserver* observer) OVERRIDE;
+ virtual void SetListener(Listener* listener) OVERRIDE;
+ virtual void SendStanza(buzz::XmlElement* stanza) OVERRIDE;
virtual void StartSession(cricket::SessionManager* session_manager) OVERRIDE;
virtual void EndSession() OVERRIDE;
virtual IqRequest* CreateIqRequest() OVERRIDE;
+ // buzz::XmppStanzaHandler interface.
+ virtual bool HandleStanza(const buzz::XmlElement* stanza) OVERRIDE;
+
private:
friend class JingleClientTest;
@@ -43,6 +50,8 @@ class XmppSignalStrategy : public SignalStrategy, public sigslot::has_slots<> {
JingleThread* thread_;
+ Listener* listener_;
+
std::string username_;
std::string auth_token_;
std::string auth_token_service_;