 Chromium Code Reviews
 Chromium Code Reviews Issue 2691423006:
  Introduce the ThrottleManager  (Closed)
    
  
    Issue 2691423006:
  Introduce the ThrottleManager  (Closed) 
  | Index: components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc | 
| diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..e20161e8d426769886844e0fb8e61e77aa16c29e | 
| --- /dev/null | 
| +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc | 
| @@ -0,0 +1,163 @@ | 
| +// Copyright 2017 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/content_subresource_filter_throttle_manager.h" | 
| + | 
| +#include "base/bind.h" | 
| +#include "base/memory/ptr_util.h" | 
| +#include "components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h" | 
| +#include "components/subresource_filter/content/browser/async_document_subresource_filter.h" | 
| +#include "components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.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 { | 
| + | 
| +FrameActivationInfo::FrameActivationInfo() {} | 
| +FrameActivationInfo::~FrameActivationInfo() {} | 
| + | 
| +bool ContentSubresourceFilterThrottleManager::Delegate::ShouldVetoActivation( | 
| + content::NavigationHandle* navigation_handle) { | 
| + return false; | 
| +} | 
| + | 
| +ContentSubresourceFilterThrottleManager:: | 
| + ContentSubresourceFilterThrottleManager( | 
| + Delegate* delegate, | 
| + VerifiedRulesetDealer::Handle* dealer_handle, | 
| + content::WebContents* web_contents) | 
| + : content::WebContentsObserver(web_contents), | 
| + dealer_handle_(dealer_handle), | 
| + delegate_(delegate) {} | 
| + | 
| +ContentSubresourceFilterThrottleManager:: | 
| + ~ContentSubresourceFilterThrottleManager() {} | 
| + | 
| +void ContentSubresourceFilterThrottleManager::OnPageStateActivationComputed( | 
| 
engedy
2017/02/17 20:44:44
nit: For consistency, what do you think about call
 
Charlie Harrison
2017/02/17 22:12:31
Sure, renamed to NotifyPageActivationComputed.
 | 
| + content::NavigationHandle* activated_navigation, | 
| + const ActivationState& state) { | 
| 
engedy
2017/02/17 20:44:44
nit: %s/ state/ activation_state/g
 
Charlie Harrison
2017/02/17 22:12:31
Done, here and throughout the file.
 | 
| + DCHECK(activated_navigation->IsInMainFrame()); | 
| + DCHECK(!activated_navigation->HasCommitted()); | 
| + auto it = ongoing_activation_throttles_.find(activated_navigation); | 
| + if (it != ongoing_activation_throttles_.end()) { | 
| + it->second->NotifyPageActivationWithRuleset( | 
| + EnsureRulesetHandle(), state, | 
| + base::Bind(&ContentSubresourceFilterThrottleManager::Delegate:: | 
| + OnFirstSubresourceLoadDisallowed, | 
| 
engedy
2017/02/17 20:44:44
Note that, later, we will need to clean up this si
 
Charlie Harrison
2017/02/17 22:12:31
I think the coalescing should be done in this clas
 
engedy
2017/02/20 15:58:13
Sounds good, let's do that in a follow-up CL.
Chr
 | 
| + delegate_->AsWeakPtr())); | 
| + } | 
| +} | 
| + | 
| +void ContentSubresourceFilterThrottleManager::RenderFrameDeleted( | 
| + content::RenderFrameHost* frame_host) { | 
| + activated_frame_hosts_.erase(frame_host); | 
| + if (activated_frame_hosts_.size() == 0) | 
| + ruleset_handle_.reset(); | 
| +} | 
| + | 
| +// Pull the AsyncDocumentSubresourceFilter and its associated ActivationState | 
| +// out of the activation state computing throttle. Store it for later filtering | 
| +// of subframe navigations. | 
| +void ContentSubresourceFilterThrottleManager::ReadyToCommitNavigation( | 
| + content::NavigationHandle* navigation_handle) { | 
| + content::RenderFrameHost* frame_host = | 
| + navigation_handle->GetRenderFrameHost(); | 
| + // Make sure that if the committed navigation is in a RenderFrameHost that is | 
| + // already activated, the activation state is reset. This is important in the | 
| + // case where this navigation does *not* trigger activation. | 
| + activated_frame_hosts_.erase(frame_host); | 
| 
engedy
2017/02/17 20:44:44
nit: It's a bit hard to argue about |ruleset_handl
 
Charlie Harrison
2017/02/17 22:12:31
You're right, this is hard to reason about. Essent
 | 
| + | 
| + auto throttle = ongoing_activation_throttles_.find(navigation_handle); | 
| + if (throttle == ongoing_activation_throttles_.end()) | 
| + return; | 
| + | 
| + const ActivationState& state = throttle->second->GetActivationState(); | 
| + if (state.activation_level == ActivationLevel::DISABLED || | 
| + delegate_->ShouldVetoActivation(navigation_handle)) | 
| + return; | 
| + | 
| + auto info = base::MakeUnique<FrameActivationInfo>(); | 
| + info->subresource_filter = throttle->second->ReleaseFilter(); | 
| + info->activation_state = state; | 
| + DCHECK(info->subresource_filter); | 
| + activated_frame_hosts_[navigation_handle->GetRenderFrameHost()] = | 
| 
engedy
2017/02/17 20:44:44
nit: activated_frame_hosts_[frame_host]
 
Charlie Harrison
2017/02/17 22:12:31
Done.
 | 
| + std::move(info); | 
| + // TODO(csharrison): Send an IPC to the renderer. | 
| +} | 
| + | 
| +void ContentSubresourceFilterThrottleManager::DidFinishNavigation( | 
| + content::NavigationHandle* navigation_handle) { | 
| + ongoing_activation_throttles_.erase(navigation_handle); | 
| +} | 
| + | 
| +void ContentSubresourceFilterThrottleManager::MaybeInsertNavigationThrottles( | 
| 
engedy
2017/02/17 20:44:44
nit: MaybeAppendNavigationThrottles
 
Charlie Harrison
2017/02/17 22:12:31
Done.
 | 
| + content::NavigationHandle* navigation_handle, | 
| + std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) { | 
| + if (std::unique_ptr<content::NavigationThrottle> filtering_throttle = | 
| + MaybeCreateSubframeNavigationFilteringThrottle(navigation_handle)) { | 
| + throttles->push_back(std::move(filtering_throttle)); | 
| + } | 
| + if (std::unique_ptr<content::NavigationThrottle> activation_throttle = | 
| + MaybeCreateActivationStateComputingThrottle(navigation_handle)) { | 
| + throttles->push_back(std::move(activation_throttle)); | 
| + } | 
| +} | 
| + | 
| +std::unique_ptr<content::NavigationThrottle> | 
| +ContentSubresourceFilterThrottleManager:: | 
| + MaybeCreateSubframeNavigationFilteringThrottle( | 
| + content::NavigationHandle* navigation_handle) { | 
| + if (navigation_handle->IsInMainFrame() || navigation_handle->IsSamePage()) | 
| 
engedy
2017/02/17 20:44:44
Could you please verify what happens here for navi
 
Charlie Harrison
2017/02/17 22:12:31
Yes I think same-page navigations and all synchron
 
engedy
2017/02/20 15:58:13
Awesome, thanks for checking!
 
engedy
2017/03/10 17:36:20
To quote a popular meme:
-- Tell me you turned th
 
Charlie Harrison
2017/03/14 23:18:31
LOL. Done.
 | 
| + return nullptr; | 
| + FrameActivationInfo* info = | 
| + GetFrameActivationInfoForChildNavigation(navigation_handle); | 
| + return info ? base::MakeUnique<SubframeNavigationFilteringThrottle>( | 
| + navigation_handle, info->subresource_filter.get()) | 
| + : nullptr; | 
| +} | 
| + | 
| +std::unique_ptr<content::NavigationThrottle> | 
| +ContentSubresourceFilterThrottleManager:: | 
| + MaybeCreateActivationStateComputingThrottle( | 
| + content::NavigationHandle* navigation_handle) { | 
| + if (navigation_handle->IsSamePage()) | 
| + return nullptr; | 
| + | 
| + // Main frames: create unconditionally. | 
| + if (navigation_handle->IsInMainFrame()) | 
| + return ActivationStateComputingNavigationThrottle::CreateForMainFrame( | 
| + navigation_handle); | 
| + | 
| + // Subframes: create only for frames with activated parents. | 
| + FrameActivationInfo* info = | 
| + GetFrameActivationInfoForChildNavigation(navigation_handle); | 
| + if (!info) | 
| + return nullptr; | 
| + DCHECK(ruleset_handle_); | 
| + return ActivationStateComputingNavigationThrottle::CreateForSubframe( | 
| + navigation_handle, ruleset_handle_.get(), info->activation_state, | 
| + base::Bind(&Delegate::OnFirstSubresourceLoadDisallowed, | 
| + delegate_->AsWeakPtr())); | 
| +} | 
| + | 
| +FrameActivationInfo* ContentSubresourceFilterThrottleManager:: | 
| + GetFrameActivationInfoForChildNavigation( | 
| + content::NavigationHandle* child_frame_navigation) { | 
| + DCHECK(!child_frame_navigation->IsInMainFrame()); | 
| + content::RenderFrameHost* parent = web_contents()->FindFrameByFrameTreeNodeId( | 
| + child_frame_navigation->GetParentFrameTreeNodeId()); | 
| + DCHECK(parent); | 
| + auto it = activated_frame_hosts_.find(parent); | 
| + return it == activated_frame_hosts_.end() ? nullptr : it->second.get(); | 
| +} | 
| + | 
| +VerifiedRuleset::Handle* | 
| +ContentSubresourceFilterThrottleManager::EnsureRulesetHandle() { | 
| + if (!ruleset_handle_) | 
| + ruleset_handle_ = base::MakeUnique<VerifiedRuleset::Handle>(dealer_handle_); | 
| + return ruleset_handle_.get(); | 
| +} | 
| + | 
| +} // namespace subresource_filter |