summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-20 20:54:47 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-20 20:54:47 +0000
commit970fb675f98ba3f0a243d1f9f0e9ab8b15f7ac45 (patch)
treeb61657e7ada88ee55f40870338c045ae91289afc /remoting
parentef3b6f3ef05e7dec8dab10c82e3cdc44e60c9fc4 (diff)
downloadchromium_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.cc184
-rw-r--r--remoting/host/chromoting_host.h44
-rw-r--r--remoting/host/chromoting_host_unittest.cc38
-rw-r--r--remoting/host/disconnect_window_linux.cc2
-rw-r--r--remoting/host/disconnect_window_mac.mm2
-rw-r--r--remoting/host/disconnect_window_win.cc2
-rw-r--r--remoting/host/heartbeat_sender_unittest.cc6
-rw-r--r--remoting/host/host_plugin.cc323
-rw-r--r--remoting/host/host_status_observer.h10
-rw-r--r--remoting/host/register_support_host_request_unittest.cc2
-rw-r--r--remoting/host/simple_host_process.cc50
-rw-r--r--remoting/host/support_access_verifier.cc13
-rw-r--r--remoting/host/support_access_verifier.h4
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_;