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 |