| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/renderer/script_injection_manager.h" | 5 #include "extensions/renderer/script_injection_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 virtual void OnExecuteDeclarativeScript(int tab_id, | 81 virtual void OnExecuteDeclarativeScript(int tab_id, |
| 82 const ExtensionId& extension_id, | 82 const ExtensionId& extension_id, |
| 83 int script_id, | 83 int script_id, |
| 84 const GURL& url); | 84 const GURL& url); |
| 85 virtual void OnPermitScriptInjection(int64_t request_id); | 85 virtual void OnPermitScriptInjection(int64_t request_id); |
| 86 | 86 |
| 87 // Tells the ScriptInjectionManager to run tasks associated with | 87 // Tells the ScriptInjectionManager to run tasks associated with |
| 88 // document_idle. | 88 // document_idle. |
| 89 void RunIdle(); | 89 void RunIdle(); |
| 90 | 90 |
| 91 void StartInjectScripts(UserScript::RunLocation run_location); |
| 92 |
| 91 // Indicate that the frame is no longer valid because it is starting | 93 // Indicate that the frame is no longer valid because it is starting |
| 92 // a new load or closing. | 94 // a new load or closing. |
| 93 void InvalidateAndResetFrame(); | 95 void InvalidateAndResetFrame(); |
| 94 | 96 |
| 95 // The owning ScriptInjectionManager. | 97 // The owning ScriptInjectionManager. |
| 96 ScriptInjectionManager* manager_; | 98 ScriptInjectionManager* manager_; |
| 97 | 99 |
| 98 bool should_run_idle_; | 100 bool should_run_idle_; |
| 99 | 101 |
| 100 base::WeakPtrFactory<RFOHelper> weak_factory_; | 102 base::WeakPtrFactory<RFOHelper> weak_factory_; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 129 // A new document is going to be shown, so invalidate the old document state. | 131 // A new document is going to be shown, so invalidate the old document state. |
| 130 // Check that the frame's state is known before invalidating the frame, | 132 // Check that the frame's state is known before invalidating the frame, |
| 131 // because it is possible that a script injection was scheduled before the | 133 // because it is possible that a script injection was scheduled before the |
| 132 // page was loaded, e.g. by navigating to a javascript: URL before the page | 134 // page was loaded, e.g. by navigating to a javascript: URL before the page |
| 133 // has loaded. | 135 // has loaded. |
| 134 if (manager_->frame_statuses_.count(render_frame()) != 0) | 136 if (manager_->frame_statuses_.count(render_frame()) != 0) |
| 135 InvalidateAndResetFrame(); | 137 InvalidateAndResetFrame(); |
| 136 } | 138 } |
| 137 | 139 |
| 138 void ScriptInjectionManager::RFOHelper::DidCreateDocumentElement() { | 140 void ScriptInjectionManager::RFOHelper::DidCreateDocumentElement() { |
| 139 manager_->StartInjectScripts(render_frame(), UserScript::DOCUMENT_START); | 141 ExtensionFrameHelper::Get(render_frame()) |
| 142 ->ScheduleAtDocumentStart( |
| 143 base::Bind(&ScriptInjectionManager::RFOHelper::StartInjectScripts, |
| 144 weak_factory_.GetWeakPtr(), UserScript::DOCUMENT_START)); |
| 140 } | 145 } |
| 141 | 146 |
| 142 void ScriptInjectionManager::RFOHelper::DidFailProvisionalLoad( | 147 void ScriptInjectionManager::RFOHelper::DidFailProvisionalLoad( |
| 143 const blink::WebURLError& error) { | 148 const blink::WebURLError& error) { |
| 144 FrameStatusMap::iterator it = manager_->frame_statuses_.find(render_frame()); | 149 FrameStatusMap::iterator it = manager_->frame_statuses_.find(render_frame()); |
| 145 if (it != manager_->frame_statuses_.end() && | 150 if (it != manager_->frame_statuses_.end() && |
| 146 it->second == UserScript::DOCUMENT_START) { | 151 it->second == UserScript::DOCUMENT_START) { |
| 147 // Since the provisional load failed, the frame stays at its previous loaded | 152 // Since the provisional load failed, the frame stays at its previous loaded |
| 148 // state and origin (or the parent's origin for new/about:blank frames). | 153 // state and origin (or the parent's origin for new/about:blank frames). |
| 149 // Reset the frame to DOCUMENT_IDLE in order to reflect that the frame is | 154 // Reset the frame to DOCUMENT_IDLE in order to reflect that the frame is |
| 150 // done loading, and avoid any deadlock in the system. | 155 // done loading, and avoid any deadlock in the system. |
| 151 // | 156 // |
| 152 // We skip injection of DOCUMENT_END and DOCUMENT_IDLE scripts, because the | 157 // We skip injection of DOCUMENT_END and DOCUMENT_IDLE scripts, because the |
| 153 // injections closely follow the DOMContentLoaded (and onload) events, which | 158 // injections closely follow the DOMContentLoaded (and onload) events, which |
| 154 // are not triggered after a failed provisional load. | 159 // are not triggered after a failed provisional load. |
| 155 // This assumption is verified in the checkDOMContentLoadedEvent subtest of | 160 // This assumption is verified in the checkDOMContentLoadedEvent subtest of |
| 156 // ExecuteScriptApiTest.FrameWithHttp204 (browser_tests). | 161 // ExecuteScriptApiTest.FrameWithHttp204 (browser_tests). |
| 157 InvalidateAndResetFrame(); | 162 InvalidateAndResetFrame(); |
| 158 should_run_idle_ = false; | 163 should_run_idle_ = false; |
| 159 manager_->frame_statuses_[render_frame()] = UserScript::DOCUMENT_IDLE; | 164 manager_->frame_statuses_[render_frame()] = UserScript::DOCUMENT_IDLE; |
| 160 } | 165 } |
| 161 } | 166 } |
| 162 | 167 |
| 163 void ScriptInjectionManager::RFOHelper::DidFinishDocumentLoad() { | 168 void ScriptInjectionManager::RFOHelper::DidFinishDocumentLoad() { |
| 164 DCHECK(content::RenderThread::Get()); | 169 DCHECK(content::RenderThread::Get()); |
| 165 manager_->StartInjectScripts(render_frame(), UserScript::DOCUMENT_END); | 170 ExtensionFrameHelper::Get(render_frame()) |
| 171 ->ScheduleAtDocumentEnd( |
| 172 base::Bind(&ScriptInjectionManager::RFOHelper::StartInjectScripts, |
| 173 weak_factory_.GetWeakPtr(), UserScript::DOCUMENT_END)); |
| 174 |
| 166 // We try to run idle in two places: here and DidFinishLoad. | 175 // We try to run idle in two places: here and DidFinishLoad. |
| 167 // DidFinishDocumentLoad() corresponds to completing the document's load, | 176 // DidFinishDocumentLoad() corresponds to completing the document's load, |
| 168 // whereas DidFinishLoad corresponds to completing the document and all | 177 // whereas DidFinishLoad corresponds to completing the document and all |
| 169 // subresources' load. We don't want to hold up script injection for a | 178 // subresources' load. We don't want to hold up script injection for a |
| 170 // particularly slow subresource, so we set a delayed task from here - but if | 179 // particularly slow subresource, so we set a delayed task from here - but if |
| 171 // we finish everything before that point (i.e., DidFinishLoad() is | 180 // we finish everything before that point (i.e., DidFinishLoad() is |
| 172 // triggered), then there's no reason to keep waiting. | 181 // triggered), then there's no reason to keep waiting. |
| 173 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 182 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 174 FROM_HERE, | 183 FROM_HERE, |
| 175 base::Bind(&ScriptInjectionManager::RFOHelper::RunIdle, | 184 base::Bind(&ScriptInjectionManager::RFOHelper::RunIdle, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 | 233 |
| 225 void ScriptInjectionManager::RFOHelper::RunIdle() { | 234 void ScriptInjectionManager::RFOHelper::RunIdle() { |
| 226 // Only notify the manager if the frame hasn't either been removed or already | 235 // Only notify the manager if the frame hasn't either been removed or already |
| 227 // had idle run since the task to RunIdle() was posted. | 236 // had idle run since the task to RunIdle() was posted. |
| 228 if (should_run_idle_) { | 237 if (should_run_idle_) { |
| 229 should_run_idle_ = false; | 238 should_run_idle_ = false; |
| 230 manager_->StartInjectScripts(render_frame(), UserScript::DOCUMENT_IDLE); | 239 manager_->StartInjectScripts(render_frame(), UserScript::DOCUMENT_IDLE); |
| 231 } | 240 } |
| 232 } | 241 } |
| 233 | 242 |
| 243 void ScriptInjectionManager::RFOHelper::StartInjectScripts( |
| 244 UserScript::RunLocation run_location) { |
| 245 manager_->StartInjectScripts(render_frame(), run_location); |
| 246 } |
| 247 |
| 234 void ScriptInjectionManager::RFOHelper::InvalidateAndResetFrame() { | 248 void ScriptInjectionManager::RFOHelper::InvalidateAndResetFrame() { |
| 235 // Invalidate any pending idle injections, and reset the frame inject on idle. | 249 // Invalidate any pending idle injections, and reset the frame inject on idle. |
| 236 weak_factory_.InvalidateWeakPtrs(); | 250 weak_factory_.InvalidateWeakPtrs(); |
| 237 // We reset to inject on idle, because the frame can be reused (in the case of | 251 // We reset to inject on idle, because the frame can be reused (in the case of |
| 238 // navigation). | 252 // navigation). |
| 239 should_run_idle_ = true; | 253 should_run_idle_ = true; |
| 240 manager_->InvalidateForFrame(render_frame()); | 254 manager_->InvalidateForFrame(render_frame()); |
| 241 } | 255 } |
| 242 | 256 |
| 243 ScriptInjectionManager::ScriptInjectionManager( | 257 ScriptInjectionManager::ScriptInjectionManager( |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 ScriptsRunInfo scripts_run_info(injection->render_frame(), | 505 ScriptsRunInfo scripts_run_info(injection->render_frame(), |
| 492 UserScript::RUN_DEFERRED); | 506 UserScript::RUN_DEFERRED); |
| 493 ScriptInjection::InjectionResult res = injection->OnPermissionGranted( | 507 ScriptInjection::InjectionResult res = injection->OnPermissionGranted( |
| 494 &scripts_run_info); | 508 &scripts_run_info); |
| 495 if (res == ScriptInjection::INJECTION_BLOCKED) | 509 if (res == ScriptInjection::INJECTION_BLOCKED) |
| 496 running_injections_.push_back(std::move(injection)); | 510 running_injections_.push_back(std::move(injection)); |
| 497 scripts_run_info.LogRun(); | 511 scripts_run_info.LogRun(); |
| 498 } | 512 } |
| 499 | 513 |
| 500 } // namespace extensions | 514 } // namespace extensions |
| OLD | NEW |