diff options
author | jamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-20 19:32:45 +0000 |
---|---|---|
committer | jamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-20 19:32:45 +0000 |
commit | 35c14eeb34ca5f21b70a388e868ff3968545812f (patch) | |
tree | 70d4fb062c1d406ac4f22bb0bd577fd5d503a04b | |
parent | 0b711e4718b64621ee2cdf5c5de597a53d1b2b07 (diff) | |
download | chromium_src-35c14eeb34ca5f21b70a388e868ff3968545812f.zip chromium_src-35c14eeb34ca5f21b70a388e868ff3968545812f.tar.gz chromium_src-35c14eeb34ca5f21b70a388e868ff3968545812f.tar.bz2 |
Completed basic implementation.
BUG=None
TEST=Manual
Review URL: http://codereview.chromium.org/7200009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89714 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | remoting/host/chromoting_host.cc | 61 | ||||
-rw-r--r-- | remoting/host/chromoting_host.h | 17 | ||||
-rw-r--r-- | remoting/host/client_session.cc | 34 | ||||
-rw-r--r-- | remoting/host/client_session.h | 13 |
4 files changed, 119 insertions, 6 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 457072d..1b2a488 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -32,6 +32,8 @@ using remoting::protocol::ConnectionToClient; using remoting::protocol::InputStub; +static const int kContinueWindowTimeoutSecs = 5 * 60; + namespace remoting { // static @@ -363,6 +365,22 @@ void ChromotingHost::LocalMouseMoved(const gfx::Point& new_pos) { } } +void ChromotingHost::PauseSession(bool pause) { + if (context_->main_message_loop() != MessageLoop::current()) { + context_->main_message_loop()->PostTask( + FROM_HERE, + NewRunnableMethod(this, + &ChromotingHost::PauseSession, + pause)); + return; + } + ClientList::iterator client; + for (client = clients_.begin(); client != clients_.end(); ++client) { + client->get()->set_awaiting_continue_approval(pause); + } + StartContinueWindowTimer(!pause); +} + void ChromotingHost::OnServerClosed() { // Don't need to do anything here. } @@ -402,6 +420,8 @@ void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { if (is_me2mom_) { MonitorLocalInputs(false); ShowDisconnectWindow(false, std::string()); + ShowContinueWindow(false); + StartContinueWindowTimer(false); } } } @@ -517,6 +537,7 @@ void ChromotingHost::LocalLoginSucceeded( if (pos != std::string::npos) username.replace(pos, std::string::npos, ""); ShowDisconnectWindow(true, username); + StartContinueWindowTimer(true); } } @@ -565,4 +586,44 @@ void ChromotingHost::ShowDisconnectWindow(bool show, } } +void ChromotingHost::ShowContinueWindow(bool show) { + if (context_->ui_message_loop() != MessageLoop::current()) { + context_->ui_message_loop()->PostTask( + FROM_HERE, + NewRunnableMethod(this, &ChromotingHost::ShowContinueWindow, show)); + return; + } + + if (show) { + desktop_environment_->continue_window()->Show(this); + } else { + desktop_environment_->continue_window()->Hide(); + } +} + +void ChromotingHost::StartContinueWindowTimer(bool start) { + if (context_->main_message_loop() != MessageLoop::current()) { + context_->main_message_loop()->PostTask( + FROM_HERE, + NewRunnableMethod(this, + &ChromotingHost::StartContinueWindowTimer, + start)); + return; + } + if (continue_window_timer_.IsRunning() == start) + return; + if (start) { + continue_window_timer_.Start( + base::TimeDelta::FromSeconds(kContinueWindowTimeoutSecs), + this, &ChromotingHost::ContinueWindowTimerFunc); + } else { + continue_window_timer_.Stop(); + } +} + +void ChromotingHost::ContinueWindowTimerFunc() { + PauseSession(true); + ShowContinueWindow(true); +} + } // namespace remoting diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index c05b06d..c4b07b2 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/threading/thread.h" +#include "base/timer.h" #include "remoting/base/encoder.h" #include "remoting/host/access_verifier.h" #include "remoting/host/capturer.h" @@ -132,6 +133,10 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // that remote input should be ignored for a short time. void LocalMouseMoved(const gfx::Point& new_pos); + // Pause or unpause the session. While the session is paused, remote input + // is ignored. + void PauseSession(bool pause); + private: friend class base::RefCountedThreadSafe<ChromotingHost>; friend class ChromotingHostTest; @@ -177,6 +182,13 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // hide the window, ignoring the |username| parameter. void ShowDisconnectWindow(bool show, const std::string& username); + // Show or hide the Continue Sharing window on the UI thread. + void ShowContinueWindow(bool show); + + void StartContinueWindowTimer(bool start); + + void ContinueWindowTimerFunc(); + // The context that the chromoting host runs on. ChromotingHostContext* context_; @@ -220,6 +232,11 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, bool is_curtained_; bool is_monitoring_local_inputs_; + // Timer controlling the "continue session" dialog. The timer is started when + // a connection is made or re-confirmed. On expiry, inputs to the host are + // 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 // are pre-authenticated, and hence the local login challenge can be bypassed. bool is_me2mom_; diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index 0ebd0c5..8718429 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -31,6 +31,7 @@ ClientSession::ClientSession( connection_(connection), input_stub_(input_stub), authenticated_(false), + awaiting_continue_approval_(false), remote_mouse_button_state_(0) { } @@ -82,7 +83,12 @@ void ClientSession::OnAuthorizationComplete(bool success) { void ClientSession::InjectKeyEvent(const protocol::KeyEvent* event, Task* done) { base::ScopedTaskRunner done_runner(done); - if (authenticated_) { + if (authenticated_ && !ShouldIgnoreRemoteKeyboardInput(event)) { + if (event->pressed()) { + pressed_keys_.insert(event->keycode()); + } else { + pressed_keys_.erase(event->keycode()); + } input_stub_->InjectKeyEvent(event, done_runner.Release()); } } @@ -90,7 +96,7 @@ void ClientSession::InjectKeyEvent(const protocol::KeyEvent* event, void ClientSession::InjectMouseEvent(const protocol::MouseEvent* event, Task* done) { base::ScopedTaskRunner done_runner(done); - if (authenticated_ && !ShouldIgnoreRemoteInput()) { + if (authenticated_ && !ShouldIgnoreRemoteMouseInput(event)) { if (event->has_button() && event->has_button_down()) { if (event->button() >= 1 && event->button() < 32) { uint32 button_change = 1 << (event->button() - 1); @@ -129,12 +135,18 @@ void ClientSession::LocalMouseMoved(const gfx::Point& mouse_pos) { } } -bool ClientSession::ShouldIgnoreRemoteInput() const { +bool ClientSession::ShouldIgnoreRemoteMouseInput( + const protocol::MouseEvent* event) const { // If the last remote input event was a click or a drag, then it's not safe - // to block remote input. For example, it might result in the host missing - // the mouse-up event and being stuck with the button pressed. + // to block remote mouse events. For example, it might result in the host + // missing the mouse-up event and being stuck with the button pressed. if (remote_mouse_button_state_ != 0) return false; + // Otherwise, if the host user has not yet approved the continuation of the + // connection, then ignore remote mouse events. + if (awaiting_continue_approval_) + return true; + // Otherwise, ignore remote mouse events if the local mouse moved recently. int64 millis = (base::Time::Now() - latest_local_input_time_) .InMilliseconds(); if (millis < kRemoteBlockTimeoutMillis) @@ -142,4 +154,16 @@ bool ClientSession::ShouldIgnoreRemoteInput() const { return false; } +bool ClientSession::ShouldIgnoreRemoteKeyboardInput( + const protocol::KeyEvent* event) const { + // If the host user has not yet approved the continuation of the connection, + // then all remote keyboard input is ignored, except to release keys that + // were already pressed. + if (awaiting_continue_approval_) { + return event->pressed() || + (pressed_keys_.find(event->keycode()) == pressed_keys_.end()); + } + return false; +} + } // namespace remoting diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index e014bdc..17dbe9b 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h @@ -6,6 +6,7 @@ #define REMOTING_HOST_CLIENT_SESSION_H_ #include <list> +#include <set> #include "remoting/protocol/connection_to_client.h" #include "remoting/protocol/host_stub.h" @@ -68,12 +69,17 @@ class ClientSession : public protocol::HostStub, return authenticated_; } + void set_awaiting_continue_approval(bool awaiting) { + awaiting_continue_approval_ = awaiting; + } + // Indicate that local mouse activity has been detected. This causes remote // inputs to be ignored for a short time so that the local user will always // have the upper hand in 'pointer wars'. void LocalMouseMoved(const gfx::Point& new_pos); - bool ShouldIgnoreRemoteInput() const; + bool ShouldIgnoreRemoteMouseInput(const protocol::MouseEvent* event) const; + bool ShouldIgnoreRemoteKeyboardInput(const protocol::KeyEvent* event) const; private: friend class base::RefCountedThreadSafe<ClientSession>; @@ -93,10 +99,15 @@ class ClientSession : public protocol::HostStub, // Whether this client is authenticated. bool authenticated_; + // Whether or not inputs from this client are blocked pending approval from + // the host user to continue the connection. + bool awaiting_continue_approval_; + // State to control remote input blocking while the local pointer is in use. uint32 remote_mouse_button_state_; std::list<gfx::Point> recent_remote_mouse_positions_; base::Time latest_local_input_time_; + std::set<int> pressed_keys_; DISALLOW_COPY_AND_ASSIGN(ClientSession); }; |