diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-20 20:54:47 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-20 20:54:47 +0000 |
commit | 970fb675f98ba3f0a243d1f9f0e9ab8b15f7ac45 (patch) | |
tree | b61657e7ada88ee55f40870338c045ae91289afc /remoting | |
parent | ef3b6f3ef05e7dec8dab10c82e3cdc44e60c9fc4 (diff) | |
download | chromium_src-970fb675f98ba3f0a243d1f9f0e9ab8b15f7ac45.zip chromium_src-970fb675f98ba3f0a243d1f9f0e9ab8b15f7ac45.tar.gz chromium_src-970fb675f98ba3f0a243d1f9f0e9ab8b15f7ac45.tar.bz2 |
Cleanups in the host shutdown logic and some minor fixes.
- replaced me2mom with it2me,
- Remove refcounting in HostStatusObserver,
- Cleanup shutdown logic in ChromotingHost,
- Cleanup shutdown logic in host plugin, particularly it now uses main host thread instead of the plugin thread to start/stop the host.
BUG=None
TEST=Don't crash when closing a tab.
Review URL: http://codereview.chromium.org/7182005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89728 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/host/chromoting_host.cc | 184 | ||||
-rw-r--r-- | remoting/host/chromoting_host.h | 44 | ||||
-rw-r--r-- | remoting/host/chromoting_host_unittest.cc | 38 | ||||
-rw-r--r-- | remoting/host/disconnect_window_linux.cc | 2 | ||||
-rw-r--r-- | remoting/host/disconnect_window_mac.mm | 2 | ||||
-rw-r--r-- | remoting/host/disconnect_window_win.cc | 2 | ||||
-rw-r--r-- | remoting/host/heartbeat_sender_unittest.cc | 6 | ||||
-rw-r--r-- | remoting/host/host_plugin.cc | 323 | ||||
-rw-r--r-- | remoting/host/host_status_observer.h | 10 | ||||
-rw-r--r-- | remoting/host/register_support_host_request_unittest.cc | 2 | ||||
-rw-r--r-- | remoting/host/simple_host_process.cc | 50 | ||||
-rw-r--r-- | remoting/host/support_access_verifier.cc | 13 | ||||
-rw-r--r-- | remoting/host/support_access_verifier.h | 4 |
13 files changed, 383 insertions, 297 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 1b2a488..67b4552 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -4,6 +4,8 @@ #include "remoting/host/chromoting_host.h" +#include "base/bind.h" +#include "base/callback.h" #include "build/build_config.h" #include "remoting/base/constants.h" #include "remoting/base/encoder.h" @@ -74,23 +76,21 @@ ChromotingHost::ChromotingHost(ChromotingHostContext* context, protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), is_curtained_(false), is_monitoring_local_inputs_(false), - is_me2mom_(false) { + is_it2me_(false) { DCHECK(desktop_environment_.get()); } ChromotingHost::~ChromotingHost() { } -void ChromotingHost::Start(Task* shutdown_task) { +void ChromotingHost::Start() { if (MessageLoop::current() != context_->main_message_loop()) { context_->main_message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &ChromotingHost::Start, shutdown_task)); + FROM_HERE, base::Bind(&ChromotingHost::Start, this)); return; } DCHECK(!jingle_client_); - DCHECK(shutdown_task); DCHECK(access_verifier_.get()); // Make sure this object is not started. @@ -101,9 +101,6 @@ void ChromotingHost::Start(Task* shutdown_task) { state_ = kStarted; } - // Save the shutdown task. - shutdown_task_.reset(shutdown_task); - std::string xmpp_login; std::string xmpp_auth_token; std::string xmpp_auth_service; @@ -126,22 +123,28 @@ void ChromotingHost::Start(Task* shutdown_task) { } // This method is called when we need to destroy the host process. -void ChromotingHost::Shutdown() { +void ChromotingHost::Shutdown(Task* shutdown_task) { if (MessageLoop::current() != context_->main_message_loop()) { context_->main_message_loop()->PostTask( FROM_HERE, - NewRunnableMethod(this, &ChromotingHost::Shutdown)); + base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); return; } // No-op if this object is not started yet. { base::AutoLock auto_lock(lock_); - if (state_ != kStarted) { + if (state_ == kInitial || state_ == kStopped) { + // Nothing to do if we are not started. + base::ScopedTaskRunner run_task(shutdown_task); state_ = kStopped; return; } - state_ = kStopped; + if (shutdown_task) + shutdown_tasks_.push_back(shutdown_task); + if (state_ == kStopping) + return; + state_ = kStopping; } // Make sure ScreenRecorder doesn't write to the connection. @@ -149,39 +152,26 @@ void ChromotingHost::Shutdown() { recorder_->RemoveAllConnections(); } + // Stop local inputs monitor. + MonitorLocalInputs(false); + // Disconnect the clients. for (size_t i = 0; i < clients_.size(); i++) { clients_[i]->Disconnect(); } clients_.clear(); - // Notify observers. - for (StatusObserverList::iterator it = status_observers_.begin(); - it != status_observers_.end(); ++it) { - (*it)->OnShutdown(); - } - // Stop chromotocol session manager. if (session_manager_) { session_manager_->Close( - NewRunnableMethod(this, &ChromotingHost::OnServerClosed)); - } - - // Disconnect from the talk network. - if (jingle_client_) { - jingle_client_->Close(); - } - - if (recorder_.get()) { - recorder_->Stop(shutdown_task_.release()); + NewRunnableMethod(this, &ChromotingHost::ShutdownJingleClient)); + session_manager_ = NULL; } else { - shutdown_task_->Run(); - shutdown_task_.reset(); + ShutdownJingleClient(); } } -void ChromotingHost::AddStatusObserver( - const scoped_refptr<HostStatusObserver>& observer) { +void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { DCHECK_EQ(state_, kInitial); status_observers_.push_back(observer); } @@ -192,11 +182,10 @@ void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) { DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); VLOG(1) << "Connection to client established."; // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. - if (is_me2mom_) { + if (is_it2me_) { context_->main_message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &ChromotingHost::ProcessPreAuthentication, - make_scoped_refptr(connection))); + FROM_HERE, base::Bind(&ChromotingHost::ProcessPreAuthentication, this, + make_scoped_refptr(connection))); } } @@ -205,9 +194,8 @@ void ChromotingHost::OnConnectionClosed(ConnectionToClient* connection) { VLOG(1) << "Connection to client closed."; context_->main_message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &ChromotingHost::OnClientDisconnected, - make_scoped_refptr(connection))); + FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this, + make_scoped_refptr(connection))); } void ChromotingHost::OnConnectionFailed(ConnectionToClient* connection) { @@ -215,9 +203,8 @@ void ChromotingHost::OnConnectionFailed(ConnectionToClient* connection) { LOG(ERROR) << "Connection failed unexpectedly."; context_->main_message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &ChromotingHost::OnClientDisconnected, - make_scoped_refptr(connection))); + FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this, + make_scoped_refptr(connection))); } void ChromotingHost::OnSequenceNumberUpdated(ConnectionToClient* connection, @@ -225,9 +212,8 @@ void ChromotingHost::OnSequenceNumberUpdated(ConnectionToClient* connection, // Update the sequence number in ScreenRecorder. if (MessageLoop::current() != context_->main_message_loop()) { context_->main_message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &ChromotingHost::OnSequenceNumberUpdated, - make_scoped_refptr(connection), sequence_number)); + FROM_HERE, base::Bind(&ChromotingHost::OnSequenceNumberUpdated, this, + make_scoped_refptr(connection), sequence_number)); return; } @@ -239,6 +225,8 @@ void ChromotingHost::OnSequenceNumberUpdated(ConnectionToClient* connection, // JingleClient::Callback implementations void ChromotingHost::OnStateChange(JingleClient* jingle_client, JingleClient::State state) { + DCHECK_EQ(MessageLoop::current(), context_->network_message_loop()); + if (state == JingleClient::CONNECTED) { std::string jid = jingle_client->GetFullJid(); @@ -268,14 +256,14 @@ void ChromotingHost::OnStateChange(JingleClient* jingle_client, } } else if (state == JingleClient::CLOSED) { VLOG(1) << "Host disconnected from talk network."; - for (StatusObserverList::iterator it = status_observers_.begin(); it != status_observers_.end(); ++it) { (*it)->OnSignallingDisconnected(); } - // TODO(sergeyu): We should try reconnecting here instead of terminating - // the host. - Shutdown(); + // TODO(sergeyu): Don't shutdown the host and let the upper level + // decide what needs to be done when signalling channel is + // disconnected. + Shutdown(NULL); } } @@ -290,7 +278,7 @@ void ChromotingHost::OnNewClientSession( // If we are running Me2Mom and already have an authenticated client then // reject the connection immediately. - if (is_me2mom_ && HasAuthenticatedClients()) { + if (is_it2me_ && HasAuthenticatedClients()) { *response = protocol::SessionManager::DECLINE; return; } @@ -353,10 +341,7 @@ void ChromotingHost::set_protocol_config( void ChromotingHost::LocalMouseMoved(const gfx::Point& new_pos) { if (MessageLoop::current() != context_->main_message_loop()) { context_->main_message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &ChromotingHost::LocalMouseMoved, - new_pos)); + FROM_HERE, base::Bind(&ChromotingHost::LocalMouseMoved, this, new_pos)); return; } ClientList::iterator client; @@ -381,10 +366,6 @@ void ChromotingHost::PauseSession(bool pause) { StartContinueWindowTimer(!pause); } -void ChromotingHost::OnServerClosed() { - // Don't need to do anything here. -} - void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); @@ -417,7 +398,7 @@ void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { if (!HasAuthenticatedClients()) { EnableCurtainMode(false); - if (is_me2mom_) { + if (is_it2me_) { MonitorLocalInputs(false); ShowDisconnectWindow(false, std::string()); ShowContinueWindow(false); @@ -464,7 +445,7 @@ void ChromotingHost::EnableCurtainMode(bool enable) { // TODO(jamiewalch): This will need to be more sophisticated when we think // about proper crash recovery and daemon mode. // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. - if (is_me2mom_ || enable == is_curtained_) + if (is_it2me_ || enable == is_curtained_) return; desktop_environment_->curtain()->EnableCurtainMode(enable); is_curtained_ = enable; @@ -485,10 +466,8 @@ void ChromotingHost::LocalLoginSucceeded( scoped_refptr<ConnectionToClient> connection) { if (MessageLoop::current() != context_->main_message_loop()) { context_->main_message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &ChromotingHost::LocalLoginSucceeded, - connection)); + FROM_HERE, base::Bind(&ChromotingHost::LocalLoginSucceeded, this, + connection)); return; } @@ -530,7 +509,7 @@ void ChromotingHost::LocalLoginSucceeded( // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, // including closing the connection on failure of a critical operation. EnableCurtainMode(true); - if (is_me2mom_) { + if (is_it2me_) { MonitorLocalInputs(true); std::string username = connection->session()->jid(); size_t pos = username.find('/'); @@ -545,8 +524,8 @@ void ChromotingHost::LocalLoginFailed( scoped_refptr<ConnectionToClient> connection) { if (MessageLoop::current() != context_->main_message_loop()) { context_->main_message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod(this, &ChromotingHost::LocalLoginFailed, connection)); + FROM_HERE, base::Bind(&ChromotingHost::LocalLoginFailed, this, + connection)); return; } @@ -626,4 +605,75 @@ void ChromotingHost::ContinueWindowTimerFunc() { ShowContinueWindow(true); } +void ChromotingHost::ShutdownJingleClient() { + if (MessageLoop::current() != context_->main_message_loop()) { + context_->main_message_loop()->PostTask( + FROM_HERE, base::Bind(&ChromotingHost::ShutdownJingleClient, this)); + return; + } + + // Disconnect from the talk network. + if (jingle_client_) { + jingle_client_->Close(NewRunnableMethod( + this, &ChromotingHost::ShutdownSignallingDisconnected)); + } else { + ShutdownRecorder(); + } +} + +void ChromotingHost::ShutdownSignallingDisconnected() { + if (MessageLoop::current() != context_->network_message_loop()) { + context_->network_message_loop()->PostTask( + FROM_HERE, base::Bind( + &ChromotingHost::ShutdownSignallingDisconnected, this)); + return; + } + + for (StatusObserverList::iterator it = status_observers_.begin(); + it != status_observers_.end(); ++it) { + (*it)->OnSignallingDisconnected(); + } + ShutdownRecorder(); +} + +void ChromotingHost::ShutdownRecorder() { + if (MessageLoop::current() != context_->main_message_loop()) { + context_->main_message_loop()->PostTask( + FROM_HERE, base::Bind(&ChromotingHost::ShutdownRecorder, this)); + return; + } + + if (recorder_.get()) { + recorder_->Stop(NewRunnableMethod(this, &ChromotingHost::ShutdownFinish)); + } else { + ShutdownFinish(); + } +} + +void ChromotingHost::ShutdownFinish() { + if (MessageLoop::current() != context_->main_message_loop()) { + context_->main_message_loop()->PostTask( + FROM_HERE, base::Bind(&ChromotingHost::ShutdownFinish, this)); + return; + } + + { + base::AutoLock auto_lock(lock_); + state_ = kStopped; + } + + // Notify observers. + for (StatusObserverList::iterator it = status_observers_.begin(); + it != status_observers_.end(); ++it) { + (*it)->OnShutdown(); + } + + for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); + it != shutdown_tasks_.end(); ++it) { + (*it)->Run(); + delete *it; + } + shutdown_tasks_.clear(); +} + } // namespace remoting diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index c4b07b2..6ae11e9 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -85,16 +85,18 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // After this is invoked, the host process will connect to the talk // network and start listening for incoming connections. // - // |shutdown_task| is called if Start() has failed ot Shutdown() is called - // and all related operations are completed. - // // This method can only be called once during the lifetime of this object. - void Start(Task* shutdown_task); + void Start(); - // Asynchronously shutdown the host process. - void Shutdown(); + // Asynchronously shutdown the host process. |shutdown_task| is + // called after shutdown is completed. + void Shutdown(Task* shutdown_task); - void AddStatusObserver(const scoped_refptr<HostStatusObserver>& observer); + // Adds |observer| to the list of status observers. Doesn't take + // ownership of |observer|, so |observer| must outlive this + // object. All status observers must be added before the host is + // started. + void AddStatusObserver(HostStatusObserver* observer); //////////////////////////////////////////////////////////////////////////// // protocol::ConnectionToClient::EventHandler implementations @@ -125,8 +127,8 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, void set_protocol_config(protocol::CandidateSessionConfig* config); // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. - void set_me2mom(bool is_me2mom) { - is_me2mom_ = is_me2mom; + void set_it2me(bool is_it2me) { + is_it2me_ = is_it2me; } // Notify all active client sessions that local input has been detected, and @@ -141,7 +143,7 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, friend class base::RefCountedThreadSafe<ChromotingHost>; friend class ChromotingHostTest; - typedef std::vector<scoped_refptr<HostStatusObserver> > StatusObserverList; + typedef std::vector<HostStatusObserver*> StatusObserverList; typedef std::vector<scoped_refptr<ClientSession> > ClientList; // Takes ownership of |access_verifier| and |environment|, and adds a @@ -155,12 +157,10 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, enum State { kInitial, kStarted, + kStopping, kStopped, }; - // Callback for protocol::SessionManager::Close(). - void OnServerClosed(); - // This method is called if a client is disconnected from the host. void OnClientDisconnected(protocol::ConnectionToClient* client); @@ -189,6 +189,12 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, void ContinueWindowTimerFunc(); + // The following methods are called during shutdown. + void ShutdownJingleClient(); + void ShutdownSignallingDisconnected(); + void ShutdownRecorder(); + void ShutdownFinish(); + // The context that the chromoting host runs on. ChromotingHostContext* context_; @@ -214,10 +220,6 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // Session manager for the host process. scoped_refptr<ScreenRecorder> recorder_; - // This task gets executed when this object fails to connect to the - // talk network or Shutdown() is called. - scoped_ptr<Task> shutdown_task_; - // Tracks the internal state of the host. // This variable is written on the main thread of ChromotingHostContext // and read by jingle thread. @@ -237,9 +239,13 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // blocked and the dialog is shown. base::OneShotTimer<ChromotingHost> continue_window_timer_; - // Whether or not the host is running in "Me2Mom" mode, in which connections + // Whether or not the host is running in "IT2Me" mode, in which connections // are pre-authenticated, and hence the local login challenge can be bypassed. - bool is_me2mom_; + bool is_it2me_; + + // Stores list of tasks that should be executed when we finish + // shutdown. Used only while |state_| is set to kStopping. + std::vector<Task*> shutdown_tasks_; DISALLOW_COPY_AND_ASSIGN(ChromotingHost); }; diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index b97cc05..fbf0b8f 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -199,6 +199,11 @@ class ChromotingHostTest : public testing::Test { host->clients_.push_back(session); } + void ShutdownHost() { + host_->Shutdown( + NewRunnableFunction(&PostQuitTask, &message_loop_)); + } + protected: MessageLoop message_loop_; MockConnectionToClientEventHandler handler_; @@ -229,16 +234,17 @@ class ChromotingHostTest : public testing::Test { }; TEST_F(ChromotingHostTest, DISABLED_StartAndShutdown) { - host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); + host_->Start(); - message_loop_.PostTask(FROM_HERE, - NewRunnableMethod(host_.get(), - &ChromotingHost::Shutdown)); + message_loop_.PostTask( + FROM_HERE,NewRunnableMethod( + host_.get(), &ChromotingHost::Shutdown, + NewRunnableFunction(&PostQuitTask, &message_loop_))); message_loop_.Run(); } TEST_F(ChromotingHostTest, DISABLED_Connect) { - host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); + host_->Start(); EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) .WillOnce(RunDoneTask()); @@ -253,7 +259,7 @@ TEST_F(ChromotingHostTest, DISABLED_Connect) { .Times(0); EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) .WillOnce(DoAll( - InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), + InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost), RunDoneTask())) .RetiresOnSaturation(); EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) @@ -266,7 +272,7 @@ TEST_F(ChromotingHostTest, DISABLED_Connect) { } TEST_F(ChromotingHostTest, DISABLED_Reconnect) { - host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); + host_->Start(); EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) .Times(2) @@ -312,7 +318,7 @@ TEST_F(ChromotingHostTest, DISABLED_Reconnect) { .Times(0); EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) .WillOnce(DoAll( - InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), + InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost), RunDoneTask())) .RetiresOnSaturation(); EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) @@ -327,7 +333,7 @@ TEST_F(ChromotingHostTest, DISABLED_Reconnect) { } TEST_F(ChromotingHostTest, DISABLED_ConnectTwice) { - host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); + host_->Start(); EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) .Times(1) @@ -363,7 +369,7 @@ TEST_F(ChromotingHostTest, DISABLED_ConnectTwice) { .Times(AnyNumber()); EXPECT_CALL(video_stub2_, ProcessVideoPacket(_, _)) .WillOnce(DoAll( - InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), + InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost), RunDoneTask())) .RetiresOnSaturation(); EXPECT_CALL(video_stub2_, ProcessVideoPacket(_, _)) @@ -380,7 +386,7 @@ TEST_F(ChromotingHostTest, DISABLED_ConnectTwice) { } TEST_F(ChromotingHostTest, CurtainModeFail) { - host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); + host_->Start(); EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) .WillOnce(RunDoneTask()); @@ -399,7 +405,7 @@ TEST_F(ChromotingHostTest, CurtainModeFail) { } TEST_F(ChromotingHostTest, CurtainModeFailSecond) { - host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); + host_->Start(); EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) .WillOnce(RunDoneTask()); @@ -442,8 +448,8 @@ TEST_F(ChromotingHostTest, CurtainModeFailSecond) { ACTION_P(SetBool, var) { *var = true; } TEST_F(ChromotingHostTest, CurtainModeIT2Me) { - host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); - host_->set_me2mom(true); + host_->Start(); + host_->set_it2me(true); EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) .WillOnce(RunDoneTask()); @@ -472,7 +478,7 @@ TEST_F(ChromotingHostTest, CurtainModeIT2Me) { EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) .InSequence(s1, s2) .WillOnce(DoAll( - InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), + InvokeWithoutArgs(this, &ChromotingHostTest::ShutdownHost), RunDoneTask())) .RetiresOnSaturation(); EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) @@ -484,7 +490,7 @@ TEST_F(ChromotingHostTest, CurtainModeIT2Me) { } SimulateClientConnection(0, true); message_loop_.Run(); - host_->set_me2mom(false); + host_->set_it2me(false); EXPECT_THAT(curtain_activated, false); } } // namespace remoting diff --git a/remoting/host/disconnect_window_linux.cc b/remoting/host/disconnect_window_linux.cc index 2aa8798..3d3464b 100644 --- a/remoting/host/disconnect_window_linux.cc +++ b/remoting/host/disconnect_window_linux.cc @@ -111,7 +111,7 @@ gboolean DisconnectWindowLinux::OnWindowDelete(GtkWidget* widget, void DisconnectWindowLinux::OnDisconnectClicked(GtkButton* sender) { DCHECK(host_); - host_->Shutdown(); + host_->Shutdown(NULL); } remoting::DisconnectWindow* remoting::DisconnectWindow::Create() { diff --git a/remoting/host/disconnect_window_mac.mm b/remoting/host/disconnect_window_mac.mm index 33a2be4..0cfe62b 100644 --- a/remoting/host/disconnect_window_mac.mm +++ b/remoting/host/disconnect_window_mac.mm @@ -96,7 +96,7 @@ remoting::DisconnectWindow* remoting::DisconnectWindow::Create() { - (IBAction)stopSharing:(id)sender { if (self.host) { - self.host->Shutdown(); + self.host->Shutdown(NULL); self.host = NULL; } if (self.disconnectWindow) { diff --git a/remoting/host/disconnect_window_win.cc b/remoting/host/disconnect_window_win.cc index 80bc9d4..09f6b16 100644 --- a/remoting/host/disconnect_window_win.cc +++ b/remoting/host/disconnect_window_win.cc @@ -98,7 +98,7 @@ BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, case IDC_DISCONNECT: { CHECK(host_); - host_->Shutdown(); + host_->Shutdown(NULL); EndDialog(hwnd, LOWORD(wParam)); hwnd_ = NULL; } diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 46f80ed..4ffa458 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc @@ -59,7 +59,7 @@ TEST_F(HeartbeatSenderTest, DoSendStanza) { EXPECT_CALL(*iq_request, set_callback(_)).Times(1); - scoped_refptr<HeartbeatSender> heartbeat_sender( + scoped_ptr<HeartbeatSender> heartbeat_sender( new HeartbeatSender(&message_loop_, config_)); ASSERT_TRUE(heartbeat_sender->Init()); @@ -78,7 +78,7 @@ TEST_F(HeartbeatSenderTest, DoSendStanza) { // Validate format of the heartbeat stanza. TEST_F(HeartbeatSenderTest, CreateHeartbeatMessage) { - scoped_refptr<HeartbeatSender> heartbeat_sender( + scoped_ptr<HeartbeatSender> heartbeat_sender( new HeartbeatSender(&message_loop_, config_)); ASSERT_TRUE(heartbeat_sender->Init()); @@ -129,7 +129,7 @@ TEST_F(HeartbeatSenderTest, ProcessResponse) { const int kTestInterval = 123; set_interval->AddText(base::IntToString(kTestInterval)); - scoped_refptr<HeartbeatSender> heartbeat_sender( + scoped_ptr<HeartbeatSender> heartbeat_sender( new HeartbeatSender(&message_loop_, config_)); heartbeat_sender->ProcessResponse(response.get()); diff --git a/remoting/host/host_plugin.cc b/remoting/host/host_plugin.cc index 11b621e..f63c3c7 100644 --- a/remoting/host/host_plugin.cc +++ b/remoting/host/host_plugin.cc @@ -21,11 +21,13 @@ #include "base/task.h" #include "base/threading/platform_thread.h" #include "base/threading/thread.h" +#include "base/synchronization/cancellation_flag.h" #include "remoting/base/auth_token_util.h" #include "remoting/host/chromoting_host.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/host_config.h" #include "remoting/host/host_key_pair.h" +#include "remoting/host/host_status_observer.h" #include "remoting/host/in_memory_host_config.h" #include "remoting/host/register_support_host_request.h" #include "remoting/host/support_access_verifier.h" @@ -56,29 +58,42 @@ uint64_t __cdecl __udivdi3(uint64_t a, uint64_t b) { } #endif -/* - Supported Javascript interface: - readonly attribute string accessCode; - readonly attribute int state; +// Supported Javascript interface: +// readonly attribute string accessCode; +// readonly attribute int state; +// +// state: { +// DISCONNECTED, +// REQUESTED_ACCESS_CODE, +// RECEIVED_ACCESS_CODE, +// CONNECTED, +// AFFIRMING_CONNECTION, +// ERROR, +// } +// +// attribute Function void onStateChanged(); +// +// // The |auth_service_with_token| parameter should be in the format +// // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd". +// void connect(string uid, string auth_service_with_token); +// void disconnect(); - state: { - DISCONNECTED, - REQUESTED_ACCESS_CODE, - RECEIVED_ACCESS_CODE, - CONNECTED, - AFFIRMING_CONNECTION, - ERROR, - } - attribute Function void onStateChanged(); +namespace { - // The |auth_service_with_token| parametershould be in the format - // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd". - void connect(string uid, string auth_service_with_token); - void disconnect(); -*/ +const char* kAttrNameAccessCode = "accessCode"; +const char* kAttrNameState = "state"; +const char* kAttrNameOnStateChanged = "onStateChanged"; +const char* kFuncNameConnect = "connect"; +const char* kFuncNameDisconnect = "disconnect"; -namespace { +// States. +const char* kAttrNameDisconnected = "DISCONNECTED"; +const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; +const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; +const char* kAttrNameConnected = "CONNECTED"; +const char* kAttrNameAffirmingConnection = "AFFIRMING_CONNECTION"; +const char* kAttrNameError = "ERROR"; // Global netscape functions initialized in NP_Initialize. NPNetscapeFuncs* g_npnetscape_funcs = NULL; @@ -131,21 +146,35 @@ NPObject* ObjectFromNPVariant(const NPVariant& variant) { } // NPAPI plugin implementation for remoting host script object. -class HostNPScriptObject { +// HostNPScriptObject creates threads that are required to run +// ChromotingHost and starts/stops the host on those threads. When +// destroyed it sychronously shuts down the host and all threads. +class HostNPScriptObject : public remoting::HostStatusObserver { public: HostNPScriptObject(NPP plugin, NPObject* parent) : plugin_(plugin), parent_(parent), state_(kDisconnected), on_state_changed_func_(NULL), - np_thread_id_(base::PlatformThread::CurrentId()) { - LOG(INFO) << "HostNPScriptObject"; + np_thread_id_(base::PlatformThread::CurrentId()), + disconnected_event_(true, false) { + VLOG(2) << "HostNPScriptObject"; host_context_.SetUITaskPostFunction(base::Bind( &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this))); } ~HostNPScriptObject() { CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); + + // Disconnect synchronously. We cannot disconnect asynchronously + // here because |host_context_| needs to be stopped on the plugin + // thread, but the plugin thread may not exist after the instance + // is destroyed. + destructing_.Set(); + disconnected_event_.Reset(); + DisconnectInternal(); + disconnected_event_.Wait(); + host_context_.Stop(); if (on_state_changed_func_) { g_npnetscape_funcs->releaseobject(on_state_changed_func_); @@ -153,14 +182,14 @@ class HostNPScriptObject { } bool Init() { - LOG(INFO) << "Init"; + VLOG(2) << "Init"; // TODO(wez): This starts a bunch of threads, which might fail. host_context_.Start(); return true; } bool HasMethod(const std::string& method_name) { - LOG(INFO) << "HasMethod " << method_name; + VLOG(2) << "HasMethod " << method_name; CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); return (method_name == kFuncNameConnect || method_name == kFuncNameDisconnect); @@ -169,7 +198,7 @@ class HostNPScriptObject { bool InvokeDefault(const NPVariant* args, uint32_t argCount, NPVariant* result) { - LOG(INFO) << "InvokeDefault"; + VLOG(2) << "InvokeDefault"; CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); SetException("exception during default invocation"); return false; @@ -179,7 +208,7 @@ class HostNPScriptObject { const NPVariant* args, uint32_t argCount, NPVariant* result) { - LOG(INFO) << "Invoke " << method_name; + VLOG(2) << "Invoke " << method_name; CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); if (method_name == kFuncNameConnect) { return Connect(args, argCount, result); @@ -192,7 +221,7 @@ class HostNPScriptObject { } bool HasProperty(const std::string& property_name) { - LOG(INFO) << "HasProperty " << property_name; + VLOG(2) << "HasProperty " << property_name; CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); return (property_name == kAttrNameAccessCode || property_name == kAttrNameState || @@ -206,7 +235,7 @@ class HostNPScriptObject { } bool GetProperty(const std::string& property_name, NPVariant* result) { - LOG(INFO) << "GetProperty " << property_name; + VLOG(2) << "GetProperty " << property_name; CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); if (!result) { SetException("GetProperty: NULL result"); @@ -247,7 +276,7 @@ class HostNPScriptObject { } bool SetProperty(const std::string& property_name, const NPVariant* value) { - LOG(INFO) << "SetProperty " << property_name; + VLOG(2) << "SetProperty " << property_name; CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); if (property_name == kAttrNameOnStateChanged) { @@ -271,13 +300,13 @@ class HostNPScriptObject { } bool RemoveProperty(const std::string& property_name) { - LOG(INFO) << "RemoveProperty " << property_name; + VLOG(2) << "RemoveProperty " << property_name; CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); return false; } bool Enumerate(std::vector<std::string>* values) { - LOG(INFO) << "Enumerate"; + VLOG(2) << "Enumerate"; CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); const char* entries[] = { kAttrNameAccessCode, @@ -298,26 +327,22 @@ class HostNPScriptObject { return true; } - private: - // JS string - static const char* kAttrNameAccessCode; - // JS int - static const char* kAttrNameState; - // JS func onStateChanged() - static const char* kAttrNameOnStateChanged; - // void connect(string uid, string auth_token); - static const char* kFuncNameConnect; - // void disconnect(); - static const char* kFuncNameDisconnect; - - // States - static const char* kAttrNameDisconnected; - static const char* kAttrNameRequestedAccessCode; - static const char* kAttrNameReceivedAccessCode; - static const char* kAttrNameConnected; - static const char* kAttrNameAffirmingConnection; - static const char* kAttrNameError; + // remoting::HostStatusObserver implementation. + virtual void OnSignallingConnected(remoting::SignalStrategy* signal_strategy, + const std::string& full_jid) OVERRIDE { + OnStateChanged(kConnected); + } + + virtual void OnSignallingDisconnected() OVERRIDE { + } + virtual void OnShutdown() OVERRIDE { + DCHECK_EQ(MessageLoop::current(), host_context_.main_message_loop()); + + OnStateChanged(kDisconnected); + } + + private: enum State { kDisconnected, kRequestedAccessCode, @@ -327,18 +352,6 @@ class HostNPScriptObject { kError }; - NPP plugin_; - NPObject* parent_; - int state_; - std::string access_code_; - NPObject* on_state_changed_func_; - base::PlatformThreadId np_thread_id_; - - scoped_refptr<remoting::RegisterSupportHostRequest> register_request_; - scoped_refptr<remoting::ChromotingHost> host_; - scoped_refptr<remoting::MutableHostConfig> host_config_; - remoting::ChromotingHostContext host_context_; - // Start connection. args are: // string uid, string auth_token // No result. @@ -354,8 +367,16 @@ class HostNPScriptObject { void OnReceivedSupportID(remoting::SupportAccessVerifier* access_verifier, bool success, const std::string& support_id); - void OnConnected(); - void OnHostShutdown(); + + // Helper functions that run on main thread. Can be called on any + // other thread. + void ConnectInternal(const std::string& uid, + const std::string& auth_token, + const std::string& auth_service); + void DisconnectInternal(); + + // Callback for ChromotingHost::Shutdown(). + void OnShutdownFinished(); // Call a JavaScript function wrapped as an NPObject. // If result is non-null, the result of the call will be stored in it. @@ -374,24 +395,22 @@ class HostNPScriptObject { // Set an exception for the current call. void SetException(const std::string& exception_string); -}; -const char* HostNPScriptObject::kAttrNameAccessCode = "accessCode"; -const char* HostNPScriptObject::kAttrNameState = "state"; -const char* HostNPScriptObject::kAttrNameOnStateChanged = "onStateChanged"; -const char* HostNPScriptObject::kFuncNameConnect = "connect"; -const char* HostNPScriptObject::kFuncNameDisconnect = "disconnect"; - -// States -const char* HostNPScriptObject::kAttrNameDisconnected = "DISCONNECTED"; -const char* HostNPScriptObject::kAttrNameRequestedAccessCode = - "REQUESTED_ACCESS_CODE"; -const char* HostNPScriptObject::kAttrNameReceivedAccessCode = - "RECEIVED_ACCESS_CODE"; -const char* HostNPScriptObject::kAttrNameConnected = "CONNECTED"; -const char* HostNPScriptObject::kAttrNameAffirmingConnection = - "AFFIRMING_CONNECTION"; -const char* HostNPScriptObject::kAttrNameError = "ERROR"; + NPP plugin_; + NPObject* parent_; + int state_; + std::string access_code_; + NPObject* on_state_changed_func_; + base::PlatformThreadId np_thread_id_; + + scoped_ptr<remoting::RegisterSupportHostRequest> register_request_; + scoped_refptr<remoting::ChromotingHost> host_; + scoped_refptr<remoting::MutableHostConfig> host_config_; + remoting::ChromotingHostContext host_context_; + + base::WaitableEvent disconnected_event_; + base::CancellationFlag destructing_; +}; // string uid, string auth_token bool HostNPScriptObject::Connect(const NPVariant* args, @@ -419,6 +438,22 @@ bool HostNPScriptObject::Connect(const NPVariant* args, return false; } + ConnectInternal(uid, auth_token, auth_service); + + return true; +} + +void HostNPScriptObject::ConnectInternal( + const std::string& uid, + const std::string& auth_token, + const std::string& auth_service) { + if (MessageLoop::current() != host_context_.main_message_loop()) { + host_context_.main_message_loop()->PostTask( + FROM_HERE, + NewRunnableMethod(this, &HostNPScriptObject::ConnectInternal, + uid, auth_token, auth_service)); + return; + } // Store the supplied user ID and token to the Host configuration. scoped_refptr<remoting::MutableHostConfig> host_config = new remoting::InMemoryHostConfig; @@ -429,10 +464,6 @@ bool HostNPScriptObject::Connect(const NPVariant* args, // Create an access verifier and fetch the host secret. scoped_ptr<remoting::SupportAccessVerifier> access_verifier; access_verifier.reset(new remoting::SupportAccessVerifier); - if (!access_verifier->Init()) { - SetException("connect: SupportAccessVerifier::Init failed"); - return false; - } // Generate a key pair for the Host to use. // TODO(wez): Move this to the worker thread. @@ -441,36 +472,35 @@ bool HostNPScriptObject::Connect(const NPVariant* args, host_key_pair.Save(host_config); // Request registration of the host for support. - scoped_refptr<remoting::RegisterSupportHostRequest> register_request = - new remoting::RegisterSupportHostRequest(); + scoped_ptr<remoting::RegisterSupportHostRequest> register_request( + new remoting::RegisterSupportHostRequest()); if (!register_request->Init( host_config.get(), base::Bind(&HostNPScriptObject::OnReceivedSupportID, base::Unretained(this), access_verifier.get()))) { - SetException("connect: RegisterSupportHostRequest::Init failed"); - return false; + OnStateChanged(kDisconnected); + return; } // Create the Host. scoped_refptr<remoting::ChromotingHost> host = remoting::ChromotingHost::Create(&host_context_, host_config, access_verifier.release()); - host->AddStatusObserver(register_request); - host->set_me2mom(true); + host->AddStatusObserver(this); + host->AddStatusObserver(register_request.get()); + host->set_it2me(true); // Nothing went wrong, so lets save the host, config and request. host_ = host; host_config_ = host_config; - register_request_ = register_request; + register_request_.reset(register_request.release()); // Start the Host. - // TODO(wez): Attach to the Host for notifications of state changes. - // It currently has no interface for that, though. - host_->Start(NewRunnableMethod(this, &HostNPScriptObject::OnHostShutdown)); + host_->Start(); OnStateChanged(kRequestedAccessCode); - return true; + return; } bool HostNPScriptObject::Disconnect(const NPVariant* args, @@ -482,17 +512,37 @@ bool HostNPScriptObject::Disconnect(const NPVariant* args, return false; } - if (host_.get()) { - host_->Shutdown(); - host_ = NULL; - } - register_request_ = NULL; - host_config_ = NULL; + DisconnectInternal(); - OnStateChanged(kDisconnected); return true; } +void HostNPScriptObject::DisconnectInternal() { + if (MessageLoop::current() != host_context_.main_message_loop()) { + host_context_.main_message_loop()->PostTask( + FROM_HERE, + NewRunnableMethod(this, &HostNPScriptObject::DisconnectInternal)); + return; + } + + if (!host_) { + disconnected_event_.Signal(); + return; + } + + host_->Shutdown( + NewRunnableMethod(this, &HostNPScriptObject::OnShutdownFinished)); +} + +void HostNPScriptObject::OnShutdownFinished() { + DCHECK_EQ(MessageLoop::current(), host_context_.main_message_loop()); + + host_ = NULL; + register_request_.reset(); + host_config_ = NULL; + disconnected_event_.Signal(); +} + void HostNPScriptObject::OnReceivedSupportID( remoting::SupportAccessVerifier* access_verifier, bool success, @@ -501,12 +551,12 @@ void HostNPScriptObject::OnReceivedSupportID( if (!success) { // TODO(wez): Replace the success/fail flag with full error reporting. - OnHostShutdown(); + DisconnectInternal(); return; } // Inform the AccessVerifier of our Support-Id, for authentication. - access_verifier->OnMe2MomHostRegistered(success, support_id); + access_verifier->OnIT2MeHostRegistered(success, support_id); // Combine the Support Id with the Host Id to make the Access Code. // TODO(wez): Locking, anyone? @@ -516,17 +566,11 @@ void HostNPScriptObject::OnReceivedSupportID( OnStateChanged(kReceivedAccessCode); } -void HostNPScriptObject::OnConnected() { - CHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_); - OnStateChanged(kConnected); -} - -void HostNPScriptObject::OnHostShutdown() { - CHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_); - OnStateChanged(kDisconnected); -} - void HostNPScriptObject::OnStateChanged(State state) { + if (destructing_.IsSet()) { + return; + } + if (!host_context_.IsUIThread()) { host_context_.PostToUIThread( FROM_HERE, @@ -535,7 +579,7 @@ void HostNPScriptObject::OnStateChanged(State state) { } state_ = state; if (on_state_changed_func_) { - LOG(INFO) << "Calling state changed " << state; + VLOG(2) << "Calling state changed " << state; bool is_good = CallJSFunction(on_state_changed_func_, NULL, 0, NULL); LOG_IF(ERROR, !is_good) << "OnStateChangedNP failed"; } @@ -681,7 +725,7 @@ class HostNPPlugin { } static NPObject* Allocate(NPP npp, NPClass* aClass) { - LOG(INFO) << "static Allocate"; + VLOG(2) << "static Allocate"; ScriptableNPObject* object = reinterpret_cast<ScriptableNPObject*>( g_npnetscape_funcs->memalloc(sizeof(ScriptableNPObject))); @@ -697,7 +741,7 @@ class HostNPPlugin { } static void Deallocate(NPObject* npobj) { - LOG(INFO) << "static Deallocate"; + VLOG(2) << "static Deallocate"; if (npobj) { Invalidate(npobj); g_npnetscape_funcs->memfree(npobj); @@ -715,7 +759,7 @@ class HostNPPlugin { } static bool HasMethod(NPObject* obj, NPIdentifier method_name) { - LOG(INFO) << "static HasMethod"; + VLOG(2) << "static HasMethod"; HostNPScriptObject* scriptable = ScriptableFromObject(obj); if (!scriptable) return false; std::string method_name_string = StringFromNPIdentifier(method_name); @@ -728,7 +772,7 @@ class HostNPPlugin { const NPVariant* args, uint32_t argCount, NPVariant* result) { - LOG(INFO) << "static InvokeDefault"; + VLOG(2) << "static InvokeDefault"; HostNPScriptObject* scriptable = ScriptableFromObject(obj); if (!scriptable) return false; return scriptable->InvokeDefault(args, argCount, result); @@ -739,7 +783,7 @@ class HostNPPlugin { const NPVariant* args, uint32_t argCount, NPVariant* result) { - LOG(INFO) << "static Invoke"; + VLOG(2) << "static Invoke"; HostNPScriptObject* scriptable = ScriptableFromObject(obj); if (!scriptable) return false; @@ -750,7 +794,7 @@ class HostNPPlugin { } static bool HasProperty(NPObject* obj, NPIdentifier property_name) { - LOG(INFO) << "static HasProperty"; + VLOG(2) << "static HasProperty"; HostNPScriptObject* scriptable = ScriptableFromObject(obj); if (!scriptable) return false; std::string property_name_string = StringFromNPIdentifier(property_name); @@ -762,7 +806,7 @@ class HostNPPlugin { static bool GetProperty(NPObject* obj, NPIdentifier property_name, NPVariant* result) { - LOG(INFO) << "static GetProperty"; + VLOG(2) << "static GetProperty"; HostNPScriptObject* scriptable = ScriptableFromObject(obj); if (!scriptable) return false; std::string property_name_string = StringFromNPIdentifier(property_name); @@ -774,7 +818,7 @@ class HostNPPlugin { static bool SetProperty(NPObject* obj, NPIdentifier property_name, const NPVariant* value) { - LOG(INFO) << "static SetProperty"; + VLOG(2) << "static SetProperty"; HostNPScriptObject* scriptable = ScriptableFromObject(obj); if (!scriptable) return false; std::string property_name_string = StringFromNPIdentifier(property_name); @@ -784,7 +828,7 @@ class HostNPPlugin { } static bool RemoveProperty(NPObject* obj, NPIdentifier property_name) { - LOG(INFO) << "static RemoveProperty"; + VLOG(2) << "static RemoveProperty"; HostNPScriptObject* scriptable = ScriptableFromObject(obj); if (!scriptable) return false; std::string property_name_string = StringFromNPIdentifier(property_name); @@ -796,7 +840,7 @@ class HostNPPlugin { static bool Enumerate(NPObject* obj, NPIdentifier** value, uint32_t* count) { - LOG(INFO) << "static Enumerate"; + VLOG(2) << "static Enumerate"; HostNPScriptObject* scriptable = ScriptableFromObject(obj); if (!scriptable) return false; std::vector<std::string> values; @@ -829,7 +873,7 @@ NPError CreatePlugin(NPMIMEType pluginType, char** argn, char** argv, NPSavedData* saved) { - LOG(INFO) << "CreatePlugin"; + VLOG(2) << "CreatePlugin"; HostNPPlugin* plugin = new HostNPPlugin(instance, mode); instance->pdata = plugin; if (!plugin->Init(argc, argn, argv, saved)) { @@ -843,7 +887,7 @@ NPError CreatePlugin(NPMIMEType pluginType, NPError DestroyPlugin(NPP instance, NPSavedData** save) { - LOG(INFO) << "DestroyPlugin"; + VLOG(2) << "DestroyPlugin"; HostNPPlugin* plugin = PluginFromInstance(instance); if (plugin) { plugin->Save(save); @@ -858,22 +902,22 @@ NPError DestroyPlugin(NPP instance, NPError GetValue(NPP instance, NPPVariable variable, void* value) { switch(variable) { default: - LOG(INFO) << "GetValue - default " << variable; + VLOG(2) << "GetValue - default " << variable; return NPERR_GENERIC_ERROR; case NPPVpluginNameString: - LOG(INFO) << "GetValue - name string"; + VLOG(2) << "GetValue - name string"; *reinterpret_cast<const char**>(value) = HOST_PLUGIN_NAME; break; case NPPVpluginDescriptionString: - LOG(INFO) << "GetValue - description string"; + VLOG(2) << "GetValue - description string"; *reinterpret_cast<const char**>(value) = HOST_PLUGIN_DESCRIPTION; break; case NPPVpluginNeedsXEmbed: - LOG(INFO) << "GetValue - NeedsXEmbed"; + VLOG(2) << "GetValue - NeedsXEmbed"; *(static_cast<NPBool*>(value)) = true; break; case NPPVpluginScriptableNPObject: - LOG(INFO) << "GetValue - scriptable object"; + VLOG(2) << "GetValue - scriptable object"; HostNPPlugin* plugin = PluginFromInstance(instance); if (!plugin) return NPERR_INVALID_PLUGIN_ERROR; @@ -886,18 +930,17 @@ NPError GetValue(NPP instance, NPPVariable variable, void* value) { } NPError HandleEvent(NPP instance, void* ev) { - LOG(INFO) << "HandleEvent"; + VLOG(2) << "HandleEvent"; return NPERR_NO_ERROR; } NPError SetWindow(NPP instance, NPWindow* pNPWindow) { - LOG(INFO) << "SetWindow"; + VLOG(2) << "SetWindow"; return NPERR_NO_ERROR; } } // namespace -// TODO(fix): Temporary hack while we figure out threading models correctly. DISABLE_RUNNABLE_METHOD_REFCOUNT(HostNPScriptObject); #if defined(OS_WIN) @@ -923,7 +966,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { extern "C" { EXPORT NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* nppfuncs) { - LOG(INFO) << "NP_GetEntryPoints"; + VLOG(2) << "NP_GetEntryPoints"; nppfuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; nppfuncs->newp = &CreatePlugin; nppfuncs->destroy = &DestroyPlugin; @@ -939,7 +982,7 @@ EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnetscape_funcs , NPPluginFuncs* nppfuncs #endif ) { - LOG(INFO) << "NP_Initialize"; + VLOG(2) << "NP_Initialize"; if (g_at_exit_manager) return NPERR_MODULE_LOAD_FAILED_ERROR; @@ -958,7 +1001,7 @@ EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnetscape_funcs } EXPORT NPError API_CALL NP_Shutdown() { - LOG(INFO) << "NP_Shutdown"; + VLOG(2) << "NP_Shutdown"; delete g_at_exit_manager; g_at_exit_manager = NULL; return NPERR_NO_ERROR; @@ -966,7 +1009,7 @@ EXPORT NPError API_CALL NP_Shutdown() { #if defined(OS_POSIX) && !defined(OS_MACOSX) EXPORT const char* API_CALL NP_GetMIMEDescription(void) { - LOG(INFO) << "NP_GetMIMEDescription"; + VLOG(2) << "NP_GetMIMEDescription"; return STRINGIZE(HOST_PLUGIN_MIME_TYPE) ":" HOST_PLUGIN_NAME ":" HOST_PLUGIN_DESCRIPTION; diff --git a/remoting/host/host_status_observer.h b/remoting/host/host_status_observer.h index dd0ae85..e7fda0b 100644 --- a/remoting/host/host_status_observer.h +++ b/remoting/host/host_status_observer.h @@ -5,16 +5,14 @@ #ifndef REMOTING_HOST_STATUS_OBSERVER_H_ #define REMOTING_HOST_STATUS_OBSERVER_H_ -#include "base/memory/ref_counted.h" - namespace remoting { class SignalStrategy; -class HostStatusObserver - : public base::RefCountedThreadSafe<HostStatusObserver> { +class HostStatusObserver { public: HostStatusObserver() { } + virtual ~HostStatusObserver() { } // Called on the network thread when status of the XMPP changes. virtual void OnSignallingConnected(SignalStrategy* signal_strategy, @@ -23,10 +21,6 @@ class HostStatusObserver // Called on the main thread when the host shuts down. virtual void OnShutdown() = 0; - - protected: - friend class base::RefCountedThreadSafe<HostStatusObserver>; - virtual ~HostStatusObserver() { } }; } // namespace remoting diff --git a/remoting/host/register_support_host_request_unittest.cc b/remoting/host/register_support_host_request_unittest.cc index 53761fa..58c639e 100644 --- a/remoting/host/register_support_host_request_unittest.cc +++ b/remoting/host/register_support_host_request_unittest.cc @@ -61,7 +61,7 @@ TEST_F(RegisterSupportHostRequestTest, Send) { // |iq_request| is freed by RegisterSupportHostRequest. int64 start_time = static_cast<int64>(base::Time::Now().ToDoubleT()); - scoped_refptr<RegisterSupportHostRequest> request( + scoped_ptr<RegisterSupportHostRequest> request( new RegisterSupportHostRequest()); ASSERT_TRUE(request->Init( config_, base::Bind(&MockCallback::OnResponse, diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc index 85f3aa8..f4da528 100644 --- a/remoting/host/simple_host_process.cc +++ b/remoting/host/simple_host_process.cc @@ -81,12 +81,8 @@ const char kDefaultConfigPath[] = ".ChromotingConfig.json"; static char* GetEnvironmentVar(const char* x) { return getenv(x); } #endif -void ShutdownTask(MessageLoop* message_loop) { - message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); -} - const char kFakeSwitchName[] = "fake"; -const char kMe2MomSwitchName[] = "me2mom"; +const char kIT2MeSwitchName[] = "it2me"; const char kConfigSwitchName[] = "config"; const char kVideoSwitchName[] = "video"; @@ -95,10 +91,10 @@ const char kVideoSwitchValueZip[] = "zip"; const char kVideoSwitchValueVp8[] = "vp8"; const char kVideoSwitchValueVp8Rtp[] = "vp8rtp"; -// Glue class to print out the access code for Me2Mom. -void SetMe2MomAccessCode(remoting::SupportAccessVerifier* access_verifier, +// Glue class to print out the access code for IT2Me. +void SetIT2MeAccessCode(remoting::SupportAccessVerifier* access_verifier, bool successful, const std::string& support_id) { - access_verifier->OnMe2MomHostRegistered(successful, support_id); + access_verifier->OnIT2MeHostRegistered(successful, support_id); if (successful) { std::cout << "Support id: " << support_id << "-" << access_verifier->host_secret() << std::endl; @@ -112,7 +108,7 @@ class SimpleHost { public: SimpleHost() : fake_(false), - is_me2mom_(false) { + is_it2me_(false) { } int Run() { @@ -151,21 +147,20 @@ class SimpleHost { kChromotingTokenDefaultServiceName); // Initialize AccessVerifier. - // TODO(jamiewalch): For the Me2Mom case, the access verifier is passed to + // TODO(jamiewalch): For the IT2Me case, the access verifier is passed to // RegisterSupportHostRequest::Init, so transferring ownership of it to the - // ChromotingHost could cause a crash condition if SetMe2MomAccessCode is + // ChromotingHost could cause a crash condition if SetIT2MeAccessCode is // called after the ChromotingHost is destroyed (for example, at shutdown). // Fix this. scoped_ptr<remoting::AccessVerifier> access_verifier; - scoped_refptr<remoting::RegisterSupportHostRequest> register_request; - if (is_me2mom_) { + scoped_ptr<remoting::RegisterSupportHostRequest> register_request; + scoped_ptr<remoting::HeartbeatSender> heartbeat_sender; + if (is_it2me_) { scoped_ptr<remoting::SupportAccessVerifier> support_access_verifier( new remoting::SupportAccessVerifier()); - if (!support_access_verifier->Init()) - return 1; - register_request = new remoting::RegisterSupportHostRequest(); + register_request.reset(new remoting::RegisterSupportHostRequest()); if (!register_request->Init( - config, base::Bind(&SetMe2MomAccessCode, + config, base::Bind(&SetIT2MeAccessCode, support_access_verifier.get()))) { return 1; } @@ -202,25 +197,26 @@ class SimpleHost { host = ChromotingHost::Create(&context, config, access_verifier.release()); } - host->set_me2mom(is_me2mom_); + host->set_it2me(is_it2me_); if (protocol_config_.get()) { host->set_protocol_config(protocol_config_.release()); } - if (is_me2mom_) { - host->AddStatusObserver(register_request); + if (is_it2me_) { + host->AddStatusObserver(register_request.get()); } else { // Initialize HeartbeatSender. - scoped_refptr<remoting::HeartbeatSender> heartbeat_sender = - new remoting::HeartbeatSender(context.network_message_loop(), config); + heartbeat_sender.reset( + new remoting::HeartbeatSender(context.network_message_loop(), + config)); if (!heartbeat_sender->Init()) return 1; - host->AddStatusObserver(heartbeat_sender); + host->AddStatusObserver(heartbeat_sender.get()); } // Let the chromoting host run until the shutdown task is executed. - host->Start(NewRunnableFunction(&ShutdownTask, &message_loop)); + host->Start(); message_loop.MessageLoop::Run(); // And then stop the chromoting context. @@ -234,7 +230,7 @@ class SimpleHost { config_path_ = config_path; } void set_fake(bool fake) { fake_ = fake; } - void set_is_me2mom(bool is_me2mom) { is_me2mom_ = is_me2mom; } + void set_is_it2me(bool is_it2me) { is_it2me_ = is_it2me; } void set_protocol_config(CandidateSessionConfig* protocol_config) { protocol_config_.reset(protocol_config); } @@ -255,7 +251,7 @@ class SimpleHost { FilePath config_path_; bool fake_; - bool is_me2mom_; + bool is_it2me_; scoped_ptr<CandidateSessionConfig> protocol_config_; }; @@ -289,7 +285,7 @@ int main(int argc, char** argv) { cmd_line->GetSwitchValuePath(kConfigSwitchName)); } simple_host.set_fake(cmd_line->HasSwitch(kFakeSwitchName)); - simple_host.set_is_me2mom(cmd_line->HasSwitch(kMe2MomSwitchName)); + simple_host.set_is_it2me(cmd_line->HasSwitch(kIT2MeSwitchName)); if (cmd_line->HasSwitch(kVideoSwitchName)) { string video_codec = cmd_line->GetSwitchValueASCII(kVideoSwitchName); diff --git a/remoting/host/support_access_verifier.cc b/remoting/host/support_access_verifier.cc index 23146ad..d7831b6 100644 --- a/remoting/host/support_access_verifier.cc +++ b/remoting/host/support_access_verifier.cc @@ -41,22 +41,15 @@ std::string GenerateRandomHostSecret() { } // namespace -SupportAccessVerifier::SupportAccessVerifier() - : initialized_(false) { +SupportAccessVerifier::SupportAccessVerifier() { + host_secret_ = GenerateRandomHostSecret(); } SupportAccessVerifier::~SupportAccessVerifier() { } -bool SupportAccessVerifier::Init() { - host_secret_ = GenerateRandomHostSecret(); - initialized_ = true; - return true; -} - bool SupportAccessVerifier::VerifyPermissions( const std::string& client_jid, const std::string& encoded_access_token) { - CHECK(initialized_); if (support_id_.empty()) return false; std::string access_code = support_id_ + "-" + host_secret_; @@ -64,7 +57,7 @@ bool SupportAccessVerifier::VerifyPermissions( client_jid, access_code, encoded_access_token); } -void SupportAccessVerifier::OnMe2MomHostRegistered( +void SupportAccessVerifier::OnIT2MeHostRegistered( bool successful, const std::string& support_id) { if (successful) { support_id_ = support_id; diff --git a/remoting/host/support_access_verifier.h b/remoting/host/support_access_verifier.h index 755700a..b01f93f 100644 --- a/remoting/host/support_access_verifier.h +++ b/remoting/host/support_access_verifier.h @@ -22,7 +22,6 @@ class SupportAccessVerifier : public AccessVerifier { SupportAccessVerifier(); virtual ~SupportAccessVerifier(); - bool Init(); const std::string& host_secret() const { return host_secret_; } // AccessVerifier interface. @@ -30,10 +29,9 @@ class SupportAccessVerifier : public AccessVerifier { const std::string& client_jid, const std::string& encoded_client_token) OVERRIDE; - void OnMe2MomHostRegistered(bool successful, const std::string& support_id); + void OnIT2MeHostRegistered(bool successful, const std::string& support_id); private: - bool initialized_; std::string host_secret_; std::string support_id_; |