• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "content/browser/renderer_host/input/tap_suppression_controller.h"
6 
7 #include "base/debug/trace_event.h"
8 #include "base/logging.h"
9 #include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
10 
11 namespace content {
12 
Config()13 TapSuppressionController::Config::Config()
14     : enabled(false),
15       max_cancel_to_down_time(base::TimeDelta::FromMilliseconds(180)),
16       max_tap_gap_time(base::TimeDelta::FromMilliseconds(500)) {
17 }
18 
TapSuppressionController(TapSuppressionControllerClient * client,const Config & config)19 TapSuppressionController::TapSuppressionController(
20     TapSuppressionControllerClient* client,
21     const Config& config)
22     : client_(client),
23       state_(config.enabled ? NOTHING : DISABLED),
24       max_cancel_to_down_time_(config.max_cancel_to_down_time),
25       max_tap_gap_time_(config.max_tap_gap_time) {
26 }
27 
~TapSuppressionController()28 TapSuppressionController::~TapSuppressionController() {}
29 
GestureFlingCancel()30 void TapSuppressionController::GestureFlingCancel() {
31   switch (state_) {
32     case DISABLED:
33       break;
34     case NOTHING:
35     case GFC_IN_PROGRESS:
36     case LAST_CANCEL_STOPPED_FLING:
37       state_ = GFC_IN_PROGRESS;
38       break;
39     case TAP_DOWN_STASHED:
40       break;
41   }
42 }
43 
GestureFlingCancelAck(bool processed)44 void TapSuppressionController::GestureFlingCancelAck(bool processed) {
45   base::TimeTicks event_time = Now();
46   switch (state_) {
47     case DISABLED:
48     case NOTHING:
49       break;
50     case GFC_IN_PROGRESS:
51       if (processed)
52         fling_cancel_time_ = event_time;
53       state_ = LAST_CANCEL_STOPPED_FLING;
54       break;
55     case TAP_DOWN_STASHED:
56       if (!processed) {
57         TRACE_EVENT0("browser",
58                      "TapSuppressionController::GestureFlingCancelAck");
59         StopTapDownTimer();
60         client_->ForwardStashedTapDown();
61         state_ = NOTHING;
62       }  // Else waiting for the timer to release the stashed tap down.
63       break;
64     case LAST_CANCEL_STOPPED_FLING:
65       break;
66   }
67 }
68 
ShouldDeferTapDown()69 bool TapSuppressionController::ShouldDeferTapDown() {
70   base::TimeTicks event_time = Now();
71   switch (state_) {
72     case DISABLED:
73     case NOTHING:
74       return false;
75     case GFC_IN_PROGRESS:
76       state_ = TAP_DOWN_STASHED;
77       StartTapDownTimer(max_tap_gap_time_);
78       return true;
79     case TAP_DOWN_STASHED:
80       NOTREACHED() << "TapDown on TAP_DOWN_STASHED state";
81       state_ = NOTHING;
82       return false;
83     case LAST_CANCEL_STOPPED_FLING:
84       if ((event_time - fling_cancel_time_) < max_cancel_to_down_time_) {
85         state_ = TAP_DOWN_STASHED;
86         StartTapDownTimer(max_tap_gap_time_);
87         return true;
88       } else {
89         state_ = NOTHING;
90         return false;
91       }
92   }
93   NOTREACHED() << "Invalid state";
94   return false;
95 }
96 
ShouldSuppressTapEnd()97 bool TapSuppressionController::ShouldSuppressTapEnd() {
98   switch (state_) {
99     case DISABLED:
100     case NOTHING:
101     case GFC_IN_PROGRESS:
102       return false;
103     case TAP_DOWN_STASHED:
104       state_ = NOTHING;
105       StopTapDownTimer();
106       client_->DropStashedTapDown();
107       return true;
108     case LAST_CANCEL_STOPPED_FLING:
109       NOTREACHED() << "Invalid tap end on LAST_CANCEL_STOPPED_FLING state";
110   }
111   return false;
112 }
113 
Now()114 base::TimeTicks TapSuppressionController::Now() {
115   return base::TimeTicks::Now();
116 }
117 
StartTapDownTimer(const base::TimeDelta & delay)118 void TapSuppressionController::StartTapDownTimer(const base::TimeDelta& delay) {
119   tap_down_timer_.Start(FROM_HERE, delay, this,
120                         &TapSuppressionController::TapDownTimerExpired);
121 }
122 
StopTapDownTimer()123 void TapSuppressionController::StopTapDownTimer() {
124   tap_down_timer_.Stop();
125 }
126 
TapDownTimerExpired()127 void TapSuppressionController::TapDownTimerExpired() {
128   switch (state_) {
129     case DISABLED:
130     case NOTHING:
131       NOTREACHED() << "Timer fired on invalid state.";
132       break;
133     case GFC_IN_PROGRESS:
134     case LAST_CANCEL_STOPPED_FLING:
135       NOTREACHED() << "Timer fired on invalid state.";
136       state_ = NOTHING;
137       break;
138     case TAP_DOWN_STASHED:
139       TRACE_EVENT0("browser",
140                    "TapSuppressionController::TapDownTimerExpired");
141       client_->ForwardStashedTapDown();
142       state_ = NOTHING;
143       break;
144   }
145 }
146 
147 }  // namespace content
148