Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/subresource_filter/content/browser/content_subresource_filt er_throttle_manager.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/memory/ptr_util.h" | |
| 9 #include "components/subresource_filter/content/browser/activation_state_computi ng_navigation_throttle.h" | |
| 10 #include "components/subresource_filter/content/browser/async_document_subresour ce_filter.h" | |
| 11 #include "components/subresource_filter/content/browser/subframe_navigation_filt ering_throttle.h" | |
| 12 #include "content/public/browser/navigation_handle.h" | |
| 13 #include "content/public/browser/render_frame_host.h" | |
| 14 #include "content/public/browser/web_contents.h" | |
| 15 | |
| 16 namespace subresource_filter { | |
| 17 | |
| 18 FrameActivationInfo::FrameActivationInfo() {} | |
| 19 FrameActivationInfo::~FrameActivationInfo() {} | |
| 20 | |
| 21 bool ContentSubresourceFilterThrottleManager::Delegate::ShouldVetoActivation( | |
| 22 content::NavigationHandle* navigation_handle) { | |
| 23 return false; | |
| 24 } | |
| 25 | |
| 26 ContentSubresourceFilterThrottleManager:: | |
| 27 ContentSubresourceFilterThrottleManager( | |
| 28 Delegate* delegate, | |
| 29 VerifiedRulesetDealer::Handle* dealer_handle, | |
| 30 content::WebContents* web_contents) | |
| 31 : content::WebContentsObserver(web_contents), | |
| 32 dealer_handle_(dealer_handle), | |
| 33 delegate_(delegate), | |
| 34 weak_ptr_factory_(this) {} | |
| 35 | |
| 36 ContentSubresourceFilterThrottleManager:: | |
| 37 ~ContentSubresourceFilterThrottleManager() {} | |
| 38 | |
| 39 void ContentSubresourceFilterThrottleManager::NotifyPageActivationComputed( | |
| 40 content::NavigationHandle* activated_navigation, | |
| 41 const ActivationState& activation_state) { | |
| 42 DCHECK(activated_navigation->IsInMainFrame()); | |
|
engedy
2017/02/20 15:58:13
For DCHECK: #include "base/logging.h"
Charlie Harrison
2017/03/01 00:02:56
Done.
| |
| 43 DCHECK(!activated_navigation->HasCommitted()); | |
| 44 auto it = ongoing_activation_throttles_.find(activated_navigation); | |
| 45 if (it != ongoing_activation_throttles_.end()) { | |
| 46 it->second->NotifyPageActivationWithRuleset( | |
| 47 EnsureRulesetHandle(), activation_state, | |
| 48 base::Bind(&ContentSubresourceFilterThrottleManager:: | |
| 49 MaybeCallFirstDisallowedLoad, | |
| 50 weak_ptr_factory_.GetWeakPtr())); | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 void ContentSubresourceFilterThrottleManager::RenderFrameDeleted( | |
| 55 content::RenderFrameHost* frame_host) { | |
| 56 activated_frame_hosts_.erase(frame_host); | |
| 57 DestroyRulesetHandleIfNecessary(); | |
| 58 } | |
| 59 | |
| 60 // Pull the AsyncDocumentSubresourceFilter and its associated ActivationState | |
| 61 // out of the activation state computing throttle. Store it for later filtering | |
| 62 // of subframe navigations. | |
| 63 void ContentSubresourceFilterThrottleManager::ReadyToCommitNavigation( | |
| 64 content::NavigationHandle* navigation_handle) { | |
| 65 content::RenderFrameHost* frame_host = | |
| 66 navigation_handle->GetRenderFrameHost(); | |
| 67 // Make sure that if the committed navigation is in a RenderFrameHost that is | |
| 68 // already activated, the activation state is reset. This is important in the | |
| 69 // case where this navigation does *not* trigger activation. | |
| 70 activated_frame_hosts_.erase(frame_host); | |
| 71 | |
| 72 auto throttle = ongoing_activation_throttles_.find(navigation_handle); | |
| 73 if (throttle == ongoing_activation_throttles_.end()) { | |
| 74 DestroyRulesetHandleIfNecessary(); | |
| 75 return; | |
| 76 } | |
| 77 | |
| 78 const ActivationState& activation_state = | |
| 79 throttle->second->GetActivationState(); | |
| 80 if (activation_state.activation_level == ActivationLevel::DISABLED || | |
| 81 delegate_->ShouldVetoActivation(navigation_handle)) { | |
| 82 DestroyRulesetHandleIfNecessary(); | |
| 83 return; | |
| 84 } | |
| 85 | |
| 86 auto info = base::MakeUnique<FrameActivationInfo>(); | |
| 87 info->subresource_filter = throttle->second->ReleaseFilter(); | |
| 88 info->activation_state = activation_state; | |
| 89 DCHECK(info->subresource_filter); | |
| 90 activated_frame_hosts_[frame_host] = std::move(info); | |
| 91 // TODO(csharrison): Send an IPC to the renderer. | |
| 92 } | |
| 93 | |
| 94 void ContentSubresourceFilterThrottleManager::DidFinishNavigation( | |
| 95 content::NavigationHandle* navigation_handle) { | |
| 96 ongoing_activation_throttles_.erase(navigation_handle); | |
| 97 if (navigation_handle->IsInMainFrame() && navigation_handle->HasCommitted()) | |
|
engedy
2017/02/20 15:58:13
Do we need to check non-same-page here?
Charlie Harrison
2017/03/01 00:02:56
Yep, great catch. Adding this to the testing TODO.
| |
| 98 current_committed_load_has_notified_disallowed_load_ = false; | |
| 99 } | |
| 100 | |
| 101 void ContentSubresourceFilterThrottleManager::MaybeAppendNavigationThrottles( | |
| 102 content::NavigationHandle* navigation_handle, | |
| 103 std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) { | |
| 104 DCHECK(!navigation_handle->IsSamePage()); | |
| 105 if (std::unique_ptr<content::NavigationThrottle> filtering_throttle = | |
| 106 MaybeCreateSubframeNavigationFilteringThrottle(navigation_handle)) { | |
| 107 throttles->push_back(std::move(filtering_throttle)); | |
| 108 } | |
| 109 if (std::unique_ptr<content::NavigationThrottle> activation_throttle = | |
| 110 MaybeCreateActivationStateComputingThrottle(navigation_handle)) { | |
| 111 throttles->push_back(std::move(activation_throttle)); | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 std::unique_ptr<content::NavigationThrottle> | |
| 116 ContentSubresourceFilterThrottleManager:: | |
| 117 MaybeCreateSubframeNavigationFilteringThrottle( | |
| 118 content::NavigationHandle* navigation_handle) { | |
| 119 if (navigation_handle->IsInMainFrame()) | |
| 120 return nullptr; | |
| 121 FrameActivationInfo* info = | |
| 122 GetFrameActivationInfoForChildNavigation(navigation_handle); | |
|
engedy
2017/02/20 15:58:13
nit: What do you think about:
FrameActivationInfo
Charlie Harrison
2017/03/01 00:02:56
I like it (modified slightly for the removal of Fr
| |
| 123 return info ? base::MakeUnique<SubframeNavigationFilteringThrottle>( | |
| 124 navigation_handle, info->subresource_filter.get()) | |
| 125 : nullptr; | |
| 126 } | |
| 127 | |
| 128 std::unique_ptr<content::NavigationThrottle> | |
| 129 ContentSubresourceFilterThrottleManager:: | |
| 130 MaybeCreateActivationStateComputingThrottle( | |
| 131 content::NavigationHandle* navigation_handle) { | |
| 132 // Main frames: create unconditionally. | |
| 133 if (navigation_handle->IsInMainFrame()) | |
|
engedy
2017/02/20 15:58:13
style nit: {}
Charlie Harrison
2017/03/01 00:02:56
Done.
| |
| 134 return ActivationStateComputingNavigationThrottle::CreateForMainFrame( | |
| 135 navigation_handle); | |
| 136 | |
| 137 // Subframes: create only for frames with activated parents. | |
| 138 FrameActivationInfo* info = | |
|
engedy
2017/02/20 15:58:13
nit: s/info/parent_info/
Charlie Harrison
2017/03/01 00:02:56
Done.
| |
| 139 GetFrameActivationInfoForChildNavigation(navigation_handle); | |
| 140 if (!info) | |
| 141 return nullptr; | |
| 142 DCHECK(ruleset_handle_); | |
| 143 return ActivationStateComputingNavigationThrottle::CreateForSubframe( | |
| 144 navigation_handle, ruleset_handle_.get(), info->activation_state, | |
| 145 base::Bind(&ContentSubresourceFilterThrottleManager:: | |
| 146 MaybeCallFirstDisallowedLoad, | |
| 147 weak_ptr_factory_.GetWeakPtr())); | |
| 148 } | |
| 149 | |
| 150 FrameActivationInfo* ContentSubresourceFilterThrottleManager:: | |
| 151 GetFrameActivationInfoForChildNavigation( | |
| 152 content::NavigationHandle* child_frame_navigation) { | |
| 153 DCHECK(!child_frame_navigation->IsInMainFrame()); | |
| 154 content::RenderFrameHost* parent = web_contents()->FindFrameByFrameTreeNodeId( | |
| 155 child_frame_navigation->GetParentFrameTreeNodeId()); | |
| 156 DCHECK(parent); | |
| 157 auto it = activated_frame_hosts_.find(parent); | |
| 158 return it == activated_frame_hosts_.end() ? nullptr : it->second.get(); | |
| 159 } | |
| 160 | |
| 161 void ContentSubresourceFilterThrottleManager::MaybeCallFirstDisallowedLoad() { | |
| 162 if (current_committed_load_has_notified_disallowed_load_) | |
| 163 return; | |
| 164 delegate_->OnFirstSubresourceLoadDisallowed(); | |
| 165 current_committed_load_has_notified_disallowed_load_ = true; | |
| 166 } | |
| 167 | |
| 168 VerifiedRuleset::Handle* | |
| 169 ContentSubresourceFilterThrottleManager::EnsureRulesetHandle() { | |
| 170 if (!ruleset_handle_) | |
| 171 ruleset_handle_ = base::MakeUnique<VerifiedRuleset::Handle>(dealer_handle_); | |
| 172 return ruleset_handle_.get(); | |
| 173 } | |
| 174 | |
| 175 void ContentSubresourceFilterThrottleManager:: | |
| 176 DestroyRulesetHandleIfNecessary() { | |
| 177 if (activated_frame_hosts_.size() == 0) | |
| 178 ruleset_handle_.reset(); | |
| 179 } | |
| 180 | |
| 181 } // namespace subresource_filter | |
| OLD | NEW |