1 // Copyright 2013 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 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_H_ 6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_H_ 7 8 #include "base/time/time.h" 9 #include "base/timer/timer.h" 10 #include "content/common/content_export.h" 11 12 namespace content { 13 14 class TapSuppressionControllerClient; 15 16 // The core controller for suppression of taps (touchpad or touchscreen) 17 // immediately following a GestureFlingCancel event (caused by the same tap). 18 // Only taps of sufficient speed and within a specified time window after a 19 // GestureFlingCancel are suppressed. 20 class CONTENT_EXPORT TapSuppressionController { 21 public: 22 struct CONTENT_EXPORT Config { 23 Config(); 24 25 // Defaults to false, in which case no suppression is performed. 26 bool enabled; 27 28 // The maximum time allowed between a GestureFlingCancel and its 29 // corresponding tap down. 30 base::TimeDelta max_cancel_to_down_time; 31 32 // The maximum time allowed between a single tap's down and up events. 33 base::TimeDelta max_tap_gap_time; 34 }; 35 36 TapSuppressionController(TapSuppressionControllerClient* client, 37 const Config& config); 38 virtual ~TapSuppressionController(); 39 40 // Should be called whenever a GestureFlingCancel event is received. 41 void GestureFlingCancel(); 42 43 // Should be called whenever an ACK for a GestureFlingCancel event is 44 // received. |processed| is true when the GestureFlingCancel actually stopped 45 // a fling and therefore should suppress the forwarding of the following tap. 46 void GestureFlingCancelAck(bool processed); 47 48 // Should be called whenever a tap down (touchpad or touchscreen) is received. 49 // Returns true if the tap down should be deferred. The caller is responsible 50 // for keeping the event for later release, if needed. 51 bool ShouldDeferTapDown(); 52 53 // Should be called whenever a tap ending event is received. Returns true if 54 // the tap event should be suppressed. 55 bool ShouldSuppressTapEnd(); 56 57 protected: 58 virtual base::TimeTicks Now(); 59 virtual void StartTapDownTimer(const base::TimeDelta& delay); 60 virtual void StopTapDownTimer(); 61 void TapDownTimerExpired(); 62 63 private: 64 friend class MockTapSuppressionController; 65 66 enum State { 67 DISABLED, 68 NOTHING, 69 GFC_IN_PROGRESS, 70 TAP_DOWN_STASHED, 71 LAST_CANCEL_STOPPED_FLING, 72 }; 73 74 TapSuppressionControllerClient* client_; 75 base::OneShotTimer<TapSuppressionController> tap_down_timer_; 76 State state_; 77 78 base::TimeDelta max_cancel_to_down_time_; 79 base::TimeDelta max_tap_gap_time_; 80 81 // TODO(rjkroege): During debugging, the event times did not prove reliable. 82 // Replace the use of base::TimeTicks with an accurate event time when they 83 // become available post http://crbug.com/119556. 84 base::TimeTicks fling_cancel_time_; 85 86 DISALLOW_COPY_AND_ASSIGN(TapSuppressionController); 87 }; 88 89 } // namespace content 90 91 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_H_ 92