diff options
Diffstat (limited to 'remoting')
39 files changed, 334 insertions, 285 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index a80e808..3633d23 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -93,11 +93,18 @@ void ChromotingHost::Start() { return; } + // Create and start XMPP connection. signal_strategy_.reset( new XmppSignalStrategy(context_->jingle_thread(), xmpp_login, - xmpp_auth_token, - xmpp_auth_service)); - signal_strategy_->Init(this); + xmpp_auth_token, xmpp_auth_service)); + signal_strategy_->AddListener(this); + signal_strategy_->Connect(); + + // Create and start session manager. + session_manager_.reset( + new protocol::JingleSessionManager(context_->network_message_loop())); + session_manager_->Init(signal_strategy_.get(), + this, allow_nat_traversal_); } // This method is called when we need to destroy the host process. @@ -140,13 +147,9 @@ void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { // Stop XMPP connection synchronously. if (signal_strategy_.get()) { - signal_strategy_->Close(); + signal_strategy_->Disconnect(); + signal_strategy_->RemoveListener(this); signal_strategy_.reset(); - - for (StatusObserverList::iterator it = status_observers_.begin(); - it != status_observers_.end(); ++it) { - (*it)->OnSignallingDisconnected(); - } } if (recorder_.get()) { @@ -163,14 +166,10 @@ void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { void ChromotingHost::SetSharedSecret(const std::string& shared_secret) { DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); - shared_secret_ = shared_secret; - have_shared_secret_ = true; - if (session_manager_.get()) { - session_manager_->set_authenticator_factory( - new protocol::V1HostAuthenticatorFactory( - key_pair_.GenerateCertificate(), key_pair_.private_key(), - shared_secret_)); - } + session_manager_->set_authenticator_factory( + new protocol::V1HostAuthenticatorFactory( + key_pair_.GenerateCertificate(), key_pair_.private_key(), + shared_secret)); } //////////////////////////////////////////////////////////////////////////// @@ -257,33 +256,18 @@ void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, //////////////////////////////////////////////////////////////////////////// // SignalStrategy::StatusObserver implementations -void ChromotingHost::OnStateChange( - SignalStrategy::StatusObserver::State state) { +void ChromotingHost::OnSignalStrategyStateChange( + SignalStrategy::State state) { DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); - if (state == SignalStrategy::StatusObserver::CONNECTED) { - LOG(INFO) << "Host connected as " << local_jid_; - - // Create and start session manager. - protocol::JingleSessionManager* server = - new protocol::JingleSessionManager(context_->network_message_loop()); - - server->Init(local_jid_, signal_strategy_.get(), - this, allow_nat_traversal_); - - session_manager_.reset(server); - if (have_shared_secret_) { - session_manager_->set_authenticator_factory( - new protocol::V1HostAuthenticatorFactory( - key_pair_.GenerateCertificate(), key_pair_.private_key(), - shared_secret_)); - } + if (state == SignalStrategy::CONNECTED) { + LOG(INFO) << "Host connected as " << signal_strategy_->GetLocalJid(); for (StatusObserverList::iterator it = status_observers_.begin(); it != status_observers_.end(); ++it) { - (*it)->OnSignallingConnected(signal_strategy_.get(), local_jid_); + (*it)->OnSignallingConnected(signal_strategy_.get()); } - } else if (state == SignalStrategy::StatusObserver::CLOSED) { + } else if (state == SignalStrategy::DISCONNECTED) { LOG(INFO) << "Host disconnected from talk network."; for (StatusObserverList::iterator it = status_observers_.begin(); it != status_observers_.end(); ++it) { @@ -292,12 +276,7 @@ void ChromotingHost::OnStateChange( } } -void ChromotingHost::OnJidChange(const std::string& full_jid) { - DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); - local_jid_ = full_jid; -} - -void ChromotingHost::OnSessionManagerInitialized() { +void ChromotingHost::OnSessionManagerReady() { DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); // Don't need to do anything here, just wait for incoming // connections. diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index 0490525..5fede90 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -62,7 +62,7 @@ class ScreenRecorder; // incoming connection. class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, public ClientSession::EventHandler, - public SignalStrategy::StatusObserver, + public SignalStrategy::Listener, public protocol::SessionManager::Listener { public: // Factory methods that must be used to create ChromotingHost @@ -98,10 +98,9 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, void SetSharedSecret(const std::string& shared_secret); //////////////////////////////////////////////////////////////////////////// - // SignalStrategy::StatusObserver implementation. - virtual void OnStateChange( - SignalStrategy::StatusObserver::State state) OVERRIDE; - virtual void OnJidChange(const std::string& full_jid) OVERRIDE; + // SignalStrategy::Listener interface. + virtual void OnSignalStrategyStateChange( + SignalStrategy::State state) OVERRIDE; //////////////////////////////////////////////////////////////////////////// // ClientSession::EventHandler implementation. @@ -112,7 +111,7 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, int64 sequence_number) OVERRIDE; // SessionManager::Listener implementation. - virtual void OnSessionManagerInitialized() OVERRIDE; + virtual void OnSessionManagerReady() OVERRIDE; virtual void OnIncomingSession( protocol::Session* session, protocol::SessionManager::IncomingSessionResponse* response) OVERRIDE; diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc index f95aecc..2a7d8ac0 100644 --- a/remoting/host/heartbeat_sender.cc +++ b/remoting/host/heartbeat_sender.cc @@ -65,13 +65,12 @@ bool HeartbeatSender::Init() { return true; } -void HeartbeatSender::OnSignallingConnected(SignalStrategy* signal_strategy, - const std::string& full_jid) { +void HeartbeatSender::OnSignallingConnected(SignalStrategy* signal_strategy) { DCHECK(message_loop_->BelongsToCurrentThread()); DCHECK(state_ == INITIALIZED || state_ == STOPPED); state_ = STARTED; - full_jid_ = full_jid; + full_jid_ = signal_strategy->GetLocalJid(); iq_sender_.reset(new IqSender(signal_strategy)); diff --git a/remoting/host/heartbeat_sender.h b/remoting/host/heartbeat_sender.h index 582bc28..63c9576 100644 --- a/remoting/host/heartbeat_sender.h +++ b/remoting/host/heartbeat_sender.h @@ -75,8 +75,7 @@ class HeartbeatSender : public HostStatusObserver { bool Init(); // HostStatusObserver implementation. - virtual void OnSignallingConnected(SignalStrategy* signal_strategy, - const std::string& full_jid) OVERRIDE; + virtual void OnSignallingConnected(SignalStrategy* signal_strategy) OVERRIDE; virtual void OnSignallingDisconnected() OVERRIDE; virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE; virtual void OnClientDisconnected(const std::string& jid) OVERRIDE; diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 4c3390a..b1de98b 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc @@ -64,12 +64,14 @@ TEST_F(HeartbeatSenderTest, DoSendStanza) { ASSERT_TRUE(heartbeat_sender->Init()); XmlElement* sent_iq = NULL; + EXPECT_CALL(signal_strategy_, GetLocalJid()) + .WillRepeatedly(Return(kTestJid)); EXPECT_CALL(signal_strategy_, GetNextId()) .WillOnce(Return(kStanzaId)); EXPECT_CALL(signal_strategy_, SendStanza(NotNull())) .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); - heartbeat_sender->OnSignallingConnected(&signal_strategy_, kTestJid); + heartbeat_sender->OnSignallingConnected(&signal_strategy_); message_loop_.RunAllPending(); scoped_ptr<XmlElement> stanza(sent_iq); diff --git a/remoting/host/host_status_observer.h b/remoting/host/host_status_observer.h index ea47a69..cb5574d 100644 --- a/remoting/host/host_status_observer.h +++ b/remoting/host/host_status_observer.h @@ -18,8 +18,7 @@ class HostStatusObserver { virtual ~HostStatusObserver() { } // Called when status of the signalling channel changes. - virtual void OnSignallingConnected(SignalStrategy* signal_strategy, - const std::string& full_jid) = 0; + virtual void OnSignallingConnected(SignalStrategy* signal_strategy) = 0; virtual void OnSignallingDisconnected() = 0; // Called when an unauthorized user attempts to connect to the host. diff --git a/remoting/host/it2me_host_user_interface.cc b/remoting/host/it2me_host_user_interface.cc index 56b9c7b..857eaca 100644 --- a/remoting/host/it2me_host_user_interface.cc +++ b/remoting/host/it2me_host_user_interface.cc @@ -53,7 +53,7 @@ void It2MeHostUserInterface::InitFrom(DisconnectWindow* disconnect_window, } void It2MeHostUserInterface::OnSignallingConnected( - SignalStrategy* signal_strategy, const std::string& full_jid) { + SignalStrategy* signal_strategy) { } void It2MeHostUserInterface::OnSignallingDisconnected() { diff --git a/remoting/host/it2me_host_user_interface.h b/remoting/host/it2me_host_user_interface.h index 8b9da6a..5450175 100644 --- a/remoting/host/it2me_host_user_interface.h +++ b/remoting/host/it2me_host_user_interface.h @@ -42,8 +42,7 @@ class It2MeHostUserInterface : public HostStatusObserver { // HostStatusObserver implementation. These methods will be called from the // network thread. - virtual void OnSignallingConnected(SignalStrategy* signal_strategy, - const std::string& full_jid) OVERRIDE; + virtual void OnSignallingConnected(SignalStrategy* signal_strategy) OVERRIDE; virtual void OnSignallingDisconnected() OVERRIDE; virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE; virtual void OnClientDisconnected(const std::string& jid) OVERRIDE; diff --git a/remoting/host/log_to_server.cc b/remoting/host/log_to_server.cc index 0dc3618..082cb13 100644 --- a/remoting/host/log_to_server.cc +++ b/remoting/host/log_to_server.cc @@ -37,8 +37,7 @@ void LogToServer::LogSessionStateChange(bool connected) { Log(*entry.get()); } -void LogToServer::OnSignallingConnected(SignalStrategy* signal_strategy, - const std::string& full_jid) { +void LogToServer::OnSignallingConnected(SignalStrategy* signal_strategy) { DCHECK(message_loop_->BelongsToCurrentThread()); iq_sender_.reset(new IqSender(signal_strategy)); SendPendingEntries(); diff --git a/remoting/host/log_to_server.h b/remoting/host/log_to_server.h index b7b17d5..1cf27cf 100644 --- a/remoting/host/log_to_server.h +++ b/remoting/host/log_to_server.h @@ -39,8 +39,7 @@ class LogToServer : public HostStatusObserver { void LogSessionStateChange(bool connected); // HostStatusObserver implementation. - virtual void OnSignallingConnected(SignalStrategy* signal_strategy, - const std::string& full_jid) OVERRIDE; + virtual void OnSignallingConnected(SignalStrategy* signal_strategy) OVERRIDE; virtual void OnSignallingDisconnected() OVERRIDE; virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE; virtual void OnClientDisconnected(const std::string& jid) OVERRIDE; diff --git a/remoting/host/log_to_server_unittest.cc b/remoting/host/log_to_server_unittest.cc index d67e76e..0749163 100644 --- a/remoting/host/log_to_server_unittest.cc +++ b/remoting/host/log_to_server_unittest.cc @@ -44,6 +44,8 @@ class LogToServerTest : public testing::Test { TEST_F(LogToServerTest, SendNow) { { InSequence s; + EXPECT_CALL(signal_strategy_, GetLocalJid()) + .WillRepeatedly(Return("host@domain.com/1234")); EXPECT_CALL(signal_strategy_, AddListener(_)); EXPECT_CALL(signal_strategy_, GetNextId()); EXPECT_CALL(signal_strategy_, SendStanza(_)) @@ -52,8 +54,7 @@ TEST_F(LogToServerTest, SendNow) { .WillOnce(QuitMainMessageLoop(&message_loop_)) .RetiresOnSaturation(); } - log_to_server_->OnSignallingConnected(&signal_strategy_, - "host@domain.com/1234"); + log_to_server_->OnSignallingConnected(&signal_strategy_); log_to_server_->OnClientAuthenticated("client@domain.com/5678"); log_to_server_->OnSignallingDisconnected(); message_loop_.Run(); @@ -62,6 +63,8 @@ TEST_F(LogToServerTest, SendNow) { TEST_F(LogToServerTest, SendLater) { { InSequence s; + EXPECT_CALL(signal_strategy_, GetLocalJid()) + .WillRepeatedly(Return("host@domain.com/1234")); EXPECT_CALL(signal_strategy_, AddListener(_)); EXPECT_CALL(signal_strategy_, GetNextId()); EXPECT_CALL(signal_strategy_, SendStanza(_)) @@ -71,8 +74,7 @@ TEST_F(LogToServerTest, SendLater) { .RetiresOnSaturation(); } log_to_server_->OnClientAuthenticated("client@domain.com/5678"); - log_to_server_->OnSignallingConnected(&signal_strategy_, - "host@domain.com/1234"); + log_to_server_->OnSignallingConnected(&signal_strategy_); log_to_server_->OnSignallingDisconnected(); message_loop_.Run(); } @@ -80,6 +82,8 @@ TEST_F(LogToServerTest, SendLater) { TEST_F(LogToServerTest, SendTwoEntriesLater) { { InSequence s; + EXPECT_CALL(signal_strategy_, GetLocalJid()) + .WillRepeatedly(Return("host@domain.com/1234")); EXPECT_CALL(signal_strategy_, AddListener(_)); EXPECT_CALL(signal_strategy_, GetNextId()); EXPECT_CALL(signal_strategy_, SendStanza(_)) @@ -90,8 +94,7 @@ TEST_F(LogToServerTest, SendTwoEntriesLater) { } log_to_server_->OnClientAuthenticated("client@domain.com/5678"); log_to_server_->OnClientAuthenticated("client2@domain.com/6789"); - log_to_server_->OnSignallingConnected(&signal_strategy_, - "host@domain.com/1234"); + log_to_server_->OnSignallingConnected(&signal_strategy_); log_to_server_->OnSignallingDisconnected(); message_loop_.Run(); } diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc index aecca5d..9f3a559 100644 --- a/remoting/host/plugin/host_script_object.cc +++ b/remoting/host/plugin/host_script_object.cc @@ -337,8 +337,8 @@ bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { return true; } -void HostNPScriptObject::OnSignallingConnected(SignalStrategy* signal_strategy, - const std::string& full_jid) { +void HostNPScriptObject::OnSignallingConnected( + SignalStrategy* signal_strategy) { } void HostNPScriptObject::OnSignallingDisconnected() { diff --git a/remoting/host/plugin/host_script_object.h b/remoting/host/plugin/host_script_object.h index 88db11c..2e04370 100644 --- a/remoting/host/plugin/host_script_object.h +++ b/remoting/host/plugin/host_script_object.h @@ -68,8 +68,8 @@ class HostNPScriptObject : public HostStatusObserver { bool Enumerate(std::vector<std::string>* values); // remoting::HostStatusObserver implementation. - virtual void OnSignallingConnected(remoting::SignalStrategy* signal_strategy, - const std::string& full_jid) OVERRIDE; + virtual void OnSignallingConnected( + remoting::SignalStrategy* signal_strategy) OVERRIDE; virtual void OnSignallingDisconnected() OVERRIDE; virtual void OnAccessDenied() OVERRIDE; virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE; diff --git a/remoting/host/register_support_host_request.cc b/remoting/host/register_support_host_request.cc index 5974675..5668f27 100644 --- a/remoting/host/register_support_host_request.cc +++ b/remoting/host/register_support_host_request.cc @@ -53,15 +53,15 @@ bool RegisterSupportHostRequest::Init(HostConfig* config, } void RegisterSupportHostRequest::OnSignallingConnected( - SignalStrategy* signal_strategy, - const std::string& jid) { + SignalStrategy* signal_strategy) { DCHECK(!callback_.is_null()); message_loop_ = MessageLoop::current(); iq_sender_.reset(new IqSender(signal_strategy)); request_.reset(iq_sender_->SendIq( - buzz::STR_SET, kChromotingBotJid, CreateRegistrationRequest(jid), + buzz::STR_SET, kChromotingBotJid, + CreateRegistrationRequest(signal_strategy->GetLocalJid()), base::Bind(&RegisterSupportHostRequest::ProcessResponse, base::Unretained(this)))); } diff --git a/remoting/host/register_support_host_request.h b/remoting/host/register_support_host_request.h index 0297daba..84dab32 100644 --- a/remoting/host/register_support_host_request.h +++ b/remoting/host/register_support_host_request.h @@ -56,8 +56,7 @@ class RegisterSupportHostRequest : public HostStatusObserver { bool Init(HostConfig* config, const RegisterCallback& callback); // HostStatusObserver implementation. - virtual void OnSignallingConnected(SignalStrategy* signal_strategy, - const std::string& full_jid) OVERRIDE; + virtual void OnSignallingConnected(SignalStrategy* signal_strategy) OVERRIDE; virtual void OnSignallingDisconnected() OVERRIDE; virtual void OnClientAuthenticated(const std::string& jid) OVERRIDE; virtual void OnClientDisconnected(const std::string& jid) OVERRIDE; diff --git a/remoting/host/register_support_host_request_unittest.cc b/remoting/host/register_support_host_request_unittest.cc index c5b6261..dc3258d 100644 --- a/remoting/host/register_support_host_request_unittest.cc +++ b/remoting/host/register_support_host_request_unittest.cc @@ -76,10 +76,12 @@ TEST_F(RegisterSupportHostRequestTest, Send) { XmlElement* sent_iq = NULL; EXPECT_CALL(signal_strategy_, GetNextId()) .WillOnce(Return(kStanzaId)); + EXPECT_CALL(signal_strategy_, GetLocalJid()) + .WillRepeatedly(Return(kTestJid)); EXPECT_CALL(signal_strategy_, SendStanza(NotNull())) .WillOnce(DoAll(SaveArg<0>(&sent_iq), Return(true))); - request->OnSignallingConnected(&signal_strategy_, kTestJid); + request->OnSignallingConnected(&signal_strategy_); message_loop_.RunAllPending(); // Verify format of the query. @@ -134,7 +136,7 @@ TEST_F(RegisterSupportHostRequestTest, Send) { support_id_lifetime->AddText(kSupportIdLifetime); result->AddElement(support_id_lifetime); - EXPECT_TRUE(listener->OnIncomingStanza(response.get())); + EXPECT_TRUE(listener->OnSignalStrategyIncomingStanza(response.get())); message_loop_.RunAllPending(); EXPECT_CALL(signal_strategy_, RemoveListener(listener)); diff --git a/remoting/jingle_glue/fake_signal_strategy.cc b/remoting/jingle_glue/fake_signal_strategy.cc index 4cbfd23..657b0ad 100644 --- a/remoting/jingle_glue/fake_signal_strategy.cc +++ b/remoting/jingle_glue/fake_signal_strategy.cc @@ -34,33 +34,37 @@ FakeSignalStrategy::~FakeSignalStrategy() { delete pending_messages_.front(); pending_messages_.pop(); } - DCHECK(listeners_.empty()); } -void FakeSignalStrategy::Init(StatusObserver* observer) { - observer->OnStateChange(StatusObserver::START); - observer->OnStateChange(StatusObserver::CONNECTING); - observer->OnJidChange(jid_); - observer->OnStateChange(StatusObserver::CONNECTED); +void FakeSignalStrategy::Connect() { + DCHECK(CalledOnValidThread()); + FOR_EACH_OBSERVER(Listener, listeners_, + OnSignalStrategyStateChange(CONNECTED)); +} + +void FakeSignalStrategy::Disconnect() { + DCHECK(CalledOnValidThread()); + FOR_EACH_OBSERVER(Listener, listeners_, + OnSignalStrategyStateChange(DISCONNECTED)); +} + +SignalStrategy::State FakeSignalStrategy::GetState() const { + return CONNECTED; } -void FakeSignalStrategy::Close() { +std::string FakeSignalStrategy::GetLocalJid() const { DCHECK(CalledOnValidThread()); + return jid_; } void FakeSignalStrategy::AddListener(Listener* listener) { DCHECK(CalledOnValidThread()); - DCHECK(std::find(listeners_.begin(), listeners_.end(), listener) == - listeners_.end()); - listeners_.push_back(listener); + listeners_.AddObserver(listener); } void FakeSignalStrategy::RemoveListener(Listener* listener) { DCHECK(CalledOnValidThread()); - std::vector<Listener*>::iterator it = - std::find(listeners_.begin(), listeners_.end(), listener); - CHECK(it != listeners_.end()); - listeners_.erase(it); + listeners_.RemoveObserver(listener); } bool FakeSignalStrategy::SendStanza(buzz::XmlElement* stanza) { @@ -100,9 +104,10 @@ void FakeSignalStrategy::DeliverIncomingMessages() { return; } - for (std::vector<Listener*>::iterator it = listeners_.begin(); - it != listeners_.end(); ++it) { - if ((*it)->OnIncomingStanza(stanza)) + ObserverListBase<Listener>::Iterator it(listeners_); + Listener* listener; + while ((listener = it.GetNext()) != NULL) { + if (listener->OnSignalStrategyIncomingStanza(stanza)) break; } diff --git a/remoting/jingle_glue/fake_signal_strategy.h b/remoting/jingle_glue/fake_signal_strategy.h index e14931f..db9cd0a 100644 --- a/remoting/jingle_glue/fake_signal_strategy.h +++ b/remoting/jingle_glue/fake_signal_strategy.h @@ -8,6 +8,7 @@ #include <queue> #include <string> +#include "base/observer_list.h" #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" #include "remoting/jingle_glue/iq_sender.h" @@ -24,8 +25,10 @@ class FakeSignalStrategy : public SignalStrategy, virtual ~FakeSignalStrategy(); // SignalStrategy interface. - virtual void Init(StatusObserver* observer) OVERRIDE; - virtual void Close() OVERRIDE; + virtual void Connect() OVERRIDE; + virtual void Disconnect() OVERRIDE; + virtual State GetState() const OVERRIDE; + virtual std::string GetLocalJid() const OVERRIDE; virtual void AddListener(Listener* listener) OVERRIDE; virtual void RemoveListener(Listener* listener) OVERRIDE; virtual bool SendStanza(buzz::XmlElement* stanza) OVERRIDE; @@ -39,7 +42,7 @@ class FakeSignalStrategy : public SignalStrategy, std::string jid_; FakeSignalStrategy* peer_; - std::vector<Listener*> listeners_; + ObserverList<Listener, true> listeners_; int last_id_; diff --git a/remoting/jingle_glue/iq_sender.cc b/remoting/jingle_glue/iq_sender.cc index e0e1e5b..d22e0f8 100644 --- a/remoting/jingle_glue/iq_sender.cc +++ b/remoting/jingle_glue/iq_sender.cc @@ -66,7 +66,10 @@ void IqSender::RemoveRequest(IqRequest* request) { } } -bool IqSender::OnIncomingStanza(const buzz::XmlElement* stanza) { +void IqSender::OnSignalStrategyStateChange(SignalStrategy::State state) { +} + +bool IqSender::OnSignalStrategyIncomingStanza(const buzz::XmlElement* stanza) { if (stanza->Name() != buzz::QN_IQ) { LOG(WARNING) << "Received unexpected non-IQ packet " << stanza->Str(); return false; diff --git a/remoting/jingle_glue/iq_sender.h b/remoting/jingle_glue/iq_sender.h index 2696b80..68871a4 100644 --- a/remoting/jingle_glue/iq_sender.h +++ b/remoting/jingle_glue/iq_sender.h @@ -48,7 +48,10 @@ class IqSender : public SignalStrategy::Listener { const ReplyCallback& callback) WARN_UNUSED_RESULT; // SignalStrategy::Listener implementation. - virtual bool OnIncomingStanza(const buzz::XmlElement* stanza) OVERRIDE; + virtual void OnSignalStrategyStateChange( + SignalStrategy::State state) OVERRIDE; + virtual bool OnSignalStrategyIncomingStanza( + const buzz::XmlElement* stanza) OVERRIDE; private: typedef std::map<std::string, IqRequest*> IqRequestMap; diff --git a/remoting/jingle_glue/iq_sender_unittest.cc b/remoting/jingle_glue/iq_sender_unittest.cc index f9dc8af..70bd4ec 100644 --- a/remoting/jingle_glue/iq_sender_unittest.cc +++ b/remoting/jingle_glue/iq_sender_unittest.cc @@ -86,7 +86,7 @@ TEST_F(IqSenderTest, SendIq) { response->AddElement(result); EXPECT_CALL(callback_, OnReply(response.get())); - EXPECT_TRUE(sender_->OnIncomingStanza(response.get())); + EXPECT_TRUE(sender_->OnSignalStrategyIncomingStanza(response.get())); } } // namespace remoting diff --git a/remoting/jingle_glue/javascript_signal_strategy.cc b/remoting/jingle_glue/javascript_signal_strategy.cc index a26a385..15a5d89 100644 --- a/remoting/jingle_glue/javascript_signal_strategy.cc +++ b/remoting/jingle_glue/javascript_signal_strategy.cc @@ -13,59 +13,57 @@ namespace remoting { -JavascriptSignalStrategy::JavascriptSignalStrategy(const std::string& your_jid) - : your_jid_(your_jid), +JavascriptSignalStrategy::JavascriptSignalStrategy(const std::string& local_jid) + : local_jid_(local_jid), last_id_(0) { } JavascriptSignalStrategy::~JavascriptSignalStrategy() { - DCHECK(listeners_.empty()); - Close(); + DCHECK_EQ(listeners_.size(), 0U); + Disconnect(); } void JavascriptSignalStrategy::AttachXmppProxy( scoped_refptr<XmppProxy> xmpp_proxy) { DCHECK(CalledOnValidThread()); xmpp_proxy_ = xmpp_proxy; - xmpp_proxy_->AttachCallback(AsWeakPtr()); } -void JavascriptSignalStrategy::Init(StatusObserver* observer) { +void JavascriptSignalStrategy::Connect() { DCHECK(CalledOnValidThread()); - // Blast through each state since for a JavascriptSignalStrategy, we're - // already connected. - // - // TODO(ajwong): Clarify the status API contract to see if we have to actually - // walk through each state. - observer->OnStateChange(StatusObserver::START); - observer->OnStateChange(StatusObserver::CONNECTING); - observer->OnJidChange(your_jid_); - observer->OnStateChange(StatusObserver::CONNECTED); + xmpp_proxy_->AttachCallback(AsWeakPtr()); + FOR_EACH_OBSERVER(Listener, listeners_, + OnSignalStrategyStateChange(CONNECTED)); } -void JavascriptSignalStrategy::Close() { +void JavascriptSignalStrategy::Disconnect() { DCHECK(CalledOnValidThread()); - if (xmpp_proxy_) { + if (xmpp_proxy_) xmpp_proxy_->DetachCallback(); - xmpp_proxy_ = NULL; - } + FOR_EACH_OBSERVER(Listener, listeners_, + OnSignalStrategyStateChange(DISCONNECTED)); +} + +SignalStrategy::State JavascriptSignalStrategy::GetState() const { + // TODO(sergeyu): Extend XmppProxy to provide status of the + // connection. + return CONNECTED; +} + +std::string JavascriptSignalStrategy::GetLocalJid() const { + return local_jid_; } void JavascriptSignalStrategy::AddListener(Listener* listener) { DCHECK(CalledOnValidThread()); - DCHECK(std::find(listeners_.begin(), listeners_.end(), listener) == - listeners_.end()); - listeners_.push_back(listener); + listeners_.AddObserver(listener); } void JavascriptSignalStrategy::RemoveListener(Listener* listener) { DCHECK(CalledOnValidThread()); - std::vector<Listener*>::iterator it = - std::find(listeners_.begin(), listeners_.end(), listener); - CHECK(it != listeners_.end()); - listeners_.erase(it); + listeners_.RemoveObserver(listener); } bool JavascriptSignalStrategy::SendStanza(buzz::XmlElement* stanza) { @@ -89,9 +87,10 @@ void JavascriptSignalStrategy::OnIq(const std::string& stanza_str) { return; } - for (std::vector<Listener*>::iterator it = listeners_.begin(); - it != listeners_.end(); ++it) { - if ((*it)->OnIncomingStanza(stanza.get())) + ObserverListBase<Listener>::Iterator it(listeners_); + Listener* listener; + while ((listener = it.GetNext()) != NULL) { + if (listener->OnSignalStrategyIncomingStanza(stanza.get())) break; } } diff --git a/remoting/jingle_glue/javascript_signal_strategy.h b/remoting/jingle_glue/javascript_signal_strategy.h index 923dd27..69ae52d 100644 --- a/remoting/jingle_glue/javascript_signal_strategy.h +++ b/remoting/jingle_glue/javascript_signal_strategy.h @@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" #include "base/threading/non_thread_safe.h" #include "remoting/jingle_glue/xmpp_proxy.h" @@ -23,14 +24,16 @@ class JavascriptSignalStrategy : public SignalStrategy, public XmppProxy::ResponseCallback, public base::NonThreadSafe { public: - explicit JavascriptSignalStrategy(const std::string& your_jid); + explicit JavascriptSignalStrategy(const std::string& local_jid); virtual ~JavascriptSignalStrategy(); void AttachXmppProxy(scoped_refptr<XmppProxy> xmpp_proxy); // SignalStrategy interface. - virtual void Init(StatusObserver* observer) OVERRIDE; - virtual void Close() OVERRIDE; + virtual void Connect() OVERRIDE; + virtual void Disconnect() OVERRIDE; + virtual State GetState() const OVERRIDE; + virtual std::string GetLocalJid() const OVERRIDE; virtual void AddListener(Listener* listener) OVERRIDE; virtual void RemoveListener(Listener* listener) OVERRIDE; virtual bool SendStanza(buzz::XmlElement* stanza) OVERRIDE; @@ -40,10 +43,10 @@ class JavascriptSignalStrategy : public SignalStrategy, virtual void OnIq(const std::string& stanza) OVERRIDE; private: - std::string your_jid_; + std::string local_jid_; scoped_refptr<XmppProxy> xmpp_proxy_; - std::vector<Listener*> listeners_; + ObserverList<Listener> listeners_; int last_id_; diff --git a/remoting/jingle_glue/jingle_signaling_connector.cc b/remoting/jingle_glue/jingle_signaling_connector.cc index 2cfe3da..913633a 100644 --- a/remoting/jingle_glue/jingle_signaling_connector.cc +++ b/remoting/jingle_glue/jingle_signaling_connector.cc @@ -48,7 +48,11 @@ JingleSignalingConnector::~JingleSignalingConnector() { pending_requests_.end()); } -bool JingleSignalingConnector::OnIncomingStanza( +void JingleSignalingConnector::OnSignalStrategyStateChange( + SignalStrategy::State state) { +} + +bool JingleSignalingConnector::OnSignalStrategyIncomingStanza( const buzz::XmlElement* stanza) { if (session_manager_->IsSessionMessage(stanza)) { session_manager_->OnIncomingMessage(stanza); diff --git a/remoting/jingle_glue/jingle_signaling_connector.h b/remoting/jingle_glue/jingle_signaling_connector.h index 2aa41bc..f26fb32 100644 --- a/remoting/jingle_glue/jingle_signaling_connector.h +++ b/remoting/jingle_glue/jingle_signaling_connector.h @@ -41,7 +41,10 @@ class JingleSignalingConnector : public SignalStrategy::Listener, virtual ~JingleSignalingConnector(); // SignalStrategy::Listener interface. - virtual bool OnIncomingStanza(const buzz::XmlElement* stanza) OVERRIDE; + virtual void OnSignalStrategyStateChange( + SignalStrategy::State state) OVERRIDE; + virtual bool OnSignalStrategyIncomingStanza( + const buzz::XmlElement* stanza) OVERRIDE; private: typedef std::map<std::string, buzz::XmlElement*> IqRequestsMap; diff --git a/remoting/jingle_glue/mock_objects.h b/remoting/jingle_glue/mock_objects.h index aad9697..61bc2d3 100644 --- a/remoting/jingle_glue/mock_objects.h +++ b/remoting/jingle_glue/mock_objects.h @@ -14,13 +14,14 @@ class MockSignalStrategy : public SignalStrategy { MockSignalStrategy(); virtual ~MockSignalStrategy(); - MOCK_METHOD1(Init, void(StatusObserver*)); - MOCK_METHOD0(Close, void()); + MOCK_METHOD0(Connect, void()); + MOCK_METHOD0(Disconnect, void()); + MOCK_CONST_METHOD0(GetState, State()); + MOCK_CONST_METHOD0(GetLocalJid, std::string()); MOCK_METHOD1(AddListener, void(Listener* listener)); MOCK_METHOD1(RemoveListener, void(Listener* listener)); MOCK_METHOD1(SendStanza, bool(buzz::XmlElement* stanza)); MOCK_METHOD0(GetNextId, std::string()); - MOCK_METHOD0(CreateIqRequest, IqRequest*()); }; } // namespace remoting diff --git a/remoting/jingle_glue/signal_strategy.h b/remoting/jingle_glue/signal_strategy.h index c4bfabe..a71e3c7 100644 --- a/remoting/jingle_glue/signal_strategy.h +++ b/remoting/jingle_glue/signal_strategy.h @@ -17,33 +17,55 @@ namespace remoting { class SignalStrategy { public: - 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; + enum State { + // Connection is being established. + CONNECTING, + + // Signalling is connected. + CONNECTED, + + // Connection is closed due to an error or because Disconnect() + // was called. + DISCONNECTED, }; + // Callback interface for signaling event. Event handlers are not + // allowed to destroy SignalStrategy, but may add or remove other + // listeners. class Listener { public: + virtual ~Listener() {} + + // Called after state of the connection has changed. + virtual void OnSignalStrategyStateChange(State state) {} + // Must return true if the stanza was handled, false otherwise. - virtual bool OnIncomingStanza(const buzz::XmlElement* stanza) = 0; + virtual bool OnSignalStrategyIncomingStanza( + const buzz::XmlElement* stanza) { return false; } }; SignalStrategy() {} virtual ~SignalStrategy() {} - virtual void Init(StatusObserver* observer) = 0; - virtual void Close() = 0; + + // Starts connection attempt. If connection is currently active + // disconnects it and opens a new connection (implicit disconnect + // triggers CLOSED notification). Connection is finished + // asynchronously. + virtual void Connect() = 0; + + // Disconnects current connection if connected. Triggers CLOSED + // notification. + virtual void Disconnect() = 0; + + // Returns current state. + virtual State GetState() const = 0; + + // Returns local JID or an empty string when not connected. + virtual std::string GetLocalJid() const = 0; // Add a |listener| that can listen to all incoming - // messages. Doesn't take ownership of the |listener|. + // messages. Doesn't take ownership of the |listener|. All listeners + // must be removed before this object is destroyed. virtual void AddListener(Listener* listener) = 0; // Remove a |listener| previously added with AddListener(). diff --git a/remoting/jingle_glue/xmpp_signal_strategy.cc b/remoting/jingle_glue/xmpp_signal_strategy.cc index 26ea9ca..f367b65 100644 --- a/remoting/jingle_glue/xmpp_signal_strategy.cc +++ b/remoting/jingle_glue/xmpp_signal_strategy.cc @@ -23,20 +23,20 @@ XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread, auth_token_(auth_token), auth_token_service_(auth_token_service), xmpp_client_(NULL), - observer_(NULL) { + state_(DISCONNECTED) { } XmppSignalStrategy::~XmppSignalStrategy() { - DCHECK(listeners_.empty()); - Close(); + DCHECK_EQ(listeners_.size(), 0U); + Disconnect(); } -void XmppSignalStrategy::Init(StatusObserver* observer) { - observer_ = observer; - - buzz::Jid login_jid(username_); +void XmppSignalStrategy::Connect() { + // Disconnect first if we are currently connected. + Disconnect(); buzz::XmppClientSettings settings; + buzz::Jid login_jid(username_); settings.set_user(login_jid.node()); settings.set_host(login_jid.domain()); settings.set_resource("chromoting"); @@ -55,7 +55,7 @@ void XmppSignalStrategy::Init(StatusObserver* observer) { xmpp_client_->Start(); } -void XmppSignalStrategy::Close() { +void XmppSignalStrategy::Disconnect() { if (xmpp_client_) { xmpp_client_->engine()->RemoveStanzaHandler(this); @@ -67,17 +67,20 @@ void XmppSignalStrategy::Close() { } } +SignalStrategy::State XmppSignalStrategy::GetState() const { + return state_; +} + +std::string XmppSignalStrategy::GetLocalJid() const { + return xmpp_client_->jid().Str(); +} + void XmppSignalStrategy::AddListener(Listener* listener) { - DCHECK(std::find(listeners_.begin(), listeners_.end(), listener) == - listeners_.end()); - listeners_.push_back(listener); + listeners_.AddObserver(listener); } void XmppSignalStrategy::RemoveListener(Listener* listener) { - std::vector<Listener*>::iterator it = - std::find(listeners_.begin(), listeners_.end(), listener); - CHECK(it != listeners_.end()); - listeners_.erase(it); + listeners_.RemoveObserver(listener); } bool XmppSignalStrategy::SendStanza(buzz::XmlElement* stanza) { @@ -102,36 +105,44 @@ std::string XmppSignalStrategy::GetNextId() { } bool XmppSignalStrategy::HandleStanza(const buzz::XmlElement* stanza) { - for (std::vector<Listener*>::iterator it = listeners_.begin(); - it != listeners_.end(); ++it) { - if ((*it)->OnIncomingStanza(stanza)) - return true; + ObserverListBase<Listener>::Iterator it(listeners_); + Listener* listener; + while ((listener = it.GetNext()) != NULL) { + if (listener->OnSignalStrategyIncomingStanza(stanza)) + break; } return false; } void XmppSignalStrategy::OnConnectionStateChanged( buzz::XmppEngine::State state) { + State new_state; + switch (state) { case buzz::XmppEngine::STATE_START: - observer_->OnStateChange(StatusObserver::START); - break; + return; + case buzz::XmppEngine::STATE_OPENING: - observer_->OnStateChange(StatusObserver::CONNECTING); + new_state = CONNECTING; break; case buzz::XmppEngine::STATE_OPEN: - observer_->OnJidChange(xmpp_client_->jid().Str()); - observer_->OnStateChange(StatusObserver::CONNECTED); + new_state = 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; + new_state = DISCONNECTED; break; default: NOTREACHED(); - break; + return; + } + + if (state_ != new_state) { + state_ = new_state; + FOR_EACH_OBSERVER(Listener, listeners_, + OnSignalStrategyStateChange(new_state)); } } @@ -145,10 +156,7 @@ buzz::PreXmppAuth* XmppSignalStrategy::CreatePreXmppAuth( } return new notifier::GaiaTokenPreXmppAuth( - jid.Str(), - settings.auth_cookie(), - settings.token_service(), - mechanism); + jid.Str(), settings.auth_cookie(), settings.token_service(), mechanism); } } // namespace remoting diff --git a/remoting/jingle_glue/xmpp_signal_strategy.h b/remoting/jingle_glue/xmpp_signal_strategy.h index 81426fe..8695c90 100644 --- a/remoting/jingle_glue/xmpp_signal_strategy.h +++ b/remoting/jingle_glue/xmpp_signal_strategy.h @@ -15,6 +15,7 @@ #include <vector> #include "base/compiler_specific.h" +#include "base/observer_list.h" #include "third_party/libjingle/source/talk/base/sigslot.h" #include "third_party/libjingle/source/talk/xmpp/xmppclient.h" @@ -33,8 +34,10 @@ class XmppSignalStrategy : public SignalStrategy, virtual ~XmppSignalStrategy(); // SignalStrategy interface. - virtual void Init(StatusObserver* observer) OVERRIDE; - virtual void Close() OVERRIDE; + virtual void Connect() OVERRIDE; + virtual void Disconnect() OVERRIDE; + virtual State GetState() const OVERRIDE; + virtual std::string GetLocalJid() const OVERRIDE; virtual void AddListener(Listener* listener) OVERRIDE; virtual void RemoveListener(Listener* listener) OVERRIDE; virtual bool SendStanza(buzz::XmlElement* stanza) OVERRIDE; @@ -55,9 +58,9 @@ class XmppSignalStrategy : public SignalStrategy, std::string auth_token_service_; buzz::XmppClient* xmpp_client_; - StatusObserver* observer_; - std::vector<Listener*> listeners_; + State state_; + ObserverList<Listener> listeners_; DISALLOW_COPY_AND_ASSIGN(XmppSignalStrategy); }; diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc index 2f70af4..92f77bf 100644 --- a/remoting/protocol/connection_to_host.cc +++ b/remoting/protocol/connection_to_host.cc @@ -71,7 +71,11 @@ void ConnectionToHost::Connect(scoped_refptr<XmppProxy> xmpp_proxy, JavascriptSignalStrategy* strategy = new JavascriptSignalStrategy(your_jid); strategy->AttachXmppProxy(xmpp_proxy); signal_strategy_.reset(strategy); - signal_strategy_->Init(this); + signal_strategy_->AddListener(this); + signal_strategy_->Connect(); + + session_manager_.reset(new PepperSessionManager(pp_instance_)); + session_manager_->Init(signal_strategy_.get(), this, allow_nat_traversal_); } void ConnectionToHost::Disconnect(const base::Closure& shutdown_task) { @@ -90,51 +94,39 @@ void ConnectionToHost::Disconnect(const base::Closure& shutdown_task) { if (session_manager_.get()) session_manager_.reset(); - if (signal_strategy_.get()) + if (signal_strategy_.get()) { + signal_strategy_->RemoveListener(this); signal_strategy_.reset(); + } shutdown_task.Run(); } -void ConnectionToHost::InitSession() { - DCHECK(message_loop_->BelongsToCurrentThread()); - - session_manager_.reset(new PepperSessionManager(pp_instance_)); - session_manager_->Init( - local_jid_, signal_strategy_.get(), this, allow_nat_traversal_); -} - const SessionConfig& ConnectionToHost::config() { return session_->config(); } -void ConnectionToHost::OnStateChange( - SignalStrategy::StatusObserver::State state) { +void ConnectionToHost::OnSignalStrategyStateChange( + SignalStrategy::State state) { DCHECK(message_loop_->BelongsToCurrentThread()); DCHECK(event_callback_); - if (state == SignalStrategy::StatusObserver::CONNECTED) { - VLOG(1) << "Connected as: " << local_jid_; - InitSession(); - } else if (state == SignalStrategy::StatusObserver::CLOSED) { + if (state == SignalStrategy::CONNECTED) { + VLOG(1) << "Connected as: " << signal_strategy_->GetLocalJid(); + } else if (state == SignalStrategy::DISCONNECTED) { VLOG(1) << "Connection closed."; CloseOnError(NETWORK_FAILURE); } } -void ConnectionToHost::OnJidChange(const std::string& full_jid) { - DCHECK(message_loop_->BelongsToCurrentThread()); - local_jid_ = full_jid; -} - -void ConnectionToHost::OnSessionManagerInitialized() { +void ConnectionToHost::OnSessionManagerReady() { DCHECK(message_loop_->BelongsToCurrentThread()); // After SessionManager is initialized we can try to connect to the host. CandidateSessionConfig* candidate_config = CandidateSessionConfig::CreateDefault(); V1ClientAuthenticator* authenticator = - new V1ClientAuthenticator(local_jid_, access_code_); + new V1ClientAuthenticator(signal_strategy_->GetLocalJid(), access_code_); session_.reset(session_manager_->Connect( host_jid_, authenticator, candidate_config, base::Bind(&ConnectionToHost::OnSessionStateChange, diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h index bba17fd..86bd005 100644 --- a/remoting/protocol/connection_to_host.h +++ b/remoting/protocol/connection_to_host.h @@ -40,7 +40,7 @@ class SessionConfig; class VideoReader; class VideoStub; -class ConnectionToHost : public SignalStrategy::StatusObserver, +class ConnectionToHost : public SignalStrategy::Listener, public SessionManager::Listener { public: enum State { @@ -89,12 +89,11 @@ class ConnectionToHost : public SignalStrategy::StatusObserver, virtual HostStub* host_stub(); // SignalStrategy::StatusObserver interface. - virtual void OnStateChange( - SignalStrategy::StatusObserver::State state) OVERRIDE; - virtual void OnJidChange(const std::string& full_jid) OVERRIDE; + virtual void OnSignalStrategyStateChange( + SignalStrategy::State state) OVERRIDE; // SessionManager::Listener interface. - virtual void OnSessionManagerInitialized() OVERRIDE; + virtual void OnSessionManagerReady() OVERRIDE; virtual void OnIncomingSession( Session* session, SessionManager::IncomingSessionResponse* response) OVERRIDE; @@ -106,10 +105,6 @@ class ConnectionToHost : public SignalStrategy::StatusObserver, State state() const; private: - // Called on the jingle thread after we've successfully to XMPP server. Starts - // P2P connection to the host. - void InitSession(); - // Callback for |session_|. void OnSessionStateChange(Session::State state); @@ -143,7 +138,6 @@ class ConnectionToHost : public SignalStrategy::StatusObserver, VideoStub* video_stub_; scoped_ptr<SignalStrategy> signal_strategy_; - std::string local_jid_; scoped_ptr<SessionManager> session_manager_; scoped_ptr<Session> session_; diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc index 96c95b1..6a94a44 100644 --- a/remoting/protocol/jingle_session_manager.cc +++ b/remoting/protocol/jingle_session_manager.cc @@ -33,6 +33,7 @@ JingleSessionManager::JingleSessionManager( : message_loop_(message_loop), signal_strategy_(NULL), allow_nat_traversal_(false), + ready_(false), http_port_allocator_(NULL), closed_(false), ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { @@ -45,20 +46,20 @@ JingleSessionManager::~JingleSessionManager() { } void JingleSessionManager::Init( - const std::string& local_jid, SignalStrategy* signal_strategy, - Listener* listener, + SessionManager::Listener* listener, bool allow_nat_traversal) { DCHECK(CalledOnValidThread()); DCHECK(signal_strategy); DCHECK(listener); - local_jid_ = local_jid; signal_strategy_ = signal_strategy; listener_ = listener; allow_nat_traversal_ = allow_nat_traversal; + signal_strategy_->AddListener(this); + if (!network_manager_.get()) { VLOG(1) << "Creating talk_base::NetworkManager."; network_manager_.reset(new talk_base::BasicNetworkManager()); @@ -97,14 +98,7 @@ void JingleSessionManager::Init( jingle_signaling_connector_.reset(new JingleSignalingConnector( signal_strategy_, cricket_session_manager_.get())); - // If NAT traversal is enabled then we need to request STUN/Relay info. - if (allow_nat_traversal) { - jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_)); - jingle_info_request_->Send(base::Bind( - &JingleSessionManager::OnJingleInfo, base::Unretained(this))); - } else { - listener_->OnSessionManagerInitialized(); - } + OnSignalStrategyStateChange(signal_strategy_->GetState()); } void JingleSessionManager::Close() { @@ -114,6 +108,7 @@ void JingleSessionManager::Close() { jingle_info_request_.reset(); cricket_session_manager_->RemoveClient(kChromotingXmlNamespace); jingle_signaling_connector_.reset(); + signal_strategy_->RemoveListener(this); closed_ = true; } } @@ -132,7 +127,7 @@ Session* JingleSessionManager::Connect( DCHECK(CalledOnValidThread()); cricket::Session* cricket_session = cricket_session_manager_->CreateSession( - local_jid_, kChromotingXmlNamespace); + signal_strategy_->GetLocalJid(), kChromotingXmlNamespace); cricket_session->set_remote_name(host_jid); JingleSession* jingle_session = @@ -172,6 +167,21 @@ void JingleSessionManager::OnSessionDestroy(cricket::Session* cricket_session) { } } +void JingleSessionManager::OnSignalStrategyStateChange( + SignalStrategy::State state) { + if (state == SignalStrategy::CONNECTED) { + // If NAT traversal is enabled then we need to request STUN/Relay info. + if (allow_nat_traversal_) { + jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_)); + jingle_info_request_->Send(base::Bind( + &JingleSessionManager::OnJingleInfo, base::Unretained(this))); + } else if (!ready_) { + ready_ = true; + listener_->OnSessionManagerReady(); + } + } +} + SessionManager::IncomingSessionResponse JingleSessionManager::AcceptConnection( JingleSession* jingle_session) { DCHECK(CalledOnValidThread()); @@ -225,7 +235,10 @@ void JingleSessionManager::OnJingleInfo( LOG(WARNING) << "Jingle info found but no port allocator."; } - listener_->OnSessionManagerInitialized(); + if (!ready_) { + ready_ = true; + listener_->OnSessionManagerReady(); + } } // Parse content description generated by WriteContent(). diff --git a/remoting/protocol/jingle_session_manager.h b/remoting/protocol/jingle_session_manager.h index a72d9a3..63f17b2 100644 --- a/remoting/protocol/jingle_session_manager.h +++ b/remoting/protocol/jingle_session_manager.h @@ -9,6 +9,7 @@ #include <string> #include "base/memory/ref_counted.h" +#include "remoting/jingle_glue/signal_strategy.h" #include "remoting/protocol/content_description.h" #include "remoting/protocol/jingle_session.h" #include "remoting/protocol/session_manager.h" @@ -31,18 +32,17 @@ namespace protocol { // This class implements SessionClient for Chromoting sessions. It acts as a // server that accepts chromoting connections and can also make new connections // to other hosts. -class JingleSessionManager - : public SessionManager, - public cricket::SessionClient { +class JingleSessionManager : public SessionManager, + public cricket::SessionClient, + public SignalStrategy::Listener { public: virtual ~JingleSessionManager(); JingleSessionManager(base::MessageLoopProxy* message_loop); // SessionManager interface. - virtual void Init(const std::string& local_jid, - SignalStrategy* signal_strategy, - Listener* listener, + virtual void Init(SignalStrategy* signal_strategy, + SessionManager::Listener* listener, bool allow_nat_traversal) OVERRIDE; virtual Session* Connect( const std::string& host_jid, @@ -67,6 +67,10 @@ class JingleSessionManager buzz::XmlElement** elem, cricket::WriteError* error) OVERRIDE; + // SignalStrategy::Listener interface. + virtual void OnSignalStrategyStateChange( + SignalStrategy::State state) OVERRIDE; + private: friend class JingleSession; @@ -95,12 +99,13 @@ class JingleSessionManager scoped_ptr<talk_base::NetworkManager> network_manager_; scoped_ptr<talk_base::PacketSocketFactory> socket_factory_; - std::string local_jid_; // Full jid for the local side of the session. SignalStrategy* signal_strategy_; scoped_ptr<AuthenticatorFactory> authenticator_factory_; - Listener* listener_; + SessionManager::Listener* listener_; bool allow_nat_traversal_; + bool ready_; + scoped_ptr<cricket::PortAllocator> port_allocator_; cricket::HttpPortAllocator* http_port_allocator_; scoped_ptr<cricket::SessionManager> cricket_session_manager_; diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc index e2bf2d1..d7f2149 100644 --- a/remoting/protocol/jingle_session_unittest.cc +++ b/remoting/protocol/jingle_session_unittest.cc @@ -64,7 +64,7 @@ ACTION_P(QuitThreadOnCounter, counter) { class MockSessionManagerListener : public SessionManager::Listener { public: - MOCK_METHOD0(OnSessionManagerInitialized, void()); + MOCK_METHOD0(OnSessionManagerReady, void()); MOCK_METHOD2(OnIncomingSession, void(Session*, SessionManager::IncomingSessionResponse*)); @@ -127,23 +127,22 @@ class JingleSessionTest : public testing::Test { FakeSignalStrategy::Connect(host_signal_strategy_.get(), client_signal_strategy_.get()); - EXPECT_CALL(host_server_listener_, OnSessionManagerInitialized()) + EXPECT_CALL(host_server_listener_, OnSessionManagerReady()) .Times(1); host_server_.reset(new JingleSessionManager( base::MessageLoopProxy::current())); host_server_->Init( - kHostJid, host_signal_strategy_.get(), &host_server_listener_, false); + host_signal_strategy_.get(), &host_server_listener_, false); host_server_->set_authenticator_factory( new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true)); - EXPECT_CALL(client_server_listener_, OnSessionManagerInitialized()) + EXPECT_CALL(client_server_listener_, OnSessionManagerReady()) .Times(1); client_server_.reset(new JingleSessionManager( base::MessageLoopProxy::current())); client_server_->Init( - kClientJid, client_signal_strategy_.get(), - &client_server_listener_, false); + client_signal_strategy_.get(), &client_server_listener_, false); } void CloseSessionManager() { diff --git a/remoting/protocol/pepper_session.cc b/remoting/protocol/pepper_session.cc index 0cdfdd9..7cf0139 100644 --- a/remoting/protocol/pepper_session.cc +++ b/remoting/protocol/pepper_session.cc @@ -77,7 +77,7 @@ void PepperSession::StartConnection( // Send session-initiate message. JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, session_id_); - message.from = session_manager_->local_jid_; + message.from = session_manager_->signal_strategy_->GetLocalJid(); message.description.reset( new ContentDescription(candidate_config_->Clone(), authenticator_->GetNextMessage())); diff --git a/remoting/protocol/pepper_session_manager.cc b/remoting/protocol/pepper_session_manager.cc index 9317fbb..3492cd3 100644 --- a/remoting/protocol/pepper_session_manager.cc +++ b/remoting/protocol/pepper_session_manager.cc @@ -23,7 +23,8 @@ PepperSessionManager::PepperSessionManager(pp::Instance* pp_instance) : pp_instance_(pp_instance), signal_strategy_(NULL), listener_(NULL), - allow_nat_traversal_(false) { + allow_nat_traversal_(false), + ready_(false) { } PepperSessionManager::~PepperSessionManager() { @@ -31,26 +32,17 @@ PepperSessionManager::~PepperSessionManager() { } void PepperSessionManager::Init( - const std::string& local_jid, SignalStrategy* signal_strategy, SessionManager::Listener* listener, bool allow_nat_traversal) { listener_ = listener; - local_jid_ = local_jid; signal_strategy_ = signal_strategy; iq_sender_.reset(new IqSender(signal_strategy_)); allow_nat_traversal_ = allow_nat_traversal; signal_strategy_->AddListener(this); - // If NAT traversal is enabled then we need to request STUN/Relay info. - if (allow_nat_traversal) { - jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_)); - jingle_info_request_->Send(base::Bind(&PepperSessionManager::OnJingleInfo, - base::Unretained(this))); - } else { - listener_->OnSessionManagerInitialized(); - } + OnSignalStrategyStateChange(signal_strategy_->GetState()); } void PepperSessionManager::OnJingleInfo( @@ -68,7 +60,10 @@ void PepperSessionManager::OnJingleInfo( << " Relay server: " << transport_config_.relay_server << " Relay token: " << transport_config_.relay_token; - listener_->OnSessionManagerInitialized(); + if (!ready_) { + ready_ = true; + listener_->OnSessionManagerReady(); + } } Session* PepperSessionManager::Connect( @@ -104,7 +99,23 @@ void PepperSessionManager::set_authenticator_factory( authenticator_factory_.reset(authenticator_factory); } -bool PepperSessionManager::OnIncomingStanza(const buzz::XmlElement* stanza) { +void PepperSessionManager::OnSignalStrategyStateChange( + SignalStrategy::State state) { + // If NAT traversal is enabled then we need to request STUN/Relay info. + if (state == SignalStrategy::CONNECTED) { + if (allow_nat_traversal_) { + jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_)); + jingle_info_request_->Send(base::Bind(&PepperSessionManager::OnJingleInfo, + base::Unretained(this))); + } else if (!ready_) { + ready_ = true; + listener_->OnSessionManagerReady(); + } + } +} + +bool PepperSessionManager::OnSignalStrategyIncomingStanza( + const buzz::XmlElement* stanza) { if (!JingleMessage::IsJingleMessage(stanza)) return false; diff --git a/remoting/protocol/pepper_session_manager.h b/remoting/protocol/pepper_session_manager.h index 3ae1823..54369bd 100644 --- a/remoting/protocol/pepper_session_manager.h +++ b/remoting/protocol/pepper_session_manager.h @@ -48,8 +48,7 @@ class PepperSessionManager : public SessionManager, virtual ~PepperSessionManager(); // SessionManager interface. - virtual void Init(const std::string& local_jid, - SignalStrategy* signal_strategy, + virtual void Init(SignalStrategy* signal_strategy, SessionManager::Listener* listener, bool allow_nat_traversal) OVERRIDE; virtual Session* Connect( @@ -62,7 +61,10 @@ class PepperSessionManager : public SessionManager, AuthenticatorFactory* authenticator_factory) OVERRIDE; // SignalStrategy::Listener interface. - virtual bool OnIncomingStanza(const buzz::XmlElement* stanza) OVERRIDE; + virtual void OnSignalStrategyStateChange( + SignalStrategy::State state) OVERRIDE; + virtual bool OnSignalStrategyIncomingStanza( + const buzz::XmlElement* stanza) OVERRIDE; private: friend class PepperSession; @@ -83,13 +85,14 @@ class PepperSessionManager : public SessionManager, pp::Instance* pp_instance_; - std::string local_jid_; SignalStrategy* signal_strategy_; scoped_ptr<AuthenticatorFactory> authenticator_factory_; scoped_ptr<IqSender> iq_sender_; SessionManager::Listener* listener_; bool allow_nat_traversal_; + bool ready_; + TransportConfig transport_config_; scoped_ptr<JingleInfoRequest> jingle_info_request_; diff --git a/remoting/protocol/pepper_session_unittest.cc b/remoting/protocol/pepper_session_unittest.cc index a6cc271..b7c9b2b 100644 --- a/remoting/protocol/pepper_session_unittest.cc +++ b/remoting/protocol/pepper_session_unittest.cc @@ -43,7 +43,7 @@ const char kClientJid[] = "host2@gmail.com/321"; class MockSessionManagerListener : public SessionManager::Listener { public: - MOCK_METHOD0(OnSessionManagerInitialized, void()); + MOCK_METHOD0(OnSessionManagerReady, void()); MOCK_METHOD2(OnIncomingSession, void(Session*, SessionManager::IncomingSessionResponse*)); @@ -94,22 +94,21 @@ class PepperSessionTest : public testing::Test { FakeSignalStrategy::Connect(host_signal_strategy_.get(), client_signal_strategy_.get()); - EXPECT_CALL(host_server_listener_, OnSessionManagerInitialized()) + EXPECT_CALL(host_server_listener_, OnSessionManagerReady()) .Times(1); host_server_.reset(new JingleSessionManager( base::MessageLoopProxy::current())); host_server_->Init( - kHostJid, host_signal_strategy_.get(), &host_server_listener_, false); + host_signal_strategy_.get(), &host_server_listener_, false); host_server_->set_authenticator_factory( new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true)); - EXPECT_CALL(client_server_listener_, OnSessionManagerInitialized()) + EXPECT_CALL(client_server_listener_, OnSessionManagerReady()) .Times(1); client_server_.reset(new PepperSessionManager(NULL)); client_server_->Init( - kClientJid, client_signal_strategy_.get(), - &client_server_listener_, false); + client_signal_strategy_.get(), &client_server_listener_, false); } void CloseSessionManager() { diff --git a/remoting/protocol/session_manager.h b/remoting/protocol/session_manager.h index ad484fa..bee08cc 100644 --- a/remoting/protocol/session_manager.h +++ b/remoting/protocol/session_manager.h @@ -89,11 +89,10 @@ class SessionManager : public base::NonThreadSafe { Listener() { } ~Listener() { } - // Called when the session manager has finished - // initialization. May be called from Init() or after Init() - // returns. Outgoing connections can be created after this method - // is called. - virtual void OnSessionManagerInitialized() = 0; + // Called when the session manager is ready to create outgoing + // sessions. May be called from Init() or after Init() + // returns. + virtual void OnSessionManagerReady() = 0; // Called when a new session is received. If the host decides to // accept the session it should set the |response| to @@ -117,8 +116,7 @@ class SessionManager : public base::NonThreadSafe { // will also take ownership of these objects. On the client side // pass in NULL for |private_key| and empty string for // |certificate|. - virtual void Init(const std::string& local_jid, - SignalStrategy* signal_strategy, + virtual void Init(SignalStrategy* signal_strategy, Listener* listener, bool allow_nat_traversal) = 0; |