Home | History | Annotate | Download | only in input
      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