blob: 134cad34e2194f5a0974dc6736642f653465b43c [file] [log] [blame]
// Copyright 2020 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 "components/subresource_filter/content/browser/profile_interaction_manager.h"
#include "base/logging.h"
#include "components/subresource_filter/content/browser/ads_intervention_manager.h"
#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
#include "components/subresource_filter/content/browser/subresource_filter_content_settings_manager.h"
#include "components/subresource_filter/content/browser/subresource_filter_profile_context.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
namespace subresource_filter {
ProfileInteractionManager::ProfileInteractionManager(
content::WebContents* web_contents,
SubresourceFilterProfileContext* profile_context)
: content::WebContentsObserver(web_contents),
profile_context_(profile_context) {
DCHECK(web_contents);
}
ProfileInteractionManager::~ProfileInteractionManager() = default;
void ProfileInteractionManager::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
if (navigation_handle->HasCommitted() && navigation_handle->IsInMainFrame() &&
!navigation_handle->IsSameDocument()) {
ads_violation_triggered_for_last_committed_navigation_ = false;
}
}
void ProfileInteractionManager::OnReloadRequested() {
ContentSubresourceFilterThrottleManager::LogAction(
SubresourceFilterAction::kAllowlistedSite);
profile_context_->settings_manager()->AllowlistSite(
web_contents()->GetLastCommittedURL());
web_contents()->GetController().Reload(content::ReloadType::NORMAL, true);
}
// TODO(https://crbug.com/1131969): Consider adding reporting when
// ads violations are triggered.
void ProfileInteractionManager::OnAdsViolationTriggered(
content::RenderFrameHost* rfh,
mojom::AdsViolation triggered_violation) {
// Only trigger violations once per navigation. The ads intervention
// manager ignores all interventions after recording an intervention
// for the intervention duration, however, a page that began a navigation
// before the intervention duration and was still alive after the duration
// could re-trigger an ads intervention.
if (ads_violation_triggered_for_last_committed_navigation_)
return;
// If the feature is disabled, simulate ads interventions as if we were
// enforcing on ads: do not record new interventions if we would be enforcing
// an intervention on ads already.
//
// TODO(https://crbug.com/1131971): Add support for enabling ads interventions
// separately for different ads violations.
const GURL& url = rfh->GetLastCommittedURL();
base::Optional<AdsInterventionManager::LastAdsIntervention>
last_intervention =
profile_context_->ads_intervention_manager()->GetLastAdsIntervention(
url);
// TODO(crbug.com/1131971): If a host triggers multiple times on a single
// navigate and the durations don't match, we'll use the last duration rather
// than the longest. The metadata should probably store the activation with
// the longest duration.
if (last_intervention && last_intervention->duration_since <
AdsInterventionManager::GetInterventionDuration(
last_intervention->ads_violation)) {
return;
}
profile_context_->ads_intervention_manager()
->TriggerAdsInterventionForUrlOnSubsequentLoads(url, triggered_violation);
ads_violation_triggered_for_last_committed_navigation_ = true;
}
mojom::ActivationLevel ProfileInteractionManager::OnPageActivationComputed(
content::NavigationHandle* navigation_handle,
mojom::ActivationLevel initial_activation_level,
ActivationDecision* decision) {
DCHECK(navigation_handle->IsInMainFrame());
mojom::ActivationLevel effective_activation_level = initial_activation_level;
if (profile_context_->ads_intervention_manager()->ShouldActivate(
navigation_handle)) {
effective_activation_level = mojom::ActivationLevel::kEnabled;
*decision = ActivationDecision::ACTIVATED;
}
const GURL& url(navigation_handle->GetURL());
if (url.SchemeIsHTTPOrHTTPS()) {
profile_context_->settings_manager()->SetSiteMetadataBasedOnActivation(
url, effective_activation_level == mojom::ActivationLevel::kEnabled,
SubresourceFilterContentSettingsManager::ActivationSource::
kSafeBrowsing);
}
if (profile_context_->settings_manager()->GetSitePermission(url) ==
CONTENT_SETTING_ALLOW) {
if (effective_activation_level == mojom::ActivationLevel::kEnabled) {
*decision = ActivationDecision::URL_ALLOWLISTED;
}
return mojom::ActivationLevel::kDisabled;
}
return effective_activation_level;
}
} // namespace subresource_filter