1558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_H_
6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/content_export.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TapSuppressionControllerClient;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The core controller for suppression of taps (touchpad or touchscreen)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// immediately following a GestureFlingCancel event (caused by the same tap).
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Only taps of sufficient speed and within a specified time window after a
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// GestureFlingCancel are suppressed.
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CONTENT_EXPORT TapSuppressionController {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  struct CONTENT_EXPORT Config {
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Config();
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Defaults to false, in which case no suppression is performed.
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool enabled;
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // The maximum time allowed between a GestureFlingCancel and its
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // corresponding tap down.
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::TimeDelta max_cancel_to_down_time;
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // The maximum time allowed between a single tap's down and up events.
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::TimeDelta max_tap_gap_time;
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  };
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  TapSuppressionController(TapSuppressionControllerClient* client,
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           const Config& config);
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TapSuppressionController();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should be called whenever a GestureFlingCancel event is received.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void GestureFlingCancel();
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should be called whenever an ACK for a GestureFlingCancel event is
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // received. |processed| is true when the GestureFlingCancel actually stopped
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a fling and therefore should suppress the forwarding of the following tap.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void GestureFlingCancelAck(bool processed);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should be called whenever a tap down (touchpad or touchscreen) is received.
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the tap down should be deferred. The caller is responsible
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for keeping the event for later release, if needed.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ShouldDeferTapDown();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Should be called whenever a tap ending event is received. Returns true if
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the tap event should be suppressed.
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool ShouldSuppressTapEnd();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::TimeTicks Now();
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void StartTapDownTimer(const base::TimeDelta& delay);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void StopTapDownTimer();
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TapDownTimerExpired();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class MockTapSuppressionController;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum State {
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DISABLED,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTHING,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GFC_IN_PROGRESS,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TAP_DOWN_STASHED,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LAST_CANCEL_STOPPED_FLING,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TapSuppressionControllerClient* client_;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::OneShotTimer<TapSuppressionController> tap_down_timer_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State state_;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::TimeDelta max_cancel_to_down_time_;
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::TimeDelta max_tap_gap_time_;
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(rjkroege): During debugging, the event times did not prove reliable.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Replace the use of base::TimeTicks with an accurate event time when they
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // become available post http://crbug.com/119556.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks fling_cancel_time_;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TapSuppressionController);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif  // CONTENT_BROWSER_RENDERER_HOST_INPUT_TAP_SUPPRESSION_CONTROLLER_H_
92