Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: remoting/host/client_session.cc

Issue 9465035: Move ClientSession's input logic into separate components. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/client_session.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/client_session.h" 5 #include "remoting/host/client_session.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/message_loop_proxy.h" 9 #include "base/message_loop_proxy.h"
10 #include "remoting/host/capturer.h" 10 #include "remoting/host/capturer.h"
(...skipping 15 matching lines...) Expand all
26 using protocol::MouseEvent; 26 using protocol::MouseEvent;
27 27
28 ClientSession::ClientSession( 28 ClientSession::ClientSession(
29 EventHandler* event_handler, 29 EventHandler* event_handler,
30 protocol::ConnectionToClient* connection, 30 protocol::ConnectionToClient* connection,
31 protocol::InputStub* input_stub, 31 protocol::InputStub* input_stub,
32 Capturer* capturer) 32 Capturer* capturer)
33 : event_handler_(event_handler), 33 : event_handler_(event_handler),
34 connection_(connection), 34 connection_(connection),
35 client_jid_(connection->session()->jid()), 35 client_jid_(connection->session()->jid()),
36 input_stub_(input_stub), 36 key_tracker_(input_stub),
37 capturer_(capturer), 37 capturer_(capturer),
38 authenticated_(false), 38 authenticated_(false),
39 awaiting_continue_approval_(false), 39 awaiting_continue_approval_(false),
40 remote_mouse_button_state_(0) { 40 remote_mouse_button_state_(0) {
41 connection_->SetEventHandler(this); 41 connection_->SetEventHandler(this);
42 42
43 // TODO(sergeyu): Currently ConnectionToClient expects stubs to be 43 // TODO(sergeyu): Currently ConnectionToClient expects stubs to be
44 // set before channels are connected. Make it possible to set stubs 44 // set before channels are connected. Make it possible to set stubs
45 // later and set them only when connection is authenticated. 45 // later and set them only when connection is authenticated.
46 connection_->set_host_stub(this); 46 connection_->set_host_stub(this);
47 connection_->set_input_stub(this); 47 connection_->set_input_stub(this);
48 } 48 }
49 49
50 ClientSession::~ClientSession() { 50 ClientSession::~ClientSession() {
51 } 51 }
52 52
53 void ClientSession::InjectKeyEvent(const KeyEvent& event) { 53 void ClientSession::InjectKeyEvent(const KeyEvent& event) {
54 DCHECK(CalledOnValidThread()); 54 DCHECK(CalledOnValidThread());
55 55
56 if (authenticated_ && !ShouldIgnoreRemoteKeyboardInput(event)) { 56 if (!authenticated_)
57 RecordKeyEvent(event); 57 return;
58 input_stub_->InjectKeyEvent(event); 58 if (ShouldIgnoreRemoteKeyboardInput(event))
59 } 59 return;
60
61 key_tracker_.InjectKeyEvent(event);
60 } 62 }
61 63
62 void ClientSession::InjectMouseEvent(const MouseEvent& event) { 64 void ClientSession::InjectMouseEvent(const MouseEvent& event) {
63 DCHECK(CalledOnValidThread()); 65 DCHECK(CalledOnValidThread());
64 66
65 if (authenticated_ && !ShouldIgnoreRemoteMouseInput(event)) { 67 if (!authenticated_)
66 RecordMouseButtonState(event); 68 return;
67 MouseEvent event_to_inject = event; 69 if (ShouldIgnoreRemoteMouseInput(event))
68 if (event.has_x() && event.has_y()) { 70 return;
69 // In case the client sends events with off-screen coordinates, modify
70 // the event to lie within the current screen area. This is better than
71 // simply discarding the event, which might lose a button-up event at the
72 // end of a drag'n'drop (or cause other related problems).
73 SkIPoint pos(SkIPoint::Make(event.x(), event.y()));
74 const SkISize& screen = capturer_->size_most_recent();
75 pos.setX(std::max(0, std::min(screen.width() - 1, pos.x())));
76 pos.setY(std::max(0, std::min(screen.height() - 1, pos.y())));
77 event_to_inject.set_x(pos.x());
78 event_to_inject.set_y(pos.y());
79 71
80 // Record the mouse position so we can use it if we need to inject 72 RecordMouseButtonState(event);
81 // fake mouse button events. Note that we need to do this after we 73 MouseEvent event_to_inject = event;
82 // clamp the values to the screen area. 74 if (event.has_x() && event.has_y()) {
83 remote_mouse_pos_ = pos; 75 // In case the client sends events with off-screen coordinates, modify
76 // the event to lie within the current screen area. This is better than
77 // simply discarding the event, which might lose a button-up event at the
78 // end of a drag'n'drop (or cause other related problems).
79 SkIPoint pos(SkIPoint::Make(event.x(), event.y()));
80 const SkISize& screen = capturer_->size_most_recent();
81 pos.setX(std::max(0, std::min(screen.width() - 1, pos.x())));
82 pos.setY(std::max(0, std::min(screen.height() - 1, pos.y())));
83 event_to_inject.set_x(pos.x());
84 event_to_inject.set_y(pos.y());
84 85
85 injected_mouse_positions_.push_back(pos); 86 // Record the mouse position so we can use it if we need to inject
86 if (injected_mouse_positions_.size() > kNumRemoteMousePositions) { 87 // fake mouse button events. Note that we need to do this after we
87 VLOG(1) << "Injected mouse positions queue full."; 88 // clamp the values to the screen area.
88 injected_mouse_positions_.pop_front(); 89 remote_mouse_pos_ = pos;
89 } 90
91 injected_mouse_positions_.push_back(pos);
92 if (injected_mouse_positions_.size() > kNumRemoteMousePositions) {
93 VLOG(1) << "Injected mouse positions queue full.";
94 injected_mouse_positions_.pop_front();
90 } 95 }
91 input_stub_->InjectMouseEvent(event_to_inject);
92 } 96 }
97 key_tracker_.InjectMouseEvent(event_to_inject);
93 } 98 }
94 99
95 void ClientSession::OnConnectionOpened( 100 void ClientSession::OnConnectionOpened(
96 protocol::ConnectionToClient* connection) { 101 protocol::ConnectionToClient* connection) {
97 DCHECK(CalledOnValidThread()); 102 DCHECK(CalledOnValidThread());
98 DCHECK_EQ(connection_.get(), connection); 103 DCHECK_EQ(connection_.get(), connection);
99 authenticated_ = true; 104 authenticated_ = true;
100 event_handler_->OnSessionAuthenticated(this); 105 event_handler_->OnSessionAuthenticated(this);
101 } 106 }
102 107
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 } 199 }
195 200
196 bool ClientSession::ShouldIgnoreRemoteKeyboardInput( 201 bool ClientSession::ShouldIgnoreRemoteKeyboardInput(
197 const KeyEvent& event) const { 202 const KeyEvent& event) const {
198 DCHECK(CalledOnValidThread()); 203 DCHECK(CalledOnValidThread());
199 204
200 // If the host user has not yet approved the continuation of the connection, 205 // If the host user has not yet approved the continuation of the connection,
201 // then all remote keyboard input is ignored, except to release keys that 206 // then all remote keyboard input is ignored, except to release keys that
202 // were already pressed. 207 // were already pressed.
203 if (awaiting_continue_approval_) { 208 if (awaiting_continue_approval_) {
204 return event.pressed() || 209 return event.pressed();
205 (pressed_keys_.find(event.keycode()) == pressed_keys_.end());
Wez 2012/02/27 18:59:04 Removing this actually fixes the client-side repea
Jamie 2012/02/27 19:39:14 How? This code only runs if the continue dialog is
Wez 2012/02/27 20:01:21 You're right; confused myself by splitting the fix
206 } 210 }
207 return false; 211 return false;
208 } 212 }
209 213
210 void ClientSession::RecordKeyEvent(const KeyEvent& event) {
211 DCHECK(CalledOnValidThread());
212
213 if (event.pressed()) {
214 pressed_keys_.insert(event.keycode());
215 } else {
216 pressed_keys_.erase(event.keycode());
217 }
218 }
219
220 void ClientSession::RecordMouseButtonState(const MouseEvent& event) { 214 void ClientSession::RecordMouseButtonState(const MouseEvent& event) {
221 DCHECK(CalledOnValidThread()); 215 DCHECK(CalledOnValidThread());
222 216
223 if (event.has_button() && event.has_button_down()) { 217 if (event.has_button() && event.has_button_down()) {
224 // Button values are defined in remoting/proto/event.proto. 218 // Button values are defined in remoting/proto/event.proto.
225 if (event.button() >= 1 && event.button() < MouseEvent::BUTTON_MAX) { 219 if (event.button() >= 1 && event.button() < MouseEvent::BUTTON_MAX) {
226 uint32 button_change = 1 << (event.button() - 1); 220 uint32 button_change = 1 << (event.button() - 1);
227 if (event.button_down()) { 221 if (event.button_down()) {
228 remote_mouse_button_state_ |= button_change; 222 remote_mouse_button_state_ |= button_change;
229 } else { 223 } else {
230 remote_mouse_button_state_ &= ~button_change; 224 remote_mouse_button_state_ &= ~button_change;
231 } 225 }
232 } 226 }
233 } 227 }
234 } 228 }
235 229
236 void ClientSession::RestoreEventState() { 230 void ClientSession::RestoreEventState() {
237 DCHECK(CalledOnValidThread()); 231 DCHECK(CalledOnValidThread());
238 232
239 // Undo any currently pressed keys. 233 // Undo any currently pressed keys.
240 std::set<int>::iterator i; 234 key_tracker_.ReleaseAllKeys();
241 for (i = pressed_keys_.begin(); i != pressed_keys_.end(); ++i) {
242 KeyEvent key;
243 key.set_keycode(*i);
244 key.set_pressed(false);
245 input_stub_->InjectKeyEvent(key);
246 }
247 pressed_keys_.clear();
248 235
249 // Undo any currently pressed mouse buttons. 236 // Undo any currently pressed mouse buttons.
250 for (int i = 1; i < MouseEvent::BUTTON_MAX; i++) { 237 for (int i = 1; i < MouseEvent::BUTTON_MAX; i++) {
251 if (remote_mouse_button_state_ & (1 << (i - 1))) { 238 if (remote_mouse_button_state_ & (1 << (i - 1))) {
252 MouseEvent mouse; 239 MouseEvent mouse;
253 // TODO(wez): Shouldn't [need to] set position here. 240 // TODO(wez): Shouldn't [need to] set position here.
254 mouse.set_x(remote_mouse_pos_.x()); 241 mouse.set_x(remote_mouse_pos_.x());
255 mouse.set_y(remote_mouse_pos_.y()); 242 mouse.set_y(remote_mouse_pos_.y());
256 mouse.set_button((MouseEvent::MouseButton)i); 243 mouse.set_button((MouseEvent::MouseButton)i);
257 mouse.set_button_down(false); 244 mouse.set_button_down(false);
258 input_stub_->InjectMouseEvent(mouse); 245 key_tracker_.InjectMouseEvent(mouse);
259 } 246 }
260 } 247 }
261 remote_mouse_button_state_ = 0; 248 remote_mouse_button_state_ = 0;
262 } 249 }
263 250
264 } // namespace remoting 251 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/client_session.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698