OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "remoting/host/remote_input_filter.h" |
| 6 |
| 7 #include <algorithm> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "remoting/proto/event.pb.h" |
| 11 |
| 12 namespace { |
| 13 |
| 14 // The number of remote mouse events to record for the purpose of eliminating |
| 15 // "echoes" detected by the local input detector. The value should be large |
| 16 // enough to cope with the fact that multiple events might be injected before |
| 17 // any echoes are detected. |
| 18 const unsigned int kNumRemoteMousePositions = 50; |
| 19 |
| 20 // The number of milliseconds for which to block remote input when local input |
| 21 // is received. |
| 22 const int64 kRemoteBlockTimeoutMillis = 2000; |
| 23 |
| 24 } // namespace |
| 25 |
| 26 namespace remoting { |
| 27 |
| 28 RemoteInputFilter::RemoteInputFilter(protocol::InputEventTracker* event_tracker) |
| 29 : event_tracker_(event_tracker) { |
| 30 } |
| 31 |
| 32 RemoteInputFilter::~RemoteInputFilter() { |
| 33 } |
| 34 |
| 35 void RemoteInputFilter::LocalMouseMoved(const SkIPoint& 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 std::list<SkIPoint>::iterator found_position = |
| 40 std::find(injected_mouse_positions_.begin(), |
| 41 injected_mouse_positions_.end(), mouse_pos); |
| 42 if (found_position != injected_mouse_positions_.end()) { |
| 43 // Remove it from the list, and any positions that were added before it, |
| 44 // if any. This is because the local input monitor is assumed to receive |
| 45 // injected mouse position events in the order in which they were injected |
| 46 // (if at all). If the position is found somewhere other than the front of |
| 47 // the queue, this would be because the earlier positions weren't |
| 48 // successfully injected (or the local input monitor might have skipped over |
| 49 // some positions), and not because the events were out-of-sequence. These |
| 50 // spurious positions should therefore be discarded. |
| 51 injected_mouse_positions_.erase(injected_mouse_positions_.begin(), |
| 52 ++found_position); |
| 53 } else { |
| 54 // Release all pressed buttons or keys, disable inputs, and note the time. |
| 55 event_tracker_->ReleaseAll(); |
| 56 latest_local_input_time_ = base::TimeTicks::Now(); |
| 57 } |
| 58 } |
| 59 |
| 60 void RemoteInputFilter::InjectKeyEvent(const protocol::KeyEvent& event) { |
| 61 if (ShouldIgnoreInput()) |
| 62 return; |
| 63 event_tracker_->InjectKeyEvent(event); |
| 64 } |
| 65 |
| 66 void RemoteInputFilter::InjectMouseEvent(const protocol::MouseEvent& event) { |
| 67 if (ShouldIgnoreInput()) |
| 68 return; |
| 69 if (event.has_x() && event.has_y()) { |
| 70 injected_mouse_positions_.push_back(SkIPoint::Make(event.x(), event.y())); |
| 71 if (injected_mouse_positions_.size() > kNumRemoteMousePositions) { |
| 72 VLOG(1) << "Injected mouse positions queue full."; |
| 73 injected_mouse_positions_.pop_front(); |
| 74 } |
| 75 } |
| 76 event_tracker_->InjectMouseEvent(event); |
| 77 } |
| 78 |
| 79 bool RemoteInputFilter::ShouldIgnoreInput() const { |
| 80 // Ignore remote events if the local mouse moved recently. |
| 81 int64 millis = |
| 82 (base::TimeTicks::Now() - latest_local_input_time_).InMilliseconds(); |
| 83 if (millis < kRemoteBlockTimeoutMillis) |
| 84 return true; |
| 85 return false; |
| 86 } |
| 87 |
| 88 } // namespace remoting |
OLD | NEW |