summaryrefslogtreecommitdiffstats
path: root/remoting/host
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/host')
-rw-r--r--remoting/host/heartbeat_sender.cc4
-rw-r--r--remoting/host/heartbeat_sender.h4
-rw-r--r--remoting/host/heartbeat_sender_unittest.cc27
-rw-r--r--remoting/host/remoting_me2me_host.cc24
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);