diff options
-rw-r--r-- | remoting/client/plugin/chromoting_scriptable_object.cc | 14 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_scriptable_object.h | 15 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_xmpp_proxy.cc | 57 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_xmpp_proxy.h | 42 | ||||
-rw-r--r-- | remoting/host/chromoting_host.cc | 19 | ||||
-rw-r--r-- | remoting/host/chromoting_host.h | 2 | ||||
-rw-r--r-- | remoting/host/heartbeat_sender.cc | 33 | ||||
-rw-r--r-- | remoting/host/heartbeat_sender.h | 15 | ||||
-rw-r--r-- | remoting/host/heartbeat_sender_unittest.cc | 36 | ||||
-rw-r--r-- | remoting/jingle_glue/iq_request.cc | 90 | ||||
-rw-r--r-- | remoting/jingle_glue/iq_request.h | 98 | ||||
-rw-r--r-- | remoting/jingle_glue/jingle_client.cc | 245 | ||||
-rw-r--r-- | remoting/jingle_glue/jingle_client.h | 153 | ||||
-rw-r--r-- | remoting/jingle_glue/jingle_client_unittest.cc | 15 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.cc | 13 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.h | 1 | ||||
-rw-r--r-- | remoting/protocol/protocol_test_client.cc | 8 |
17 files changed, 619 insertions, 237 deletions
diff --git a/remoting/client/plugin/chromoting_scriptable_object.cc b/remoting/client/plugin/chromoting_scriptable_object.cc index 497e803..b45b822 100644 --- a/remoting/client/plugin/chromoting_scriptable_object.cc +++ b/remoting/client/plugin/chromoting_scriptable_object.cc @@ -9,6 +9,7 @@ #include "ppapi/cpp/var.h" #include "remoting/client/client_config.h" #include "remoting/client/plugin/chromoting_instance.h" +#include "remoting/client/plugin/pepper_xmpp_proxy.h" using pp::Var; @@ -250,6 +251,19 @@ void ChromotingScriptableObject::SignalLoginChallenge() { LogDebugInfo("Exception when invoking loginChallenge JS callback."); } +void ChromotingScriptableObject::AttachXmppProxy(XmppProxy* xmpp_proxy) { + xmpp_proxy_ = xmpp_proxy; +} + +void ChromotingScriptableObject::SendIq(const std::string& iq_request_xml) { + // TODO(ajwong): Do something smart here. + NOTIMPLEMENTED(); +} + +void ChromotingScriptableObject::ReceiveIq(const std::string& iq_response_xml) { + xmpp_proxy_->ReceiveIq(iq_response_xml); +} + Var ChromotingScriptableObject::DoConnect(const std::vector<Var>& args, Var* exception) { if (args.size() != 3) { diff --git a/remoting/client/plugin/chromoting_scriptable_object.h b/remoting/client/plugin/chromoting_scriptable_object.h index aec9c23..b8b848e62 100644 --- a/remoting/client/plugin/chromoting_scriptable_object.h +++ b/remoting/client/plugin/chromoting_scriptable_object.h @@ -65,12 +65,15 @@ #include <string> #include <vector> +#include "base/weak_ptr.h" + #include "ppapi/cpp/dev/scriptable_object_deprecated.h" #include "ppapi/cpp/var.h" namespace remoting { class ChromotingInstance; +class XmppProxy; extern const char kStatusAttribute[]; @@ -91,7 +94,9 @@ enum ConnectionQuality { QUALITY_BAD, }; -class ChromotingScriptableObject : public pp::deprecated::ScriptableObject { +class ChromotingScriptableObject + : public pp::deprecated::ScriptableObject, + public base::SupportsWeakPtr<ChromotingScriptableObject> { public: explicit ChromotingScriptableObject(ChromotingInstance* instance); virtual ~ChromotingScriptableObject(); @@ -118,6 +123,12 @@ class ChromotingScriptableObject : public pp::deprecated::ScriptableObject { // This should be called to signal JS code to provide login information. void SignalLoginChallenge(); + // Handles a Request/Response for a Javascript IQ stanza used to initiate a + // jingle connection. + void AttachXmppProxy(XmppProxy* xmpp_proxy); + void SendIq(const std::string& iq_request_xml); + void ReceiveIq(const std::string& iq_response_xml); + private: typedef std::map<std::string, int> PropertyNameMap; typedef pp::Var (ChromotingScriptableObject::*MethodHandler)( @@ -141,7 +152,6 @@ class ChromotingScriptableObject : public pp::deprecated::ScriptableObject { MethodHandler method; }; - // Routines to add new attribute, method properties. void AddAttribute(const std::string& name, pp::Var attribute); void AddMethod(const std::string& name, MethodHandler handler); @@ -158,6 +168,7 @@ class ChromotingScriptableObject : public pp::deprecated::ScriptableObject { PropertyNameMap property_names_; std::vector<PropertyDescriptor> properties_; + scoped_refptr<XmppProxy> xmpp_proxy_; ChromotingInstance* instance_; }; diff --git a/remoting/client/plugin/pepper_xmpp_proxy.cc b/remoting/client/plugin/pepper_xmpp_proxy.cc new file mode 100644 index 0000000..7e4c26c --- /dev/null +++ b/remoting/client/plugin/pepper_xmpp_proxy.cc @@ -0,0 +1,57 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/client/plugin/pepper_xmpp_proxy.h" + +namespace remoting { + +PepperXmppProxy::PepperXmppProxy(MessageLoop* jingle_message_loop, + MessageLoop* pepper_message_loop) + : jingle_message_loop_(jingle_message_loop), + pepper_message_loop_(pepper_message_loop) { +} + +void PepperXmppProxy::AttachScriptableObject( + ChromotingScriptableObject* scriptable_object, + Task* done) { + DCHECK_EQ(jingle_message_loop_, MessageLoop::Current()); + scriptable_object_ = scriptable_object; + scriptable_object_->AttachXmppProxy(this); +} + +void PepperXmppProxy::AttachJavascriptIqRequest( + JavascriptIqRequest* javascript_iq_request) { + DCHECK_EQ(pepper_message_loop_, MessageLoop::Current()); + javascript_iq_request_ = javascript_iq_request; +} + +void PepperXmppProxy::SendIq(const std::string& iq_request_xml) { + if (MessageLoop::Current() != pepper_message_loop_) { + pepper_message_loop_->PostTask( + NewRunnableMethod(this, + &PepperXmppProxy::SendIq, + iq_request_xml)); + return; + } + + if (scriptable_object_) { + scriptable_object_->SendIq(iq_request_xml, this); + } +} + +void PepperXmppProxy::ReceiveIq(const std::string& iq_response_xml) { + if (MessageLoop::Current() != jingle_message_loop_) { + jingle_message_loop_->PostTask( + NewRunnableMethod(this, + &PepperXmppProxy::ReceiveIq, + iq_response_xml)); + return; + } + + if (javascript_iq_request_) { + javascript_iq_request_->handleIqResponse(iq_response_xml); + } +} + +} // namespace remoting diff --git a/remoting/client/plugin/pepper_xmpp_proxy.h b/remoting/client/plugin/pepper_xmpp_proxy.h new file mode 100644 index 0000000..6c6c553 --- /dev/null +++ b/remoting/client/plugin/pepper_xmpp_proxy.h @@ -0,0 +1,42 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_CLIENT_PLUGIN_PEPPER_XMPP_PROXY_H_ +#define REMOTING_CLIENT_PLUGIN_PEPPER_XMPP_PROXY_H_ + +#include "base/weak_ptr.h" +#include "remoting/jingle_glue/iq_request.h" + +namespace remoting { + +class PepperXmppProxy : public XmppProxy { + public: + PepperXmppProxy(MessageLoop* jingle_message_loop, + MessageLoop* pepper_message_loop); + + // Must be run on pepper thread. + void AttachScriptableObject(ChromotingScriptableObject* scriptable_object); + + // Must be run on jingle thread. + void AttachJavascriptIqRequest(JavascriptIqRequest* javascript_iq_request); + + void SendIq(const std::string& iq_request_xml); + void ReceiveIq(const std::string& iq_response_xml); + + private: + ~PepperXmppProxy(); + + MessageLoop* jingle_message_loop_; + MessageLoop* pepper_message_loop_; + + base::WeakPtr<ChromotingScriptableObject> scriptable_object_; + base::WeakPtr<JavascriptIqRequest> javascript_iq_request_; + std::string iq_response_xml_; + + DISALLOW_COPY_AND_ASSIGN(PepperXmppProxy); +}; + +} // namespace remoting + +#endif // REMOTING_CLIENT_PLUGIN_PEPPER_XMPP_PROXY_H_ diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 38437e8..9522b5c 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -97,12 +97,19 @@ void ChromotingHost::Start(Task* shutdown_task) { return; // Connect to the talk network with a JingleClient. - jingle_client_ = new JingleClient(context_->jingle_thread()); - jingle_client_->Init(xmpp_login, xmpp_auth_token, - kChromotingTokenServiceName, this); - - heartbeat_sender_ = new HeartbeatSender(); - if (!heartbeat_sender_->Init(config_, jingle_client_.get())) { + signal_strategy_.reset( + new XmppSignalStrategy(context_->jingle_thread(), xmpp_login, + xmpp_auth_token, + kChromotingTokenServiceName)); + jingle_client_ = new JingleClient(context_->jingle_thread(), + signal_strategy_.get(), + this); + jingle_client_->Init(); + + heartbeat_sender_ = + new HeartbeatSender(context_->jingle_thread()->message_loop(), + jingle_client_.get(), config_); + if (!heartbeat_sender_->Init()) { LOG(ERROR) << "Failed to initialize HeartbeatSender."; return; } diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index 5a5959f..fc6daaf 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -154,6 +154,8 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, scoped_ptr<DesktopEnvironment> desktop_environment_; + scoped_ptr<SignalStrategy> signal_strategy_; + // The libjingle client. This is used to connect to the talk network to // receive connection requests from chromoting client. scoped_refptr<JingleClient> jingle_client_; diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc index 74c08c3..56ec751 100644 --- a/remoting/host/heartbeat_sender.cc +++ b/remoting/host/heartbeat_sender.cc @@ -33,29 +33,32 @@ const char kSetIntervalTag[] = "set-interval"; const int64 kDefaultHeartbeatIntervalMs = 5 * 60 * 1000; // 5 minutes. } -HeartbeatSender::HeartbeatSender() +HeartbeatSender::HeartbeatSender(MessageLoop* message_loop, + JingleClient* jingle_client, + MutableHostConfig* config) + : state_(CREATED), + message_loop_(message_loop), + jingle_client_(jingle_client), + config_(config), interval_ms_(kDefaultHeartbeatIntervalMs) { + DCHECK(jingle_client_); + DCHECK(config_); } HeartbeatSender::~HeartbeatSender() { DCHECK(state_ == CREATED || state_ == INITIALIZED || state_ == STOPPED); } -bool HeartbeatSender::Init(MutableHostConfig* config, - JingleClient* jingle_client) { - DCHECK(jingle_client); +bool HeartbeatSender::Init() { DCHECK(state_ == CREATED); - jingle_client_ = jingle_client; - config_ = config; - if (!config_->GetString(kHostIdConfigPath, &host_id_)) { LOG(ERROR) << "host_id is not defined in the config."; return false; } - if (!key_pair_.Load(config)) { + if (!key_pair_.Load(config_)) { return false; } @@ -65,8 +68,8 @@ bool HeartbeatSender::Init(MutableHostConfig* config, } void HeartbeatSender::Start() { - if (MessageLoop::current() != jingle_client_->message_loop()) { - jingle_client_->message_loop()->PostTask( + if (MessageLoop::current() != message_loop_) { + message_loop_->PostTask( FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::Start)); return; } @@ -77,13 +80,13 @@ void HeartbeatSender::Start() { request_.reset(jingle_client_->CreateIqRequest()); request_->set_callback(NewCallback(this, &HeartbeatSender::ProcessResponse)); - jingle_client_->message_loop()->PostTask( + message_loop_->PostTask( FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoSendStanza)); } void HeartbeatSender::Stop() { - if (MessageLoop::current() != jingle_client_->message_loop()) { - jingle_client_->message_loop()->PostTask( + if (MessageLoop::current() != message_loop_) { + message_loop_->PostTask( FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::Stop)); return; } @@ -99,7 +102,7 @@ void HeartbeatSender::DoSendStanza() { if (state_ == STARTED) { // |jingle_client_| may be already destroyed if |state_| is set to // |STOPPED|, so don't touch it here unless we are in |STARTED| state. - DCHECK(MessageLoop::current() == jingle_client_->message_loop()); + DCHECK(MessageLoop::current() == message_loop_); VLOG(1) << "Sending heartbeat stanza to " << kChromotingBotJid; @@ -107,7 +110,7 @@ void HeartbeatSender::DoSendStanza() { CreateHeartbeatMessage()); // Schedule next heartbeat. - jingle_client_->message_loop()->PostDelayedTask( + message_loop_->PostDelayedTask( FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoSendStanza), interval_ms_); } diff --git a/remoting/host/heartbeat_sender.h b/remoting/host/heartbeat_sender.h index ef310b4..089e040 100644 --- a/remoting/host/heartbeat_sender.h +++ b/remoting/host/heartbeat_sender.h @@ -18,6 +18,7 @@ namespace remoting { class IqRequest; class HostKeyPair; class JingleClient; +class JingleThread; class MutableHostConfig; // HeartbeatSender periodically sends heartbeat stanzas to the Chromoting Bot. @@ -56,13 +57,14 @@ class MutableHostConfig; // TODO(sergeyu): Is it enough to sign JID and nothing else? class HeartbeatSender : public base::RefCountedThreadSafe<HeartbeatSender> { public: - HeartbeatSender(); + HeartbeatSender(MessageLoop* main_loop, + JingleClient* jingle_client, + MutableHostConfig* config); virtual ~HeartbeatSender(); - // Initializes heart-beating for |jingle_client| with the specified - // config. Returns false if the config is invalid (e.g. private key - // cannot be parsed). - bool Init(MutableHostConfig* config, JingleClient* jingle_client); + // Initializes heart-beating for |jingle_client_| with |config_|. Returns + // false if the config is invalid (e.g. private key cannot be parsed). + bool Init(); // Starts heart-beating. Must be called after init. void Start(); @@ -96,8 +98,9 @@ class HeartbeatSender : public base::RefCountedThreadSafe<HeartbeatSender> { void ProcessResponse(const buzz::XmlElement* response); State state_; - scoped_refptr<MutableHostConfig> config_; + MessageLoop* message_loop_; JingleClient* jingle_client_; + scoped_refptr<MutableHostConfig> config_; scoped_ptr<IqRequest> request_; std::string host_id_; HostKeyPair key_pair_; diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 6e1f4fe..fc59c33 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc @@ -36,20 +36,21 @@ const char kTestJid[] = "user@gmail.com/chromoting123"; const int64 kTestTime = 123123123; } // namespace -class MockJingleClient : public JingleClient { +class MockSignalStrategy : public SignalStrategy { public: - explicit MockJingleClient(JingleThread* thread) : JingleClient(thread) { } + MOCK_METHOD1(Init, void(StatusObserver* observer)); + MOCK_METHOD0(port_allocator, cricket::BasicPortAllocator*()); + MOCK_METHOD1(StartSession, void(cricket::SessionManager* session_manager)); + MOCK_METHOD0(EndSession, void()); MOCK_METHOD0(CreateIqRequest, IqRequest*()); }; class MockIqRequest : public IqRequest { public: - explicit MockIqRequest(JingleClient* jingle_client) - : IqRequest(jingle_client) { - } MOCK_METHOD3(SendIq, void(const std::string& type, const std::string& addressee, XmlElement* iq_body)); + MOCK_METHOD1(set_callback, void(IqRequest::ReplyCallback*)); }; class HeartbeatSenderTest : public testing::Test { @@ -61,12 +62,15 @@ class HeartbeatSenderTest : public testing::Test { jingle_thread_.message_loop_ = &message_loop_; - jingle_client_ = new MockJingleClient(&jingle_thread_); + signal_strategy_.reset(new MockSignalStrategy()); + jingle_client_ = + new JingleClient(&jingle_thread_, signal_strategy_.get(), NULL); jingle_client_->full_jid_ = kTestJid; } JingleThread jingle_thread_; - scoped_refptr<MockJingleClient> jingle_client_; + scoped_ptr<MockSignalStrategy> signal_strategy_; + scoped_refptr<JingleClient> jingle_client_; MessageLoop message_loop_; scoped_refptr<InMemoryHostConfig> config_; }; @@ -75,12 +79,14 @@ class HeartbeatSenderTest : public testing::Test { // being send. TEST_F(HeartbeatSenderTest, DoSendStanza) { // |iq_request| is freed by HeartbeatSender. - MockIqRequest* iq_request = new MockIqRequest(jingle_client_); + MockIqRequest* iq_request = new MockIqRequest(); + EXPECT_CALL(*iq_request, set_callback(_)).Times(1); - scoped_refptr<HeartbeatSender> heartbeat_sender(new HeartbeatSender()); - ASSERT_TRUE(heartbeat_sender->Init(config_, jingle_client_)); + scoped_refptr<HeartbeatSender> heartbeat_sender( + new HeartbeatSender(&message_loop_, jingle_client_.get(), config_)); + ASSERT_TRUE(heartbeat_sender->Init()); - EXPECT_CALL(*jingle_client_, CreateIqRequest()) + EXPECT_CALL(*signal_strategy_, CreateIqRequest()) .WillOnce(Return(iq_request)); EXPECT_CALL(*iq_request, SendIq(buzz::STR_SET, kChromotingBotJid, NotNull())) @@ -95,8 +101,9 @@ TEST_F(HeartbeatSenderTest, DoSendStanza) { // Validate format of the heartbeat stanza. TEST_F(HeartbeatSenderTest, CreateHeartbeatMessage) { - scoped_refptr<HeartbeatSender> heartbeat_sender(new HeartbeatSender()); - ASSERT_TRUE(heartbeat_sender->Init(config_, jingle_client_)); + scoped_refptr<HeartbeatSender> heartbeat_sender( + new HeartbeatSender(&message_loop_, jingle_client_.get(), config_)); + ASSERT_TRUE(heartbeat_sender->Init()); int64 start_time = static_cast<int64>(base::Time::Now().ToDoubleT()); @@ -145,7 +152,8 @@ TEST_F(HeartbeatSenderTest, ProcessResponse) { const int kTestInterval = 123; set_interval->AddText(base::IntToString(kTestInterval)); - scoped_refptr<HeartbeatSender> heartbeat_sender(new HeartbeatSender()); + scoped_refptr<HeartbeatSender> heartbeat_sender( + new HeartbeatSender(&message_loop_, jingle_client_.get(), config_)); heartbeat_sender->ProcessResponse(response.get()); EXPECT_EQ(kTestInterval * 1000, heartbeat_sender->interval_ms_); diff --git a/remoting/jingle_glue/iq_request.cc b/remoting/jingle_glue/iq_request.cc index c56ef4c..8d53b40 100644 --- a/remoting/jingle_glue/iq_request.cc +++ b/remoting/jingle_glue/iq_request.cc @@ -7,28 +7,42 @@ #include "base/logging.h" #include "base/message_loop.h" #include "base/scoped_ptr.h" -#include "remoting/jingle_glue/jingle_client.h" #include "third_party/libjingle/source/talk/xmpp/constants.h" -#include "third_party/libjingle/source/talk/xmpp/xmppengine.h" +#include "third_party/libjingle/source/talk/xmpp/xmppclient.h" namespace remoting { -IqRequest::IqRequest(JingleClient* jingle_client) - : jingle_client_(jingle_client), +// static +buzz::XmlElement* IqRequest::MakeIqStanza(const std::string& type, + const std::string& addressee, + buzz::XmlElement* iq_body, + const std::string& id) { + buzz::XmlElement* stanza = new buzz::XmlElement(buzz::QN_IQ); + stanza->AddAttr(buzz::QN_TYPE, type); + stanza->AddAttr(buzz::QN_TO, addressee); + stanza->AddAttr(buzz::QN_ID, id); + stanza->AddElement(iq_body); + return stanza; +} + +XmppIqRequest::XmppIqRequest(MessageLoop* message_loop, + buzz::XmppClient* xmpp_client) + : message_loop_(message_loop), + xmpp_client_(xmpp_client), cookie_(NULL) { - DCHECK(jingle_client_ != NULL); - DCHECK(MessageLoop::current() == jingle_client_->message_loop()); + DCHECK(xmpp_client_); + DCHECK_EQ(MessageLoop::current(), message_loop_); } -IqRequest::~IqRequest() { - DCHECK(MessageLoop::current() == jingle_client_->message_loop()); +XmppIqRequest::~XmppIqRequest() { + DCHECK_EQ(MessageLoop::current(), message_loop_); Unregister(); } -void IqRequest::SendIq(const std::string& type, +void XmppIqRequest::SendIq(const std::string& type, const std::string& addressee, buzz::XmlElement* iq_body) { - DCHECK(MessageLoop::current() == jingle_client_->message_loop()); + DCHECK_EQ(MessageLoop::current(), message_loop_); // Unregister the handler if it is already registered. Unregister(); @@ -36,44 +50,54 @@ void IqRequest::SendIq(const std::string& type, DCHECK_GT(type.length(), 0U); DCHECK_GT(addressee.length(), 0U); - buzz::XmppClient* xmpp_client = jingle_client_->xmpp_client(); - DCHECK(xmpp_client); // Expect that connection is active. - scoped_ptr<buzz::XmlElement> stanza(MakeIqStanza(type, addressee, iq_body, - xmpp_client->NextId())); + xmpp_client_->NextId())); - xmpp_client->engine()->SendIq(stanza.get(), this, &cookie_); -} - -// static -buzz::XmlElement* IqRequest::MakeIqStanza(const std::string& type, - const std::string& addressee, - buzz::XmlElement* iq_body, - const std::string& id) { - buzz::XmlElement* stanza = new buzz::XmlElement(buzz::QN_IQ); - stanza->AddAttr(buzz::QN_TYPE, type); - stanza->AddAttr(buzz::QN_TO, addressee); - stanza->AddAttr(buzz::QN_ID, id); - stanza->AddElement(iq_body); - return stanza; + xmpp_client_->engine()->SendIq(stanza.get(), this, &cookie_); } -void IqRequest::Unregister() { +void XmppIqRequest::Unregister() { if (cookie_) { - buzz::XmppClient* xmpp_client = jingle_client_->xmpp_client(); // No need to unregister the handler if the client has been destroyed. - if (xmpp_client) { - xmpp_client->engine()->RemoveIqHandler(cookie_, NULL); + if (xmpp_client_) { + xmpp_client_->engine()->RemoveIqHandler(cookie_, NULL); } cookie_ = NULL; } } -void IqRequest::IqResponse(buzz::XmppIqCookie cookie, +void XmppIqRequest::IqResponse(buzz::XmppIqCookie cookie, const buzz::XmlElement* stanza) { if (callback_.get() != NULL) { callback_->Run(stanza); } } +JavascriptIqRequest::JavascriptIqRequest() { +} + +JavascriptIqRequest::~JavascriptIqRequest() { +} + +void JavascriptIqRequest::SendIq(const std::string& type, + const std::string& addressee, + buzz::XmlElement* iq_body) { + NOTIMPLEMENTED(); + // TODO(ajwong): The "1" below is completely wrong. Need to change to use a + // sequence that just increments or something. + scoped_ptr<buzz::XmlElement> stanza( + MakeIqStanza(type, addressee, iq_body, "1")); + + xmpp_proxy_->SendIq(stanza->Str()); +} + +void JavascriptIqRequest::ReceiveIq(const std::string& iq_response) { + // TODO(ajwong): Somehow send this to callback_ here. + LOG(ERROR) << "Got IQ!!!!!!\n" << iq_response; +} + +void JavascriptIqRequest::set_callback(ReplyCallback* callback) { + callback_.reset(callback); +} + } // namespace remoting diff --git a/remoting/jingle_glue/iq_request.h b/remoting/jingle_glue/iq_request.h index 6933b17..3d11034 100644 --- a/remoting/jingle_glue/iq_request.h +++ b/remoting/jingle_glue/iq_request.h @@ -9,11 +9,42 @@ #include "base/callback.h" #include "base/gtest_prod_util.h" +#include "base/weak_ptr.h" #include "third_party/libjingle/source/talk/xmpp/xmppengine.h" +class MessageLoop; + +namespace buzz { +class XmppClient; +} // namespace buzz + namespace remoting { -class JingleClient; +class JavascriptIqRequest; +class ChromotingScriptableObject; + +class XmppProxy : public base::RefCountedThreadSafe<XmppProxy> { + public: + XmppProxy() {} + + // Must be run on pepper thread. + virtual void AttachScriptableObject( + ChromotingScriptableObject* scriptable_object) = 0; + + // Must be run on jingle thread. + virtual void AttachJavascriptIqRequest( + JavascriptIqRequest* javascript_iq_request) = 0; + + virtual void SendIq(const std::string& iq_request_xml) = 0; + virtual void ReceiveIq(const std::string& iq_response_xml) = 0; + + protected: + friend class base::RefCountedThreadSafe<XmppProxy>; + virtual ~XmppProxy() {} + + private: + DISALLOW_COPY_AND_ASSIGN(XmppProxy); +}; // IqRequest class can be used to send an IQ stanza and then receive reply // stanza for that request. It sends outgoing stanza when SendIq() is called, @@ -21,22 +52,67 @@ class JingleClient; // set_callback(). If multiple IQ stanzas are send with SendIq() then only reply // to the last one will be received. // The class must be used on the jingle thread only. -class IqRequest : private buzz::XmppIqHandler { +class IqRequest { public: typedef Callback1<const buzz::XmlElement*>::Type ReplyCallback; - explicit IqRequest(JingleClient* jingle_client); - virtual ~IqRequest(); + IqRequest() {} + virtual ~IqRequest() {} // Sends stanza of type |type| to |addressee|. |iq_body| contains body of // the stanza. Ownership of |iq_body| is transfered to IqRequest. Must // be called on the jingle thread. virtual void SendIq(const std::string& type, const std::string& addressee, - buzz::XmlElement* iq_body); + buzz::XmlElement* iq_body) = 0; // Sets callback that is called when reply stanza is received. Callback // is called on the jingle thread. - void set_callback(ReplyCallback* callback) { + virtual void set_callback(ReplyCallback* callback) = 0; + + protected: + static buzz::XmlElement* MakeIqStanza(const std::string& type, + const std::string& addressee, + buzz::XmlElement* iq_body, + const std::string& id); + + private: + FRIEND_TEST_ALL_PREFIXES(IqRequestTest, MakeIqStanza); + + DISALLOW_COPY_AND_ASSIGN(IqRequest); +}; + +// TODO(ajwong): Is this class even used? The client side may never use +// IqRequests in the JingleClient. +class JavascriptIqRequest : public IqRequest, + public base::SupportsWeakPtr<JavascriptIqRequest> { + public: + JavascriptIqRequest(); + virtual ~JavascriptIqRequest(); + + virtual void SendIq(const std::string& type, const std::string& addressee, + buzz::XmlElement* iq_body); + + virtual void ReceiveIq(const std::string& iq_response); + + virtual void set_callback(ReplyCallback* callback); + + private: + scoped_ptr<ReplyCallback> callback_; + scoped_refptr<XmppProxy> xmpp_proxy_; + + FRIEND_TEST_ALL_PREFIXES(IqRequestTest, MakeIqStanza); +}; + +class XmppIqRequest : public IqRequest, private buzz::XmppIqHandler { + public: + typedef Callback1<const buzz::XmlElement*>::Type ReplyCallback; + + XmppIqRequest(MessageLoop* message_loop, buzz::XmppClient* xmpp_client); + virtual ~XmppIqRequest(); + + virtual void SendIq(const std::string& type, const std::string& addressee, + buzz::XmlElement* iq_body); + virtual void set_callback(ReplyCallback* callback) { callback_.reset(callback); } @@ -47,14 +123,12 @@ class IqRequest : private buzz::XmppIqHandler { virtual void IqResponse(buzz::XmppIqCookie cookie, const buzz::XmlElement* stanza); - static buzz::XmlElement* MakeIqStanza(const std::string& type, - const std::string& addressee, - buzz::XmlElement* iq_body, - const std::string& id); - void Unregister(); - scoped_refptr<JingleClient> jingle_client_; + // TODO(ajwong): This used to hold a reference to the jingle client...make + // sure the lifetime names sense now. + MessageLoop* message_loop_; + buzz::XmppClient* xmpp_client_; buzz::XmppIqCookie cookie_; scoped_ptr<ReplyCallback> callback_; }; diff --git a/remoting/jingle_glue/jingle_client.cc b/remoting/jingle_glue/jingle_client.cc index 7b00d79..02593ed 100644 --- a/remoting/jingle_glue/jingle_client.cc +++ b/remoting/jingle_glue/jingle_client.cc @@ -22,79 +22,178 @@ namespace remoting { -JingleClient::JingleClient(JingleThread* thread) - : thread_(thread), - callback_(NULL), - client_(NULL), - state_(START), - initialized_(false), - closed_(false) { -} - -JingleClient::~JingleClient() { - base::AutoLock auto_lock(state_lock_); - DCHECK(!initialized_ || closed_); +// The XmppSignalStrategy encapsulates all the logic to perform the signaling +// STUN/ICE for jingle via a direct XMPP connection. +// +// This class is not threadsafe. +XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread, + const std::string& username, + const std::string& auth_token, + const std::string& auth_token_service) + : thread_(jingle_thread), + username_(username), + auth_token_(auth_token), + auth_token_service_(auth_token_service), + xmpp_client_(NULL), + observer_(NULL) { } -void JingleClient::Init( - const std::string& username, const std::string& auth_token, - const std::string& auth_token_service, Callback* callback) { - DCHECK_NE(username, ""); - - { - base::AutoLock auto_lock(state_lock_); - DCHECK(!initialized_ && !closed_); - initialized_ = true; - - DCHECK(callback != NULL); - callback_ = callback; - } - - message_loop()->PostTask( - FROM_HERE, NewRunnableMethod(this, &JingleClient::DoInitialize, - username, auth_token, auth_token_service)); +XmppSignalStrategy::~XmppSignalStrategy() { } -void JingleClient::DoInitialize(const std::string& username, - const std::string& auth_token, - const std::string& auth_token_service) { - DCHECK_EQ(message_loop(), MessageLoop::current()); +void XmppSignalStrategy::Init(StatusObserver* observer) { + observer_ = observer; - buzz::Jid login_jid(username); + buzz::Jid login_jid(username_); buzz::XmppClientSettings settings; settings.set_user(login_jid.node()); settings.set_host(login_jid.domain()); settings.set_resource("chromoting"); settings.set_use_tls(true); - settings.set_token_service(auth_token_service); - settings.set_auth_cookie(auth_token); + settings.set_token_service(auth_token_service_); + settings.set_auth_cookie(auth_token_); settings.set_server(talk_base::SocketAddress("talk.google.com", 5222)); - client_ = new buzz::XmppClient(thread_->task_pump()); - client_->SignalStateChange.connect( - this, &JingleClient::OnConnectionStateChanged); - buzz::AsyncSocket* socket = new XmppSocketAdapter(settings, false); - client_->Connect(settings, "", socket, CreatePreXmppAuth(settings)); - client_->Start(); + xmpp_client_ = new buzz::XmppClient(thread_->task_pump()); + xmpp_client_->Connect(settings, "", socket, CreatePreXmppAuth(settings)); + xmpp_client_->SignalStateChange.connect( + this, &XmppSignalStrategy::OnConnectionStateChanged); + xmpp_client_->Start(); + // Setup the port allocation based on jingle connections. network_manager_.reset(new talk_base::NetworkManager()); - RelayPortAllocator* port_allocator = new RelayPortAllocator(network_manager_.get(), "transp2"); + port_allocator->SetJingleInfo(xmpp_client_); port_allocator_.reset(port_allocator); - port_allocator->SetJingleInfo(client_); +} - session_manager_.reset(new cricket::SessionManager(port_allocator_.get())); +cricket::BasicPortAllocator* XmppSignalStrategy::port_allocator() { + return port_allocator_.get(); +} +void XmppSignalStrategy::StartSession( + cricket::SessionManager* session_manager) { cricket::SessionManagerTask* receiver = - new cricket::SessionManagerTask(client_, session_manager_.get()); + new cricket::SessionManagerTask(xmpp_client_, session_manager); receiver->EnableOutgoingMessages(); receiver->Start(); } +void XmppSignalStrategy::EndSession() { + if (xmpp_client_) { + xmpp_client_->Disconnect(); + // Client is deleted by TaskRunner. + xmpp_client_ = NULL; + } +} + +IqRequest* XmppSignalStrategy::CreateIqRequest() { + return new XmppIqRequest(thread_->message_loop(), xmpp_client_); +} + +void XmppSignalStrategy::OnConnectionStateChanged( + buzz::XmppEngine::State state) { + switch (state) { + case buzz::XmppEngine::STATE_START: + observer_->OnStateChange(StatusObserver::START); + break; + case buzz::XmppEngine::STATE_OPENING: + observer_->OnStateChange(StatusObserver::CONNECTING); + break; + case buzz::XmppEngine::STATE_OPEN: + observer_->OnJidChange(xmpp_client_->jid().Str()); + observer_->OnStateChange(StatusObserver::CONNECTED); + break; + case buzz::XmppEngine::STATE_CLOSED: + observer_->OnStateChange(StatusObserver::CLOSED); + // Client is destroyed by the TaskRunner after the client is + // closed. Reset the pointer so we don't try to use it later. + xmpp_client_ = NULL; + break; + default: + NOTREACHED(); + break; + } +} + +buzz::PreXmppAuth* XmppSignalStrategy::CreatePreXmppAuth( + const buzz::XmppClientSettings& settings) { + buzz::Jid jid(settings.user(), settings.host(), buzz::STR_EMPTY); + return new notifier::GaiaTokenPreXmppAuth(jid.Str(), settings.auth_cookie(), + settings.token_service()); +} + + +JavascriptSignalStrategy::JavascriptSignalStrategy() { +} + +JavascriptSignalStrategy::~JavascriptSignalStrategy() { +} + +void JavascriptSignalStrategy::Init(StatusObserver* observer) { + NOTIMPLEMENTED(); +} + +cricket::BasicPortAllocator* JavascriptSignalStrategy::port_allocator() { + NOTIMPLEMENTED(); + return NULL; +} + +void JavascriptSignalStrategy::StartSession( + cricket::SessionManager* session_manager) { + NOTIMPLEMENTED(); +} + +void JavascriptSignalStrategy::EndSession() { + NOTIMPLEMENTED(); +} + +IqRequest* JavascriptSignalStrategy::CreateIqRequest() { + return new JavascriptIqRequest(); +} + +JingleClient::JingleClient(JingleThread* thread, + SignalStrategy* signal_strategy, + Callback* callback) + : thread_(thread), + state_(START), + initialized_(false), + closed_(false), + callback_(callback), + signal_strategy_(signal_strategy) { +} + +JingleClient::~JingleClient() { + base::AutoLock auto_lock(state_lock_); + DCHECK(!initialized_ || closed_); +} + +void JingleClient::Init() { + { + base::AutoLock auto_lock(state_lock_); + DCHECK(!initialized_ && !closed_); + initialized_ = true; + } + + message_loop()->PostTask( + FROM_HERE, NewRunnableMethod(this, &JingleClient::DoInitialize)); +} + +void JingleClient::DoInitialize() { + DCHECK_EQ(message_loop(), MessageLoop::current()); + + signal_strategy_->Init(this); + + session_manager_.reset( + new cricket::SessionManager(signal_strategy_->port_allocator())); + + signal_strategy_->StartSession(session_manager_.get()); +} + void JingleClient::Close() { Close(NULL); } @@ -121,14 +220,9 @@ void JingleClient::DoClose() { DCHECK(closed_); session_manager_.reset(); - port_allocator_.reset(); - network_manager_.reset(); - - if (client_) { - client_->Disconnect(); - // Client is deleted by TaskRunner. - client_ = NULL; - } + signal_strategy_->EndSession(); + // TODO(ajwong): SignalStrategy should drop all resources at EndSession(). + signal_strategy_ = NULL; if (closed_task_.get()) { closed_task_->Run(); @@ -137,12 +231,12 @@ void JingleClient::DoClose() { } std::string JingleClient::GetFullJid() { - base::AutoLock auto_lock(full_jid_lock_); + base::AutoLock auto_lock(jid_lock_); return full_jid_; } IqRequest* JingleClient::CreateIqRequest() { - return new IqRequest(this); + return signal_strategy_->CreateIqRequest(); } MessageLoop* JingleClient::message_loop() { @@ -154,36 +248,7 @@ cricket::SessionManager* JingleClient::session_manager() { return session_manager_.get(); } -void JingleClient::OnConnectionStateChanged(buzz::XmppEngine::State state) { - switch (state) { - case buzz::XmppEngine::STATE_START: - UpdateState(START); - break; - case buzz::XmppEngine::STATE_OPENING: - UpdateState(CONNECTING); - break; - case buzz::XmppEngine::STATE_OPEN: - SetFullJid(client_->jid().Str()); - UpdateState(CONNECTED); - break; - case buzz::XmppEngine::STATE_CLOSED: - UpdateState(CLOSED); - // Client is destroyed by the TaskRunner after the client is - // closed. Reset the pointer so we don't try to use it later. - client_ = NULL; - break; - default: - NOTREACHED(); - break; - } -} - -void JingleClient::SetFullJid(const std::string& full_jid) { - base::AutoLock auto_lock(full_jid_lock_); - full_jid_ = full_jid; -} - -void JingleClient::UpdateState(State new_state) { +void JingleClient::OnStateChange(State new_state) { if (new_state != state_) { state_ = new_state; { @@ -196,11 +261,9 @@ void JingleClient::UpdateState(State new_state) { } } -buzz::PreXmppAuth* JingleClient::CreatePreXmppAuth( - const buzz::XmppClientSettings& settings) { - buzz::Jid jid(settings.user(), settings.host(), buzz::STR_EMPTY); - return new notifier::GaiaTokenPreXmppAuth(jid.Str(), settings.auth_cookie(), - settings.token_service()); +void JingleClient::OnJidChange(const std::string& full_jid) { + base::AutoLock auto_lock(jid_lock_); + full_jid_ = full_jid; } } // namespace remoting diff --git a/remoting/jingle_glue/jingle_client.h b/remoting/jingle_glue/jingle_client.h index 173e90e..f60e029 100644 --- a/remoting/jingle_glue/jingle_client.h +++ b/remoting/jingle_glue/jingle_client.h @@ -7,6 +7,7 @@ #include <string> +#include "base/gtest_prod_util.h" #include "base/ref_counted.h" #include "base/synchronization/lock.h" #include "third_party/libjingle/source/talk/xmpp/xmppclient.h" @@ -35,16 +36,90 @@ namespace remoting { class IqRequest; class JingleThread; -class JingleClient : public base::RefCountedThreadSafe<JingleClient>, - public sigslot::has_slots<> { +// TODO(ajwong): The SignalStrategy stuff needs to be separated out to separate +// files. +class SignalStrategy { public: - enum State { - START, // Initial state. - CONNECTING, - CONNECTED, - CLOSED, + class StatusObserver { + public: + enum State { + START, + CONNECTING, + CONNECTED, + CLOSED, + }; + + // Called when state of the connection is changed. + virtual void OnStateChange(State state) = 0; + virtual void OnJidChange(const std::string& full_jid) = 0; }; + SignalStrategy() {} + virtual ~SignalStrategy() {} + virtual void Init(StatusObserver* observer) = 0; + virtual cricket::BasicPortAllocator* port_allocator() = 0; + virtual void StartSession(cricket::SessionManager* session_manager) = 0; + virtual void EndSession() = 0; + virtual IqRequest* CreateIqRequest() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SignalStrategy); +}; + +class XmppSignalStrategy : public SignalStrategy, public sigslot::has_slots<> { + public: + XmppSignalStrategy(JingleThread* thread, + const std::string& username, + const std::string& auth_token, + const std::string& auth_token_service); + virtual ~XmppSignalStrategy(); + + virtual void Init(StatusObserver* observer); + virtual cricket::BasicPortAllocator* port_allocator(); + virtual void StartSession(cricket::SessionManager* session_manager); + virtual void EndSession(); + virtual IqRequest* CreateIqRequest(); + + private: + void OnConnectionStateChanged(buzz::XmppEngine::State state); + static buzz::PreXmppAuth* CreatePreXmppAuth( + const buzz::XmppClientSettings& settings); + + JingleThread* thread_; + + std::string username_; + std::string auth_token_; + std::string auth_token_service_; + buzz::XmppClient* xmpp_client_; + StatusObserver* observer_; + scoped_ptr<talk_base::NetworkManager> network_manager_; + scoped_ptr<cricket::BasicPortAllocator> port_allocator_; + + private: + friend class JingleClientTest; + + DISALLOW_COPY_AND_ASSIGN(XmppSignalStrategy); +}; + +class JavascriptSignalStrategy : public SignalStrategy { + public: + JavascriptSignalStrategy(); + virtual ~JavascriptSignalStrategy(); + + virtual void Init(StatusObserver* observer); + virtual cricket::BasicPortAllocator* port_allocator(); + virtual void StartSession(cricket::SessionManager* session_manager); + virtual void EndSession(); + virtual IqRequest* CreateIqRequest(); + + private: + DISALLOW_COPY_AND_ASSIGN(JavascriptSignalStrategy); +}; + + +class JingleClient : public base::RefCountedThreadSafe<JingleClient>, + public SignalStrategy::StatusObserver { + public: class Callback { public: virtual ~Callback() {} @@ -53,17 +128,13 @@ class JingleClient : public base::RefCountedThreadSafe<JingleClient>, virtual void OnStateChange(JingleClient* client, State state) = 0; }; - // Creates a JingleClient object that executes on |thread|. This does not - // take ownership of |thread| and expects that the thread is started before - // the constructor is called, and only stopped after the JingleClient object - // has been destructed. - explicit JingleClient(JingleThread* thread); - virtual ~JingleClient(); + JingleClient(JingleThread* thread, SignalStrategy* signal_strategy, + Callback* callback); + ~JingleClient(); // Starts the XMPP connection initialization. Must be called only once. // |callback| specifies callback object for the client and must not be NULL. - void Init(const std::string& username, const std::string& auth_token, - const std::string& auth_token_service, Callback* callback); + void Init(); // Closes XMPP connection and stops the thread. Must be called before the // object is destroyed. If specified, |closed_task| is executed after the @@ -77,64 +148,52 @@ class JingleClient : public base::RefCountedThreadSafe<JingleClient>, // Creates new IqRequest for this client. Ownership for of the created object // is transfered to the caller. - virtual IqRequest* CreateIqRequest(); - - // Current connection state of the client. - State state() { return state_; } - - // Returns XmppClient object for the xmpp connection or NULL if not connected. - buzz::XmppClient* xmpp_client() { return client_; } - - // Message loop used by this object to execute tasks. - MessageLoop* message_loop(); + IqRequest* CreateIqRequest(); // The session manager used by this client. Must be called from the // jingle thread only. Returns NULL if the client is not active. cricket::SessionManager* session_manager(); + // Message loop used by this object to execute tasks. + MessageLoop* message_loop(); + private: friend class HeartbeatSenderTest; friend class JingleClientTest; - void OnConnectionStateChanged(buzz::XmppEngine::State state); - - void DoInitialize(const std::string& username, - const std::string& auth_token, - const std::string& auth_token_service); - - // Used by Close(). + void DoInitialize(); void DoClose(); - void SetFullJid(const std::string& full_jid); - // Updates current state of the connection. Must be called only in // the jingle thread. void UpdateState(State new_state); - buzz::PreXmppAuth* CreatePreXmppAuth( - const buzz::XmppClientSettings& settings); + virtual void OnStateChange(State state); + virtual void OnJidChange(const std::string& full_jid); // JingleThread used for the connection. Set in the constructor. JingleThread* thread_; - // Callback for this object. Callback must not be called if closed_ == true. - Callback* callback_; - - // The XmppClient and its state and jid. - buzz::XmppClient* client_; - State state_; - base::Lock full_jid_lock_; - std::string full_jid_; - // Current state of the object. // Must be locked when accessing initialized_ or closed_. base::Lock state_lock_; + State state_; bool initialized_; bool closed_; scoped_ptr<Task> closed_task_; - scoped_ptr<talk_base::NetworkManager> network_manager_; - scoped_ptr<cricket::BasicPortAllocator> port_allocator_; + // We need a separate lock for the jid since the |state_lock_| may be held + // over a callback which can end up having a double lock. + // + // TODO(ajwong): Can we avoid holding the |state_lock_| over a callback and + // remove this extra lock? + base::Lock jid_lock_; + std::string full_jid_; + + // Callback for this object. Callback must not be called if closed_ == true. + Callback* callback_; + + SignalStrategy* signal_strategy_; scoped_ptr<cricket::SessionManager> session_manager_; DISALLOW_COPY_AND_ASSIGN(JingleClient); diff --git a/remoting/jingle_glue/jingle_client_unittest.cc b/remoting/jingle_glue/jingle_client_unittest.cc index 807f061..3d9f574 100644 --- a/remoting/jingle_glue/jingle_client_unittest.cc +++ b/remoting/jingle_glue/jingle_client_unittest.cc @@ -29,22 +29,25 @@ class JingleClientTest : public testing::Test { // A helper that calls OnConnectionStateChanged(). Need this because we want // to call it on the jingle thread. - static void ChangeState(JingleClient* client, buzz::XmppEngine::State state, + static void ChangeState(XmppSignalStrategy* strategy, + buzz::XmppEngine::State state, base::WaitableEvent* done_event) { - client->OnConnectionStateChanged(state); + strategy->OnConnectionStateChanged(state); if (done_event) done_event->Signal(); } protected: virtual void SetUp() { - client_ = new JingleClient(&thread_); + signal_strategy_.reset(new XmppSignalStrategy(&thread_, "", "", "")); + client_ = new JingleClient(&thread_, signal_strategy_.get(), &callback_); // Fake initialization client_->initialized_ = true; - client_->callback_ = &callback_; + signal_strategy_->observer_ = client_; } JingleThread thread_; + scoped_ptr<XmppSignalStrategy> signal_strategy_; scoped_refptr<JingleClient> client_; MockJingleClientCallback callback_; }; @@ -57,7 +60,7 @@ TEST_F(JingleClientTest, OnStateChanged) { base::WaitableEvent state_changed_event(true, false); thread_.message_loop()->PostTask(FROM_HERE, NewRunnableFunction( - &JingleClientTest::ChangeState, client_, + &JingleClientTest::ChangeState, signal_strategy_.get(), buzz::XmppEngine::STATE_OPENING, &state_changed_event)); state_changed_event.Wait(); @@ -73,7 +76,7 @@ TEST_F(JingleClientTest, Close) { client_->Close(); // Verify that the channel doesn't call callback anymore. thread_.message_loop()->PostTask(FROM_HERE, NewRunnableFunction( - &JingleClientTest::ChangeState, client_, + &JingleClientTest::ChangeState, signal_strategy_.get(), buzz::XmppEngine::STATE_OPENING, static_cast<base::WaitableEvent*>(NULL))); thread_.Stop(); diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc index 67719f4..27d2da1 100644 --- a/remoting/protocol/connection_to_host.cc +++ b/remoting/protocol/connection_to_host.cc @@ -53,9 +53,16 @@ void ConnectionToHost::Connect(const std::string& username, video_stub_ = video_stub; // Initialize |jingle_client_|. - jingle_client_ = new JingleClient(thread_); - jingle_client_->Init(username, auth_token, - kChromotingTokenServiceName, this); + if (1 == 0) { + signal_strategy_.reset(new JavascriptSignalStrategy()); + } else { + signal_strategy_.reset( + new XmppSignalStrategy(thread_, username, auth_token, + kChromotingTokenServiceName)); + } + + jingle_client_ = new JingleClient(thread_, signal_strategy_.get(), this); + jingle_client_->Init(); // Save jid of the host. The actual connection is created later after // |jingle_client_| is connected. diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h index 515b89a..0869a7b 100644 --- a/remoting/protocol/connection_to_host.h +++ b/remoting/protocol/connection_to_host.h @@ -98,6 +98,7 @@ class ConnectionToHost : public JingleClient::Callback { JingleThread* thread_; + scoped_ptr<SignalStrategy> signal_strategy_; scoped_refptr<JingleClient> jingle_client_; scoped_refptr<SessionManager> session_manager_; scoped_refptr<Session> session_; diff --git a/remoting/protocol/protocol_test_client.cc b/remoting/protocol/protocol_test_client.cc index 849bbd7..f95b93e 100644 --- a/remoting/protocol/protocol_test_client.cc +++ b/remoting/protocol/protocol_test_client.cc @@ -112,6 +112,7 @@ class ProtocolTestClient void DestroyConnection(scoped_refptr<ProtocolTestConnection> connection); std::string host_jid_; + scoped_ptr<SignalStrategy> signal_strategy_; scoped_refptr<JingleClient> client_; scoped_refptr<JingleSessionManager> session_manager_; ConnectionsList connections_; @@ -225,8 +226,11 @@ void ProtocolTestClient::Run(const std::string& username, const std::string& host_jid) { remoting::JingleThread jingle_thread; jingle_thread.Start(); - client_ = new JingleClient(&jingle_thread); - client_->Init(username, auth_token, kChromotingTokenServiceName, this); + signal_strategy_.reset( + new XmppSignalStrategy(&jingle_thread, username, auth_token, + kChromotingTokenServiceName)); + client_ = new JingleClient(&jingle_thread, signal_strategy_.get(), this); + client_->Init(); session_manager_ = new JingleSessionManager(&jingle_thread); |