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