| Index: components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
|
| diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
|
| index 12b21a1b8f435eb4a18586d283cf3ffd4e2b17bf..7711de302b38347e3e9d3fc2d2e89c4e701629c7 100644
|
| --- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
|
| +++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
|
| @@ -41,14 +41,6 @@ bool ShouldMeasurePerformanceForPageLoad() {
|
| return rate == 1 || (rate > 0 && base::RandDouble() < rate);
|
| }
|
|
|
| -bool NavigationIsPageReload(const GURL& url,
|
| - const content::Referrer& referrer,
|
| - ui::PageTransition transition) {
|
| - return ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD) ||
|
| - // Some pages 'reload' from JavaScript by navigating to themselves.
|
| - url == referrer.url;
|
| -}
|
| -
|
| } // namespace
|
|
|
| // static
|
| @@ -70,12 +62,23 @@ ContentSubresourceFilterDriverFactory::FromWebContents(
|
| web_contents->GetUserData(kWebContentsUserDataKey));
|
| }
|
|
|
| +// static
|
| +bool ContentSubresourceFilterDriverFactory::NavigationIsPageReload(
|
| + const GURL& url,
|
| + const content::Referrer& referrer,
|
| + ui::PageTransition transition) {
|
| + return ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD) ||
|
| + // Some pages 'reload' from JavaScript by navigating to themselves.
|
| + url == referrer.url;
|
| +}
|
| +
|
| ContentSubresourceFilterDriverFactory::ContentSubresourceFilterDriverFactory(
|
| content::WebContents* web_contents,
|
| std::unique_ptr<SubresourceFilterClient> client)
|
| : content::WebContentsObserver(web_contents),
|
| client_(std::move(client)),
|
| activation_level_(ActivationLevel::DISABLED),
|
| + activation_decision_(ActivationDecision::UNKNOWN),
|
| measure_performance_(false) {}
|
|
|
| ContentSubresourceFilterDriverFactory::
|
| @@ -137,33 +140,42 @@ void ContentSubresourceFilterDriverFactory::AddHostOfURLToWhitelistSet(
|
| whitelisted_hosts_.insert(url.host());
|
| }
|
|
|
| -bool ContentSubresourceFilterDriverFactory::ShouldActivateForMainFrameURL(
|
| +ContentSubresourceFilterDriverFactory::ActivationDecision
|
| +ContentSubresourceFilterDriverFactory::ComputeActivationDecisionForMainFrameURL(
|
| const GURL& url) const {
|
| - switch (GetCurrentActivationScope()) {
|
| + if (GetMaximumActivationLevel() == ActivationLevel::DISABLED)
|
| + return ActivationDecision::ACTIVATION_DISABLED;
|
| +
|
| + ActivationScope scope = GetCurrentActivationScope();
|
| + if (scope == ActivationScope::NO_SITES)
|
| + return ActivationDecision::ACTIVATION_DISABLED;
|
| +
|
| + if (!url.SchemeIsHTTPOrHTTPS())
|
| + return ActivationDecision::UNSUPPORTED_SCHEME;
|
| + if (IsWhitelisted(url))
|
| + return ActivationDecision::URL_WHITELISTED;
|
| +
|
| + switch (scope) {
|
| case ActivationScope::ALL_SITES:
|
| - return url.SchemeIsHTTPOrHTTPS() && !IsWhitelisted(url);
|
| + return ActivationDecision::ACTIVATED;
|
| case ActivationScope::ACTIVATION_LIST:
|
| // The logic to ensure only http/https URLs are activated lives in
|
| // AddActivationListMatch to ensure the activation list only has relevant
|
| // entries.
|
| DCHECK(url.SchemeIsHTTPOrHTTPS() ||
|
| !DidURLMatchCurrentActivationList(url));
|
| - return DidURLMatchCurrentActivationList(url) && !IsWhitelisted(url);
|
| + return DidURLMatchCurrentActivationList(url)
|
| + ? ActivationDecision::ACTIVATED
|
| + : ActivationDecision::ACTIVATION_LIST_NOT_MATCHED;
|
| default:
|
| - return false;
|
| + return ActivationDecision::ACTIVATION_DISABLED;
|
| }
|
| }
|
|
|
| void ContentSubresourceFilterDriverFactory::ActivateForFrameHostIfNeeded(
|
| content::RenderFrameHost* render_frame_host,
|
| - const GURL& url,
|
| - bool failed_navigation) {
|
| - // PlzNavigate: For failed navigations, ReadyToCommitNavigation is still
|
| - // called, so we end up here; but there is no longer a failed provisional load
|
| - // on the renderer side, so an activation message sent from here would turn on
|
| - // filtering for the subsequent error page load. This is probably harmless,
|
| - // but not sending an activation message is even cleaner.
|
| - if (activation_level_ != ActivationLevel::DISABLED && !failed_navigation) {
|
| + const GURL& url) {
|
| + if (activation_level_ != ActivationLevel::DISABLED) {
|
| render_frame_host->Send(
|
| new SubresourceFilterMsg_ActivateForNextCommittedLoad(
|
| render_frame_host->GetRoutingID(), activation_level_,
|
| @@ -189,6 +201,7 @@ void ContentSubresourceFilterDriverFactory::ResetActivationState() {
|
| void ContentSubresourceFilterDriverFactory::DidStartNavigation(
|
| content::NavigationHandle* navigation_handle) {
|
| if (navigation_handle->IsInMainFrame() && !navigation_handle->IsSamePage()) {
|
| + activation_decision_ = ActivationDecision::UNKNOWN;
|
| ResetActivationState();
|
| navigation_chain_.push_back(navigation_handle->GetURL());
|
| client_->ToggleNotificationVisibility(false);
|
| @@ -205,14 +218,20 @@ void ContentSubresourceFilterDriverFactory::DidRedirectNavigation(
|
| void ContentSubresourceFilterDriverFactory::ReadyToCommitNavigation(
|
| content::NavigationHandle* navigation_handle) {
|
| DCHECK(!navigation_handle->IsSamePage());
|
| +
|
| + // ReadyToCommitNavigation with browser-side navigation disabled is not called
|
| + // in production code for failed navigations (e.g. network errors). We don't
|
| + // want to activate on these pages, so we bail early to guarantee consistent
|
| + // behavior regardless of whether browser-side navigation is enabled.
|
| + if (navigation_handle->GetNetErrorCode() != net::OK)
|
| + return;
|
| +
|
| content::RenderFrameHost* render_frame_host =
|
| navigation_handle->GetRenderFrameHost();
|
| GURL url = navigation_handle->GetURL();
|
| const content::Referrer& referrer = navigation_handle->GetReferrer();
|
| ui::PageTransition transition = navigation_handle->GetPageTransition();
|
| - ReadyToCommitNavigationInternal(
|
| - render_frame_host, url, referrer, transition,
|
| - navigation_handle->GetNetErrorCode() != net::OK);
|
| + ReadyToCommitNavigationInternal(render_frame_host, url, referrer, transition);
|
| }
|
|
|
| void ContentSubresourceFilterDriverFactory::DidFinishLoad(
|
| @@ -274,10 +293,9 @@ void ContentSubresourceFilterDriverFactory::ReadyToCommitNavigationInternal(
|
| content::RenderFrameHost* render_frame_host,
|
| const GURL& url,
|
| const content::Referrer& referrer,
|
| - ui::PageTransition transition,
|
| - bool failed_navigation) {
|
| + ui::PageTransition transition) {
|
| if (render_frame_host->GetParent()) {
|
| - ActivateForFrameHostIfNeeded(render_frame_host, url, failed_navigation);
|
| + ActivateForFrameHostIfNeeded(render_frame_host, url);
|
| return;
|
| }
|
|
|
| @@ -289,7 +307,9 @@ void ContentSubresourceFilterDriverFactory::ReadyToCommitNavigationInternal(
|
| AddHostOfURLToWhitelistSet(url);
|
| }
|
|
|
| - if (!ShouldActivateForMainFrameURL(url)) {
|
| + activation_decision_ = ComputeActivationDecisionForMainFrameURL(url);
|
| + DCHECK(activation_decision_ != ActivationDecision::UNKNOWN);
|
| + if (activation_decision_ != ActivationDecision::ACTIVATED) {
|
| ResetActivationState();
|
| return;
|
| }
|
| @@ -297,7 +317,7 @@ void ContentSubresourceFilterDriverFactory::ReadyToCommitNavigationInternal(
|
| activation_level_ = GetMaximumActivationLevel();
|
| measure_performance_ = activation_level_ != ActivationLevel::DISABLED &&
|
| ShouldMeasurePerformanceForPageLoad();
|
| - ActivateForFrameHostIfNeeded(render_frame_host, url, failed_navigation);
|
| + ActivateForFrameHostIfNeeded(render_frame_host, url);
|
| }
|
|
|
| bool ContentSubresourceFilterDriverFactory::DidURLMatchCurrentActivationList(
|
|
|