summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-20 19:32:45 +0000
committerjamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-20 19:32:45 +0000
commit35c14eeb34ca5f21b70a388e868ff3968545812f (patch)
tree70d4fb062c1d406ac4f22bb0bd577fd5d503a04b
parent0b711e4718b64621ee2cdf5c5de597a53d1b2b07 (diff)
downloadchromium_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.cc61
-rw-r--r--remoting/host/chromoting_host.h17
-rw-r--r--remoting/host/client_session.cc34
-rw-r--r--remoting/host/client_session.h13
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);
};