| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/renderer_host/input/tap_suppression_controller.h" |
| |
| #include "base/debug/trace_event.h" |
| #include "base/logging.h" |
| #include "content/browser/renderer_host/input/tap_suppression_controller_client.h" |
| |
| namespace content { |
| |
| TapSuppressionController::TapSuppressionController( |
| TapSuppressionControllerClient* client) |
| : client_(client), |
| state_(TapSuppressionController::NOTHING) { |
| } |
| |
| TapSuppressionController::~TapSuppressionController() {} |
| |
| void TapSuppressionController::GestureFlingCancel() { |
| switch (state_) { |
| case NOTHING: |
| case GFC_IN_PROGRESS: |
| case LAST_CANCEL_STOPPED_FLING: |
| state_ = GFC_IN_PROGRESS; |
| break; |
| case TAP_DOWN_STASHED: |
| break; |
| } |
| } |
| |
| void TapSuppressionController::GestureFlingCancelAck(bool processed) { |
| base::TimeTicks event_time = Now(); |
| switch (state_) { |
| case NOTHING: |
| break; |
| case GFC_IN_PROGRESS: |
| if (processed) |
| fling_cancel_time_ = event_time; |
| state_ = LAST_CANCEL_STOPPED_FLING; |
| break; |
| case TAP_DOWN_STASHED: |
| if (!processed) { |
| TRACE_EVENT0("browser", |
| "TapSuppressionController::GestureFlingCancelAck"); |
| StopTapDownTimer(); |
| client_->ForwardStashedTapDown(); |
| state_ = NOTHING; |
| } // Else waiting for the timer to release the stashed tap down. |
| break; |
| case LAST_CANCEL_STOPPED_FLING: |
| break; |
| } |
| } |
| |
| bool TapSuppressionController::ShouldDeferTapDown() { |
| base::TimeTicks event_time = Now(); |
| switch (state_) { |
| case NOTHING: |
| return false; |
| case GFC_IN_PROGRESS: |
| state_ = TAP_DOWN_STASHED; |
| StartTapDownTimer( |
| base::TimeDelta::FromMilliseconds(client_->MaxTapGapTimeInMs())); |
| return true; |
| case TAP_DOWN_STASHED: |
| NOTREACHED() << "TapDown on TAP_DOWN_STASHED state"; |
| state_ = NOTHING; |
| return false; |
| case LAST_CANCEL_STOPPED_FLING: |
| if ((event_time - fling_cancel_time_).InMilliseconds() |
| < client_->MaxCancelToDownTimeInMs()) { |
| state_ = TAP_DOWN_STASHED; |
| StartTapDownTimer( |
| base::TimeDelta::FromMilliseconds(client_->MaxTapGapTimeInMs())); |
| return true; |
| } else { |
| state_ = NOTHING; |
| return false; |
| } |
| } |
| NOTREACHED() << "Invalid state"; |
| return false; |
| } |
| |
| bool TapSuppressionController::ShouldSuppressTapUp() { |
| switch (state_) { |
| case NOTHING: |
| case GFC_IN_PROGRESS: |
| return false; |
| case TAP_DOWN_STASHED: |
| state_ = NOTHING; |
| StopTapDownTimer(); |
| client_->DropStashedTapDown(); |
| return true; |
| case LAST_CANCEL_STOPPED_FLING: |
| NOTREACHED() << "Invalid TapUp on LAST_CANCEL_STOPPED_FLING state"; |
| } |
| return false; |
| } |
| |
| bool TapSuppressionController::ShouldSuppressTapCancel() { |
| switch (state_) { |
| case NOTHING: |
| case GFC_IN_PROGRESS: |
| return false; |
| case TAP_DOWN_STASHED: |
| state_ = NOTHING; |
| StopTapDownTimer(); |
| client_->DropStashedTapDown(); |
| return true; |
| case LAST_CANCEL_STOPPED_FLING: |
| NOTREACHED() << "Invalid TapCancel on LAST_CANCEL_STOPPED_FLING state"; |
| } |
| return false; |
| } |
| |
| base::TimeTicks TapSuppressionController::Now() { |
| return base::TimeTicks::Now(); |
| } |
| |
| void TapSuppressionController::StartTapDownTimer(const base::TimeDelta& delay) { |
| tap_down_timer_.Start(FROM_HERE, delay, this, |
| &TapSuppressionController::TapDownTimerExpired); |
| } |
| |
| void TapSuppressionController::StopTapDownTimer() { |
| tap_down_timer_.Stop(); |
| } |
| |
| void TapSuppressionController::TapDownTimerExpired() { |
| switch (state_) { |
| case NOTHING: |
| case GFC_IN_PROGRESS: |
| case LAST_CANCEL_STOPPED_FLING: |
| NOTREACHED() << "Timer fired on invalid state."; |
| state_ = NOTHING; |
| break; |
| case TAP_DOWN_STASHED: |
| TRACE_EVENT0("browser", |
| "TapSuppressionController::TapDownTimerExpired"); |
| client_->ForwardStashedTapDown(); |
| state_ = NOTHING; |
| break; |
| } |
| } |
| |
| } // namespace content |