diff options
author | rmsousa@chromium.org <rmsousa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-12 17:10:46 +0000 |
---|---|---|
committer | rmsousa@chromium.org <rmsousa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-12 17:10:46 +0000 |
commit | 8426f3aaa2ba2fe446512c4dbcd7bcf3b4c7eb4a (patch) | |
tree | ce95ef7caeffa717d76574cbd0eb9ba84109c25f /remoting/host | |
parent | f94e0a0bc0bf8d3f55422deb0455d7e7a36cf364 (diff) | |
download | chromium_src-8426f3aaa2ba2fe446512c4dbcd7bcf3b4c7eb4a.zip chromium_src-8426f3aaa2ba2fe446512c4dbcd7bcf3b4c7eb4a.tar.gz chromium_src-8426f3aaa2ba2fe446512c4dbcd7bcf3b4c7eb4a.tar.bz2 |
Add notification when the host successfully starts.
This adds a listener for when first heartbeat is successful, which I think is the best signal that everything is working and the host is able to receive connections.
On Linux, that can send a signal if requested by the caller. On the script side, when running as a daemon, we create a pipe that allows the parent process to wait for that signal (or a permanent failure), and dump all Python log input to the STDERR. This gives users a much better feedback about whether starting the host worked or not.
BUG=179419
Review URL: https://chromiumcodereview.appspot.com/16448005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205837 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host')
-rw-r--r-- | remoting/host/heartbeat_sender.cc | 4 | ||||
-rw-r--r-- | remoting/host/heartbeat_sender.h | 4 | ||||
-rw-r--r-- | remoting/host/heartbeat_sender_unittest.cc | 27 | ||||
-rw-r--r-- | remoting/host/remoting_me2me_host.cc | 24 |
4 files changed, 50 insertions, 9 deletions
diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc index ed000e6..5b6d20b 100644 --- a/remoting/host/heartbeat_sender.cc +++ b/remoting/host/heartbeat_sender.cc @@ -153,6 +153,10 @@ void HeartbeatSender::ProcessResponse(IqRequest* request, return; } + // Notify listener of the first successful heartbeat. + if (!heartbeat_succeeded_) { + listener_->OnHeartbeatSuccessful(); + } heartbeat_succeeded_ = true; // This method must only be called for error or result stanzas. diff --git a/remoting/host/heartbeat_sender.h b/remoting/host/heartbeat_sender.h index c79c863..55d11d3 100644 --- a/remoting/host/heartbeat_sender.h +++ b/remoting/host/heartbeat_sender.h @@ -82,6 +82,10 @@ class HeartbeatSender : public SignalStrategy::Listener { class Listener { public: virtual ~Listener() { } + + // Invoked after the first successful heartbeat. + virtual void OnHeartbeatSuccessful() = 0; + // Invoked when the host ID is permanently not recognized by the server. virtual void OnUnknownHostIdError() = 0; }; diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 9ed8863..2d8cbb3 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc @@ -34,10 +34,23 @@ using testing::SaveArg; namespace remoting { namespace { + const char kTestBotJid[] = "remotingunittest@bot.talk.google.com"; const char kHostId[] = "0"; const char kTestJid[] = "user@gmail.com/chromoting123"; const char kStanzaId[] = "123"; + +class MockListener : public HeartbeatSender::Listener { + public: + // Overridden from HeartbeatSender::Listener + virtual void OnUnknownHostIdError() OVERRIDE { + NOTREACHED(); + } + + // Overridden from HeartbeatSender::Listener + MOCK_METHOD0(OnHeartbeatSuccessful, void()); +}; + } // namespace ACTION_P(AddListener, list) { @@ -49,14 +62,8 @@ ACTION_P(RemoveListener, list) { } class HeartbeatSenderTest - : public testing::Test, - public HeartbeatSender::Listener { + : public testing::Test { protected: - // Overridden from HeartbeatSender::Listener - virtual void OnUnknownHostIdError() OVERRIDE { - NOTREACHED(); - } - virtual void SetUp() OVERRIDE { key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair); ASSERT_TRUE(key_pair_.get()); @@ -71,7 +78,7 @@ class HeartbeatSenderTest .WillRepeatedly(Return(kTestJid)); heartbeat_sender_.reset(new HeartbeatSender( - this, kHostId, &signal_strategy_, key_pair_, kTestBotJid)); + &mock_listener_, kHostId, &signal_strategy_, key_pair_, kTestBotJid)); } virtual void TearDown() OVERRIDE { @@ -84,6 +91,7 @@ class HeartbeatSenderTest base::MessageLoop message_loop_; MockSignalStrategy signal_strategy_; + MockListener mock_listener_; std::set<SignalStrategy::Listener*> signal_strategy_listeners_; scoped_refptr<RsaKeyPair> key_pair_; scoped_ptr<HeartbeatSender> heartbeat_sender_; @@ -174,6 +182,7 @@ TEST_F(HeartbeatSenderTest, DoSendStanzaWithExpectedSequenceId) { .WillOnce(Return(kStanzaId + 1)); EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull())) .WillOnce(DoAll(SaveArg<0>(&sent_iq2), Return(true))); + EXPECT_CALL(mock_listener_, OnHeartbeatSuccessful()); scoped_ptr<XmlElement> response(new XmlElement(buzz::QN_IQ)); response->AddAttr(QName(std::string(), "type"), "result"); @@ -199,6 +208,8 @@ TEST_F(HeartbeatSenderTest, DoSendStanzaWithExpectedSequenceId) { // Verify that ProcessResponse parses set-interval result. TEST_F(HeartbeatSenderTest, ProcessResponseSetInterval) { + EXPECT_CALL(mock_listener_, OnHeartbeatSuccessful()); + scoped_ptr<XmlElement> response(new XmlElement(buzz::QN_IQ)); response->AddAttr(QName(std::string(), "type"), "result"); diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 50b0568..252390a 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -71,6 +71,8 @@ #if defined(OS_POSIX) #include <signal.h> +#include <sys/types.h> +#include <unistd.h> #include "base/file_descriptor_posix.h" #include "remoting/host/pam_authorization_factory_posix.h" #include "remoting/host/posix/signal_handler.h" @@ -103,6 +105,10 @@ const char kApplicationName[] = "chromoting"; // linux. const char kAudioPipeSwitchName[] = "audio-pipe-name"; +// The command line switch used by the parent to request the host to signal it +// when it is successfully started. +const char kSignalParentSwitchName[] = "signal-parent"; + void QuitMessageLoop(base::MessageLoop* message_loop) { message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); } @@ -130,6 +136,7 @@ class HostProcess virtual void OnChannelError() OVERRIDE; // HeartbeatSender::Listener overrides. + virtual void OnHeartbeatSuccessful() OVERRIDE; virtual void OnUnknownHostIdError() OVERRIDE; // HostChangeNotificationListener::Listener overrides. @@ -278,6 +285,7 @@ class HostProcess #endif // defined(REMOTING_MULTI_PROCESS) int* exit_code_out_; + bool signal_parent_; }; HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, @@ -290,7 +298,8 @@ HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, desktop_session_connector_(NULL), #endif // defined(REMOTING_MULTI_PROCESS) self_(this), - exit_code_out_(exit_code_out) { + exit_code_out_(exit_code_out), + signal_parent_(false) { StartOnUiThread(); } @@ -371,6 +380,9 @@ bool HostProcess::InitWithCommandLine(const CommandLine* cmd_line) { } xmpp_server_config_.use_tls = service_urls->xmpp_server_use_tls(); directory_bot_jid_ = service_urls->directory_bot_jid(); + + signal_parent_ = cmd_line->HasSwitch(kSignalParentSwitchName); + return true; } @@ -622,6 +634,16 @@ void HostProcess::OnUnknownHostIdError() { ShutdownHost(kInvalidHostIdExitCode); } +void HostProcess::OnHeartbeatSuccessful() { + LOG(INFO) << "Host ready to receive connections."; +#if defined(OS_POSIX) + if (signal_parent_) { + kill(getppid(), SIGUSR1); + signal_parent_ = false; + } +#endif +} + void HostProcess::OnHostDeleted() { LOG(ERROR) << "Host was deleted from the directory."; ShutdownHost(kInvalidHostIdExitCode); |