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
3 // found in the LICENSE file.
5 #include "remoting/host/remote_input_filter.h"
7 #include "base/logging.h"
8 #include "remoting/proto/event.pb.h"
12 // The number of remote mouse events to record for the purpose of eliminating
13 // "echoes" detected by the local input detector. The value should be large
14 // enough to cope with the fact that multiple events might be injected before
15 // any echoes are detected.
16 const unsigned int kNumRemoteMousePositions
= 50;
18 // The number of milliseconds for which to block remote input when local input
20 const int64 kRemoteBlockTimeoutMillis
= 2000;
26 RemoteInputFilter::RemoteInputFilter(protocol::InputEventTracker
* event_tracker
)
27 : event_tracker_(event_tracker
),
28 expect_local_echo_(true) {
31 RemoteInputFilter::~RemoteInputFilter() {
34 void RemoteInputFilter::LocalMouseMoved(
35 const webrtc::DesktopVector
& mouse_pos
) {
36 // If this is a genuine local input event (rather than an echo of a remote
37 // input event that we've just injected), then ignore remote inputs for a
39 if (expect_local_echo_
) {
40 std::list
<webrtc::DesktopVector
>::iterator found_position
=
41 injected_mouse_positions_
.begin();
42 while (found_position
!= injected_mouse_positions_
.end() &&
43 !mouse_pos
.equals(*found_position
)) {
46 if (found_position
!= injected_mouse_positions_
.end()) {
47 // Remove it from the list, and any positions that were added before it,
48 // if any. This is because the local input monitor is assumed to receive
49 // injected mouse position events in the order in which they were injected
50 // (if at all). If the position is found somewhere other than the front
51 // of the queue, this would be because the earlier positions weren't
52 // successfully injected (or the local input monitor might have skipped
53 // over some positions), and not because the events were out-of-sequence.
54 // These spurious positions should therefore be discarded.
55 injected_mouse_positions_
.erase(injected_mouse_positions_
.begin(),
61 // Release all pressed buttons or keys, disable inputs, and note the time.
62 event_tracker_
->ReleaseAll();
63 latest_local_input_time_
= base::TimeTicks::Now();
66 void RemoteInputFilter::SetExpectLocalEcho(bool expect_local_echo
) {
67 expect_local_echo_
= expect_local_echo
;
68 if (!expect_local_echo_
)
69 injected_mouse_positions_
.clear();
72 void RemoteInputFilter::InjectKeyEvent(const protocol::KeyEvent
& event
) {
73 if (ShouldIgnoreInput())
75 event_tracker_
->InjectKeyEvent(event
);
78 void RemoteInputFilter::InjectTextEvent(const protocol::TextEvent
& event
) {
79 if (ShouldIgnoreInput())
81 event_tracker_
->InjectTextEvent(event
);
84 void RemoteInputFilter::InjectMouseEvent(const protocol::MouseEvent
& event
) {
85 if (ShouldIgnoreInput())
87 if (expect_local_echo_
&& event
.has_x() && event
.has_y()) {
88 injected_mouse_positions_
.push_back(
89 webrtc::DesktopVector(event
.x(), event
.y()));
90 if (injected_mouse_positions_
.size() > kNumRemoteMousePositions
) {
91 VLOG(1) << "Injected mouse positions queue full.";
92 injected_mouse_positions_
.pop_front();
95 event_tracker_
->InjectMouseEvent(event
);
98 void RemoteInputFilter::InjectTouchEvent(const protocol::TouchEvent
& event
) {
99 if (ShouldIgnoreInput())
101 event_tracker_
->InjectTouchEvent(event
);
104 bool RemoteInputFilter::ShouldIgnoreInput() const {
105 // Ignore remote events if the local mouse moved recently.
107 (base::TimeTicks::Now() - latest_local_input_time_
).InMilliseconds();
108 if (millis
< kRemoteBlockTimeoutMillis
)
113 } // namespace remoting