Commit e00ac24b authored by Yi Su's avatar Yi Su Committed by Commit Bot

Refactor user-interaction out of CRWWebController.

This CL refactors all user-interaction logic from CRWWebController into
UserInteractionEvent and UserInteractionState.

Bug: 956511
Change-Id: I1ae63c395c0b269a30ab0b7b2743103c1ae4ffbf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1610775
Commit-Queue: Yi Su <mrsuyi@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#660322}
parent 166a4bbd
...@@ -171,3 +171,18 @@ source_set("web_frame") { ...@@ -171,3 +171,18 @@ source_set("web_frame") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
} }
source_set("user_interaction") {
sources = [
"user_interaction_event.h",
"user_interaction_state.h",
"user_interaction_state.mm",
]
deps = [
"//base",
"//url",
]
configs += [ "//build/config/compiler:enable_arc" ]
}
...@@ -29,6 +29,7 @@ source_set("ui") { ...@@ -29,6 +29,7 @@ source_set("ui") {
"//ios/web/web_state:error_translation_util", "//ios/web/web_state:error_translation_util",
"//ios/web/web_state:page_viewport_state", "//ios/web/web_state:page_viewport_state",
"//ios/web/web_state:session_certificate_policy_cache", "//ios/web/web_state:session_certificate_policy_cache",
"//ios/web/web_state:user_interaction",
"//ios/web/web_state:web_frame", "//ios/web/web_state:web_frame",
"//ios/web/web_state:web_state_impl_header", "//ios/web/web_state:web_state_impl_header",
"//ios/web/web_state:web_view_internal_creation_util", "//ios/web/web_state:web_view_internal_creation_util",
......
...@@ -222,9 +222,6 @@ class WebStateImpl; ...@@ -222,9 +222,6 @@ class WebStateImpl;
@property(nonatomic, readonly) web::WebState* webState; @property(nonatomic, readonly) web::WebState* webState;
@property(nonatomic, readonly) web::WebStateImpl* webStateImpl; @property(nonatomic, readonly) web::WebStateImpl* webStateImpl;
// Returns whether the user is interacting with the page.
@property(nonatomic, readonly) BOOL userIsInteracting;
// Injects a CRWWebViewContentView for testing. Takes ownership of // Injects a CRWWebViewContentView for testing. Takes ownership of
// |webViewContentView|. // |webViewContentView|.
- (void)injectWebViewContentView:(CRWWebViewContentView*)webViewContentView; - (void)injectWebViewContentView:(CRWWebViewContentView*)webViewContentView;
......
This diff is collapsed.
...@@ -1127,7 +1127,6 @@ TEST_P(WindowOpenByDomTest, OpenWithUserGesture) { ...@@ -1127,7 +1127,6 @@ TEST_P(WindowOpenByDomTest, OpenWithUserGesture) {
// Tests that window.open executed w/o user gesture does not open a new window, // Tests that window.open executed w/o user gesture does not open a new window,
// but blocks popup instead. // but blocks popup instead.
TEST_P(WindowOpenByDomTest, BlockPopup) { TEST_P(WindowOpenByDomTest, BlockPopup) {
ASSERT_FALSE([web_controller() userIsInteracting]);
EXPECT_NSEQ([NSNull null], OpenWindowByDom()); EXPECT_NSEQ([NSNull null], OpenWindowByDom());
EXPECT_TRUE(delegate_.child_windows().empty()); EXPECT_TRUE(delegate_.child_windows().empty());
......
// Copyright 2019 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.
#ifndef IOS_WEB_WEB_STATE_USER_INTERACTION_EVENT_H_
#define IOS_WEB_WEB_STATE_USER_INTERACTION_EVENT_H_
#import <CoreFoundation/CFDate.h>
#include "url/gurl.h"
namespace web {
// Struct to capture data about a user interaction. Records the time of the
// interaction and the main document URL at that time.
struct UserInteractionEvent {
explicit UserInteractionEvent(const GURL& url)
: main_document_url(url), time(CFAbsoluteTimeGetCurrent()) {}
// Main document URL at the time the interaction occurred.
GURL main_document_url;
// Time that the interaction occurred, measured in seconds since Jan 1 2001.
CFAbsoluteTime time;
};
} // namespace web
#endif // IOS_WEB_WEB_STATE_USER_INTERACTION_EVENT_H_
// Copyright 2019 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.
#ifndef IOS_WEB_WEB_STATE_USER_INTERACTION_STATE_H_
#define IOS_WEB_WEB_STATE_USER_INTERACTION_STATE_H_
#import <WebKit/WebKit.h>
#include <memory>
#import "ios/web/web_state/user_interaction_event.h"
namespace web {
// Records user's interaction state with web content.
class UserInteractionState {
public:
UserInteractionState();
~UserInteractionState();
// Returns |user_interaction_registered_since_page_loaded_|.
bool UserInteractionRegisteredSincePageLoaded() const;
// Sets |user_interaction_registered_since_page_loaded_|. If true, also sets
// |user_interaction_registered_since_last_url_change_| and
// |user_interaction_registered_since_web_view_created_| to true;
void SetUserInteractionRegisteredSincePageLoaded(
bool user_interaction_registered_since_page_loaded);
// Returns |user_interaction_registered_since_last_url_change_|.
bool UserInteractionRegisteredSinceLastUrlChange() const;
// Sets |user_interaction_registered_since_last_url_change_|. If true, also
// sets |user_interaction_registered_since_web_view_created_| to true.
void SetUserInteractionRegisteredSinceLastUrlChange(
bool interaction_registered_since_last_url_change);
// Returns |user_interaction_registered_since_web_view_created_|.
bool UserInteractionRegisteredSinceWebViewCreated() const;
// Sets |tap_in_progress_|.
void SetTapInProgress(bool tap_in_progress);
// Resets |last_transfer_time_in_seconds_| to current time.
void ResetLastTransferTime();
// Returns the raw pointer managed by |last_user_interaction_|.
web::UserInteractionEvent* LastUserInteraction() const;
// Sets |last_user_interaction_|.
void SetLastUserInteraction(
std::unique_ptr<web::UserInteractionEvent> last_user_interaction);
// Returns true if the user interacted with the page recently.
bool HasUserTappedRecently(WKWebView* web_view) const;
// Returns whether the user is interacting with the page.
bool IsUserInteracting(WKWebView* web_view) const;
private:
// Whether a user interaction has been registered since the page has loaded.
bool user_interaction_registered_since_page_loaded_;
// Whether a user interaction has been registered since the last URL change.
bool user_interaction_registered_since_last_url_change_;
// Whether a user interaction has been registered since the web view is
// created.
bool user_interaction_registered_since_web_view_created_;
// Whether a tap is in progress.
bool tap_in_progress_;
// The time of the last page transfer start, measured in seconds since Jan 1
// 2001.
CFAbsoluteTime last_transfer_time_in_seconds_;
// Data on the recorded last user interaction.
std::unique_ptr<web::UserInteractionEvent> last_user_interaction_;
};
} // namespace web
#endif // IOS_WEB_WEB_STATE_USER_INTERACTION_STATE_H_
// Copyright 2019 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.
#import "ios/web/web_state/user_interaction_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// The duration of the period following a screen touch during which the user is
// still considered to be interacting with the page.
const NSTimeInterval kMaximumDelayForUserInteractionInSeconds = 2;
}
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_in_seconds_ = CFAbsoluteTimeGetCurrent();
}
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;
return tap_in_progress_ ||
((CFAbsoluteTimeGetCurrent() - last_user_interaction_->time) <
kMaximumDelayForUserInteractionInSeconds);
}
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_in_seconds_ > last_user_interaction_->time) {
return NO;
}
return HasUserTappedRecently(web_view);
}
} // namespace web
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment