| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "ios/web/web_state/user_interaction_state.h" |
| |
| #import "base/time/time.h" |
| |
| namespace { |
| // The duration of the period following a screen touch during which the user is |
| // still considered to be interacting with the page. |
| constexpr base::TimeDelta kMaximumDelayForUserInteraction = base::Seconds(2); |
| } // namespace |
| |
| namespace web { |
| |
| UserInteractionState::UserInteractionState() |
| : user_interaction_registered_since_page_loaded_(false), |
| user_interaction_registered_since_last_url_change_(false), |
| user_interaction_registered_since_web_view_created_(false), |
| tap_in_progress_(false), |
| last_user_interaction_(nullptr) {} |
| |
| UserInteractionState::~UserInteractionState() {} |
| |
| bool UserInteractionState::UserInteractionRegisteredSincePageLoaded() const { |
| return user_interaction_registered_since_page_loaded_; |
| } |
| |
| void UserInteractionState::SetUserInteractionRegisteredSincePageLoaded( |
| bool user_interaction_registered_since_page_loaded) { |
| user_interaction_registered_since_page_loaded_ = |
| user_interaction_registered_since_page_loaded; |
| if (user_interaction_registered_since_page_loaded) { |
| user_interaction_registered_since_last_url_change_ = true; |
| user_interaction_registered_since_web_view_created_ = true; |
| } |
| } |
| |
| bool UserInteractionState::UserInteractionRegisteredSinceLastUrlChange() const { |
| return user_interaction_registered_since_last_url_change_; |
| } |
| |
| void UserInteractionState::SetUserInteractionRegisteredSinceLastUrlChange( |
| bool user_interaction_registered_since_last_url_change) { |
| user_interaction_registered_since_last_url_change_ = |
| user_interaction_registered_since_last_url_change; |
| if (user_interaction_registered_since_last_url_change) { |
| user_interaction_registered_since_web_view_created_ = true; |
| } |
| } |
| |
| bool UserInteractionState::UserInteractionRegisteredSinceWebViewCreated() |
| const { |
| return user_interaction_registered_since_web_view_created_; |
| } |
| |
| void UserInteractionState::SetTapInProgress(bool tap_in_progress) { |
| tap_in_progress_ = tap_in_progress; |
| } |
| |
| void UserInteractionState::ResetLastTransferTime() { |
| last_transfer_time_ = base::TimeTicks::Now(); |
| } |
| |
| web::UserInteractionEvent* UserInteractionState::LastUserInteraction() const { |
| return last_user_interaction_.get(); |
| } |
| |
| void UserInteractionState::SetLastUserInteraction( |
| std::unique_ptr<web::UserInteractionEvent> last_user_interaction) { |
| last_user_interaction_ = std::move(last_user_interaction); |
| } |
| |
| bool UserInteractionState::HasUserTappedRecently(WKWebView* web_view) const { |
| // Scrolling generates a pair of touch on/off event which causes |
| // last_user_interaction_ to register that there was user interaction. Checks |
| // for scrolling first to override time-based tap heuristics. |
| if (web_view.scrollView.dragging || web_view.scrollView.decelerating) { |
| return NO; |
| } |
| if (!last_user_interaction_) { |
| return NO; |
| } |
| if (tap_in_progress_) { |
| return YES; |
| } |
| return (base::TimeTicks::Now() - last_user_interaction_->time) < |
| kMaximumDelayForUserInteraction; |
| } |
| |
| bool UserInteractionState::IsUserInteracting(WKWebView* web_view) const { |
| // If page transfer started after last tap, user is deemed to be no longer |
| // interacting. |
| if (!last_user_interaction_ || |
| last_transfer_time_ > last_user_interaction_->time) { |
| return NO; |
| } |
| return HasUserTappedRecently(web_view); |
| } |
| |
| } // namespace web |