MD Downloads: prevent search text from overlapping with the cancel search (X)
[chromium-blink-merge.git] / remoting / host / remote_input_filter.cc
blob3201431f49423f0e9146ac59b77efd8b423693a9
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"
10 namespace {
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
19 // is received.
20 const int64 kRemoteBlockTimeoutMillis = 2000;
22 } // namespace
24 namespace remoting {
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
38 // short time.
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)) {
44 ++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(),
56 ++found_position);
57 return;
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())
74 return;
75 event_tracker_->InjectKeyEvent(event);
78 void RemoteInputFilter::InjectTextEvent(const protocol::TextEvent& event) {
79 if (ShouldIgnoreInput())
80 return;
81 event_tracker_->InjectTextEvent(event);
84 void RemoteInputFilter::InjectMouseEvent(const protocol::MouseEvent& event) {
85 if (ShouldIgnoreInput())
86 return;
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())
100 return;
101 event_tracker_->InjectTouchEvent(event);
104 bool RemoteInputFilter::ShouldIgnoreInput() const {
105 // Ignore remote events if the local mouse moved recently.
106 int64 millis =
107 (base::TimeTicks::Now() - latest_local_input_time_).InMilliseconds();
108 if (millis < kRemoteBlockTimeoutMillis)
109 return true;
110 return false;
113 } // namespace remoting