diff options
-rw-r--r-- | remoting/host/chromoting_host.cc | 20 | ||||
-rw-r--r-- | remoting/host/chromoting_host.h | 27 | ||||
-rw-r--r-- | remoting/host/chromoting_host_unittest.cc | 97 | ||||
-rw-r--r-- | remoting/host/host_stub_fake.cc | 14 | ||||
-rw-r--r-- | remoting/host/host_stub_fake.h | 8 | ||||
-rw-r--r-- | remoting/protocol/jingle_connection_to_host.cc | 2 | ||||
-rw-r--r-- | remoting/protocol/mock_objects.h | 13 |
7 files changed, 146 insertions, 35 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 21cc126..942a1c0 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -17,7 +17,9 @@ #include "remoting/host/host_config.h" #include "remoting/host/host_stub_fake.h" #include "remoting/host/screen_recorder.h" +#include "remoting/proto/auth.pb.h" #include "remoting/protocol/connection_to_client.h" +#include "remoting/protocol/client_stub.h" #include "remoting/protocol/host_stub.h" #include "remoting/protocol/input_stub.h" #include "remoting/protocol/jingle_session_manager.h" @@ -53,12 +55,12 @@ ChromotingHost::ChromotingHost(ChromotingHostContext* context, config_(config), capturer_(capturer), input_stub_(input_stub), - host_stub_(new HostStubFake()), + ALLOW_THIS_IN_INITIALIZER_LIST( + host_stub_(new HostStubFake(this))), state_(kInitial), protocol_config_(protocol::CandidateSessionConfig::CreateDefault()) { } - ChromotingHost::~ChromotingHost() { } @@ -178,8 +180,6 @@ void ChromotingHost::OnClientConnected(ConnectionToClient* connection) { // Immediately add the connection and start the session. recorder_->AddConnection(connection); - recorder_->Start(); - VLOG(1) << "Session manager started"; } void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { @@ -346,4 +346,16 @@ std::string ChromotingHost::GenerateHostAuthToken( return encoded_client_token; } +void ChromotingHost::LocalLoginSucceeded() { + if (MessageLoop::current() != context_->main_message_loop()) { + context_->main_message_loop()->PostTask( + FROM_HERE, + NewRunnableMethod(this, &ChromotingHost::LocalLoginSucceeded)); + return; + } + + // If local login has succeeded the recorder can start. + recorder_->Start(); +} + } // namespace remoting diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index c99dac2..f0ac438 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -32,6 +32,7 @@ class CandidateSessionConfig; class Capturer; class ChromotingHostContext; class Encoder; +class HostStubFake; class MutableHostConfig; class ScreenRecorder; @@ -50,10 +51,8 @@ class ScreenRecorder; // the screen captures. An InputStub is created and registered with the // ConnectionToClient to receive mouse / keyboard events from the remote // client. -// This is also the right time to create multiple threads to host -// the above objects. After we have done all the initialization -// we'll start the ScreenRecorder. We'll then enter the running state -// of the host process. +// After we have done all the initialization we'll start the ScreenRecorder. +// We'll then enter the running state of the host process. // // 3. When the user is disconnected, we will pause the ScreenRecorder // and try to terminate the threads we have created. This will allow @@ -112,8 +111,18 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // |config| is transferred to the object. Must be called before Start(). void set_protocol_config(protocol::CandidateSessionConfig* config); + // The getter for |host_stub_| is only used in unit test. + protocol::HostStub* host_stub() const { return host_stub_.get(); } + + // This setter is only used in unit test to simulate client connection. + void set_connection(protocol::ConnectionToClient* conn) { + connection_ = conn; + } + private: friend class base::RefCountedThreadSafe<ChromotingHost>; + friend class HostStubFake; + ChromotingHost(ChromotingHostContext* context, MutableHostConfig* config, Capturer* capturer, protocol::InputStub* input_stub); virtual ~ChromotingHost(); @@ -132,6 +141,16 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, std::string GenerateHostAuthToken(const std::string& encoded_client_token); + // Called by HostStub to signal that local login has succeeded and + // ChromotingHost can proceed with the next step. + // This method is only called by HostStubFake. + void LocalLoginSucceeded(); + + // This method is only called by HostStubFake. + protocol::ConnectionToClient* connection_to_client() const { + return connection_; + } + // The context that the chromoting host runs on. ChromotingHostContext* context_; diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index 4710e68..2a4be8c 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -30,6 +30,20 @@ void PostQuitTask(MessageLoop* message_loop) { message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); } +void BeginSessionRequest(protocol::HostStub* host_stub) { + protocol::LocalLoginCredentials* credentials = + new protocol::LocalLoginCredentials(); + credentials->set_type(protocol::PASSWORD); + credentials->set_username("hello"); + + const std::string password = "world!"; + credentials->set_credential(password.data(), password.length()); + + host_stub->BeginSessionRequest( + credentials, + new DeleteTask<protocol::LocalLoginCredentials>(credentials)); +} + // Run the task and delete it afterwards. This action is used to deal with // done callbacks. ACTION(RunDoneTask) { @@ -70,24 +84,45 @@ class ChromotingHostTest : public testing::Test { session_ = new protocol::MockSession(); session_config_.reset(protocol::SessionConfig::CreateDefault()); + ON_CALL(video_stub_, ProcessVideoPacket(_, _)) + .WillByDefault( + DoAll(DeleteArg<0>(), DeleteArg<1>())); ON_CALL(*connection_.get(), video_stub()) .WillByDefault(Return(&video_stub_)); + ON_CALL(*connection_.get(), client_stub()) + .WillByDefault(Return(&client_stub_)); ON_CALL(*connection_.get(), session()) .WillByDefault(Return(session_)); ON_CALL(*session_.get(), config()) .WillByDefault(Return(session_config_.get())); + EXPECT_CALL(*connection_.get(), video_stub()) + .Times(AnyNumber()); + EXPECT_CALL(*connection_.get(), client_stub()) + .Times(AnyNumber()); + EXPECT_CALL(*connection_.get(), session()) + .Times(AnyNumber()); + EXPECT_CALL(*session_.get(), config()) + .Times(AnyNumber()); } virtual void TearDown() { } // Helper metjod to pretend a client is connected to ChromotingHost. - void InjectClientConnection() { + void SimulateClientConnection() { + context_.network_message_loop()->PostTask( + FROM_HERE, + NewRunnableMethod(host_.get(), + &ChromotingHost::set_connection, + connection_)); context_.network_message_loop()->PostTask( FROM_HERE, NewRunnableMethod(host_.get(), - &ChromotingHost::OnConnectionOpened, + &ChromotingHost::OnClientConnected, connection_)); + context_.network_message_loop()->PostTask( + FROM_HERE, + NewRunnableFunction(&BeginSessionRequest, host_->host_stub())); } // Helper method to remove a client connection from ChromotongHost. @@ -95,7 +130,7 @@ class ChromotingHostTest : public testing::Test { context_.network_message_loop()->PostTask( FROM_HERE, NewRunnableMethod(host_.get(), - &ChromotingHost::OnConnectionClosed, + &ChromotingHost::OnClientDisconnected, connection_)); } @@ -108,6 +143,7 @@ class ChromotingHostTest : public testing::Test { scoped_refptr<protocol::MockSession> session_; scoped_ptr<protocol::SessionConfig> session_config_; protocol::MockVideoStub video_stub_; + protocol::MockClientStub client_stub_; protocol::MockInputStub* input_stub_; }; @@ -123,9 +159,8 @@ TEST_F(ChromotingHostTest, StartAndShutdown) { TEST_F(ChromotingHostTest, Connect) { host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); - ON_CALL(video_stub_, ProcessVideoPacket(_, _)) - .WillByDefault( - DoAll(DeleteArg<0>(), DeleteArg<1>())); + EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) + .WillOnce(RunDoneTask()); // When the video packet is received we first shutdown ChromotingHost // then execute the done task. @@ -137,47 +172,57 @@ TEST_F(ChromotingHostTest, Connect) { .RetiresOnSaturation(); EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) .Times(AnyNumber()); + EXPECT_CALL(*connection_.get(), Disconnect()) + .RetiresOnSaturation(); - InjectClientConnection(); + SimulateClientConnection(); message_loop_.Run(); } TEST_F(ChromotingHostTest, Reconnect) { host_->Start(NewRunnableFunction(&PostQuitTask, &message_loop_)); - ON_CALL(video_stub_, ProcessVideoPacket(_, _)) - .WillByDefault( - DoAll(DeleteArg<0>(), DeleteArg<1>())); + EXPECT_CALL(client_stub_, BeginSessionResponse(_, _)) + .Times(2) + .WillRepeatedly(RunDoneTask()); // When the video packet is received we first disconnect the mock // connection. - InSequence s; - EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) - .WillOnce(DoAll( - InvokeWithoutArgs(this, &ChromotingHostTest::RemoveClientConnection), - RunDoneTask())) - .RetiresOnSaturation(); - EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) - .Times(AnyNumber()); + { + InSequence s; + EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) + .WillOnce(DoAll( + InvokeWithoutArgs(this, + &ChromotingHostTest::RemoveClientConnection), + RunDoneTask())) + .RetiresOnSaturation(); + EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) + .Times(AnyNumber()); + } // If Disconnect() is called we can break the main message loop. EXPECT_CALL(*connection_.get(), Disconnect()) .WillOnce(QuitMainMessageLoop(&message_loop_)) .RetiresOnSaturation(); - InjectClientConnection(); + SimulateClientConnection(); message_loop_.Run(); // Connect the client again. - EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) - .WillOnce(DoAll( - InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), - RunDoneTask())) + { + InSequence s; + EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) + .WillOnce(DoAll( + InvokeWithoutArgs(host_.get(), &ChromotingHost::Shutdown), + RunDoneTask())) + .RetiresOnSaturation(); + EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) + .Times(AnyNumber()); + } + EXPECT_CALL(*connection_.get(), Disconnect()) .RetiresOnSaturation(); - EXPECT_CALL(video_stub_, ProcessVideoPacket(_, _)) - .Times(AnyNumber()); - InjectClientConnection(); + SimulateClientConnection(); message_loop_.Run(); } diff --git a/remoting/host/host_stub_fake.cc b/remoting/host/host_stub_fake.cc index 2e3fc76..895b21a 100644 --- a/remoting/host/host_stub_fake.cc +++ b/remoting/host/host_stub_fake.cc @@ -3,10 +3,18 @@ // found in the LICENSE file. #include "base/task.h" +#include "remoting/host/chromoting_host.h" #include "remoting/host/host_stub_fake.h" +#include "remoting/proto/auth.pb.h" +#include "remoting/protocol/client_stub.h" +#include "remoting/protocol/connection_to_client.h" namespace remoting { +HostStubFake::HostStubFake(ChromotingHost* host) + : host_(host) { +} + void HostStubFake::SuggestResolution( const protocol::SuggestResolutionRequest* msg, Task* done) { done->Run(); @@ -17,6 +25,12 @@ void HostStubFake::BeginSessionRequest( const protocol::LocalLoginCredentials* credentials, Task* done) { done->Run(); delete done; + + protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); + status->set_success(true); + host_->connection_to_client()->client_stub()->BeginSessionResponse( + status, new DeleteTask<protocol::LocalLoginStatus>(status)); + host_->LocalLoginSucceeded(); } } // namespace remoting diff --git a/remoting/host/host_stub_fake.h b/remoting/host/host_stub_fake.h index 218e15d..7dc579e 100644 --- a/remoting/host/host_stub_fake.h +++ b/remoting/host/host_stub_fake.h @@ -8,13 +8,17 @@ #define REMOTING_PROTOCOL_HOST_STUB_FAKE_H_ #include "base/basictypes.h" +#include "base/callback.h" +#include "base/scoped_ptr.h" #include "remoting/protocol/host_stub.h" namespace remoting { +class ChromotingHost; + class HostStubFake : public protocol::HostStub { public: - HostStubFake() {} + HostStubFake(ChromotingHost* host); virtual ~HostStubFake() {} virtual void SuggestResolution( @@ -23,6 +27,8 @@ class HostStubFake : public protocol::HostStub { const protocol::LocalLoginCredentials* credentials, Task* done); private: + ChromotingHost* host_; + DISALLOW_COPY_AND_ASSIGN(HostStubFake); }; diff --git a/remoting/protocol/jingle_connection_to_host.cc b/remoting/protocol/jingle_connection_to_host.cc index f680012..6d4b256 100644 --- a/remoting/protocol/jingle_connection_to_host.cc +++ b/remoting/protocol/jingle_connection_to_host.cc @@ -11,6 +11,7 @@ #include "remoting/proto/auth.pb.h" #include "remoting/protocol/client_message_dispatcher.h" #include "remoting/protocol/client_stub.h" +#include "remoting/protocol/host_control_sender.h" #include "remoting/protocol/input_sender.h" #include "remoting/protocol/jingle_session_manager.h" #include "remoting/protocol/video_reader.h" @@ -164,6 +165,7 @@ void JingleConnectionToHost::OnSessionStateChange( video_reader_.reset(VideoReader::Create(session_->config())); video_reader_->Init(session_, video_stub_); input_stub_.reset(new InputSender(session_->event_channel())); + host_stub_.reset(new HostControlSender(session_->control_channel())); dispatcher_->Initialize(session_.get(), client_stub_); event_callback_->OnConnectionOpened(this); break; diff --git a/remoting/protocol/mock_objects.h b/remoting/protocol/mock_objects.h index 99826c2..c1535d1 100644 --- a/remoting/protocol/mock_objects.h +++ b/remoting/protocol/mock_objects.h @@ -70,6 +70,19 @@ class MockHostStub : public HostStub { DISALLOW_COPY_AND_ASSIGN(MockHostStub); }; +class MockClientStub : public ClientStub { + public: + MockClientStub() {} + + MOCK_METHOD2(NotifyResolution, void(const NotifyResolutionRequest* msg, + Task* done)); + MOCK_METHOD2(BeginSessionResponse, void(const LocalLoginStatus* msg, + Task* done)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockClientStub); +}; + class MockVideoStub : public VideoStub { public: MockVideoStub() {} |