blob: f758b95015afa057c521051497c8fe5e1144a8fd [file] [log] [blame]
[email protected]ac2f89372014-06-23 21:44:251// Copyright 2014 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 "extensions/renderer/script_injection_manager.h"
6
rdevlin.cronin1463eeaf2014-12-11 18:06:567#include "base/auto_reset.h"
[email protected]ac2f89372014-06-23 21:44:258#include "base/bind.h"
9#include "base/memory/weak_ptr.h"
[email protected]ac2f89372014-06-23 21:44:2510#include "base/values.h"
alexclarke5f9af5642015-01-09 19:24:3111#include "content/public/renderer/render_thread.h"
[email protected]ac2f89372014-06-23 21:44:2512#include "content/public/renderer/render_view.h"
13#include "content/public/renderer/render_view_observer.h"
14#include "extensions/common/extension.h"
15#include "extensions/common/extension_messages.h"
16#include "extensions/common/extension_set.h"
17#include "extensions/renderer/extension_helper.h"
hanxia5c856cf2015-02-13 20:51:5818#include "extensions/renderer/extension_injection_host.h"
[email protected]c11e6592014-06-27 17:07:3419#include "extensions/renderer/programmatic_script_injector.h"
20#include "extensions/renderer/script_injection.h"
21#include "extensions/renderer/scripts_run_info.h"
hanxi79f7a572015-03-09 20:46:5922#include "extensions/renderer/web_ui_injection_host.h"
[email protected]ac2f89372014-06-23 21:44:2523#include "ipc/ipc_message_macros.h"
markdittmer9ea140f2014-08-29 02:46:1524#include "third_party/WebKit/public/web/WebDocument.h"
[email protected]ac2f89372014-06-23 21:44:2525#include "third_party/WebKit/public/web/WebFrame.h"
26#include "third_party/WebKit/public/web/WebLocalFrame.h"
27#include "third_party/WebKit/public/web/WebView.h"
28#include "url/gurl.h"
29
30namespace extensions {
31
32namespace {
33
34// The length of time to wait after the DOM is complete to try and run user
35// scripts.
36const int kScriptIdleTimeoutInMs = 200;
37
rdevlin.cronin1463eeaf2014-12-11 18:06:5638// Returns the RunLocation that follows |run_location|.
39UserScript::RunLocation NextRunLocation(UserScript::RunLocation run_location) {
40 switch (run_location) {
41 case UserScript::DOCUMENT_START:
42 return UserScript::DOCUMENT_END;
43 case UserScript::DOCUMENT_END:
44 return UserScript::DOCUMENT_IDLE;
45 case UserScript::DOCUMENT_IDLE:
46 return UserScript::RUN_LOCATION_LAST;
47 case UserScript::UNDEFINED:
48 case UserScript::RUN_DEFERRED:
49 case UserScript::BROWSER_DRIVEN:
50 case UserScript::RUN_LOCATION_LAST:
51 break;
52 }
53 NOTREACHED();
54 return UserScript::RUN_LOCATION_LAST;
55}
56
[email protected]ac2f89372014-06-23 21:44:2557} // namespace
58
59class ScriptInjectionManager::RVOHelper : public content::RenderViewObserver {
60 public:
61 RVOHelper(content::RenderView* render_view, ScriptInjectionManager* manager);
dcheng9168b2f2014-10-21 12:38:2462 ~RVOHelper() override;
[email protected]ac2f89372014-06-23 21:44:2563
64 private:
65 // RenderViewObserver implementation.
dcheng9168b2f2014-10-21 12:38:2466 bool OnMessageReceived(const IPC::Message& message) override;
rob5ef11ff2014-11-17 23:56:2067 void DidCreateNewDocument(blink::WebLocalFrame* frame) override;
dcheng9168b2f2014-10-21 12:38:2468 void DidCreateDocumentElement(blink::WebLocalFrame* frame) override;
69 void DidFinishDocumentLoad(blink::WebLocalFrame* frame) override;
70 void DidFinishLoad(blink::WebLocalFrame* frame) override;
dcheng9168b2f2014-10-21 12:38:2471 void FrameDetached(blink::WebFrame* frame) override;
72 void OnDestruct() override;
[email protected]ac2f89372014-06-23 21:44:2573
74 virtual void OnExecuteCode(const ExtensionMsg_ExecuteCode_Params& params);
markdittmer9ea140f2014-08-29 02:46:1575 virtual void OnExecuteDeclarativeScript(int tab_id,
76 const ExtensionId& extension_id,
77 int script_id,
78 const GURL& url);
[email protected]ac2f89372014-06-23 21:44:2579 virtual void OnPermitScriptInjection(int64 request_id);
80
81 // Tells the ScriptInjectionManager to run tasks associated with
82 // document_idle.
83 void RunIdle(blink::WebFrame* frame);
84
[email protected]5672620d2014-07-30 10:07:1785 // Indicate that the given |frame| is no longer valid because it is starting
86 // a new load or closing.
87 void InvalidateFrame(blink::WebFrame* frame);
88
89 // The owning ScriptInjectionManager.
[email protected]ac2f89372014-06-23 21:44:2590 ScriptInjectionManager* manager_;
[email protected]5672620d2014-07-30 10:07:1791
92 // The set of frames that we are about to notify for DOCUMENT_IDLE. We keep
93 // a set of those that are valid, so we don't notify that an invalid frame
94 // became idle.
95 std::set<blink::WebFrame*> pending_idle_frames_;
96
[email protected]ac2f89372014-06-23 21:44:2597 base::WeakPtrFactory<RVOHelper> weak_factory_;
98};
99
100ScriptInjectionManager::RVOHelper::RVOHelper(
101 content::RenderView* render_view,
102 ScriptInjectionManager* manager)
103 : content::RenderViewObserver(render_view),
104 manager_(manager),
105 weak_factory_(this) {
106}
107
108ScriptInjectionManager::RVOHelper::~RVOHelper() {
109}
110
111bool ScriptInjectionManager::RVOHelper::OnMessageReceived(
112 const IPC::Message& message) {
113 bool handled = true;
114 IPC_BEGIN_MESSAGE_MAP(ScriptInjectionManager::RVOHelper, message)
115 IPC_MESSAGE_HANDLER(ExtensionMsg_ExecuteCode, OnExecuteCode)
116 IPC_MESSAGE_HANDLER(ExtensionMsg_PermitScriptInjection,
117 OnPermitScriptInjection)
markdittmer9ea140f2014-08-29 02:46:15118 IPC_MESSAGE_HANDLER(ExtensionMsg_ExecuteDeclarativeScript,
119 OnExecuteDeclarativeScript)
[email protected]ac2f89372014-06-23 21:44:25120 IPC_MESSAGE_UNHANDLED(handled = false)
121 IPC_END_MESSAGE_MAP()
122 return handled;
123}
124
rob5ef11ff2014-11-17 23:56:20125void ScriptInjectionManager::RVOHelper::DidCreateNewDocument(
126 blink::WebLocalFrame* frame) {
127 // A new document is going to be shown, so invalidate the old document state.
128 // Check that the frame's state is known before invalidating the frame,
129 // because it is possible that a script injection was scheduled before the
130 // page was loaded, e.g. by navigating to a javascript: URL before the page
131 // has loaded.
132 if (manager_->frame_statuses_.find(frame) != manager_->frame_statuses_.end())
133 InvalidateFrame(frame);
134}
135
[email protected]ac2f89372014-06-23 21:44:25136void ScriptInjectionManager::RVOHelper::DidCreateDocumentElement(
137 blink::WebLocalFrame* frame) {
rdevlin.cronin1463eeaf2014-12-11 18:06:56138 manager_->StartInjectScripts(frame, UserScript::DOCUMENT_START);
[email protected]ac2f89372014-06-23 21:44:25139}
140
141void ScriptInjectionManager::RVOHelper::DidFinishDocumentLoad(
142 blink::WebLocalFrame* frame) {
rdevlin.cronin1463eeaf2014-12-11 18:06:56143 manager_->StartInjectScripts(frame, UserScript::DOCUMENT_END);
[email protected]5672620d2014-07-30 10:07:17144 pending_idle_frames_.insert(frame);
145 // We try to run idle in two places: here and DidFinishLoad.
146 // DidFinishDocumentLoad() corresponds to completing the document's load,
147 // whereas DidFinishLoad corresponds to completing the document and all
148 // subresources' load. We don't want to hold up script injection for a
149 // particularly slow subresource, so we set a delayed task from here - but if
150 // we finish everything before that point (i.e., DidFinishLoad() is
151 // triggered), then there's no reason to keep waiting.
alexclarke5f9af5642015-01-09 19:24:31152 content::RenderThread::Get()->GetTaskRunner()->PostDelayedTask(
[email protected]ac2f89372014-06-23 21:44:25153 FROM_HERE,
154 base::Bind(&ScriptInjectionManager::RVOHelper::RunIdle,
155 weak_factory_.GetWeakPtr(),
156 frame),
157 base::TimeDelta::FromMilliseconds(kScriptIdleTimeoutInMs));
158}
159
160void ScriptInjectionManager::RVOHelper::DidFinishLoad(
161 blink::WebLocalFrame* frame) {
[email protected]5672620d2014-07-30 10:07:17162 // Ensure that we don't block any UI progress by running scripts.
163 // We *don't* add the frame to |pending_idle_frames_| here because
164 // DidFinishDocumentLoad should strictly come before DidFinishLoad, so the
165 // first posted task to RunIdle() pops it out of the set. This ensures we
166 // don't try to run idle twice.
alexclarke5f9af5642015-01-09 19:24:31167 content::RenderThread::Get()->GetTaskRunner()->PostTask(
[email protected]ac2f89372014-06-23 21:44:25168 FROM_HERE,
169 base::Bind(&ScriptInjectionManager::RVOHelper::RunIdle,
170 weak_factory_.GetWeakPtr(),
171 frame));
172}
173
[email protected]ac2f89372014-06-23 21:44:25174void ScriptInjectionManager::RVOHelper::FrameDetached(blink::WebFrame* frame) {
[email protected]5672620d2014-07-30 10:07:17175 // The frame is closing - invalidate.
176 InvalidateFrame(frame);
[email protected]ac2f89372014-06-23 21:44:25177}
178
179void ScriptInjectionManager::RVOHelper::OnDestruct() {
180 manager_->RemoveObserver(this);
181}
182
183void ScriptInjectionManager::RVOHelper::OnExecuteCode(
184 const ExtensionMsg_ExecuteCode_Params& params) {
185 manager_->HandleExecuteCode(params, render_view());
186}
187
markdittmer9ea140f2014-08-29 02:46:15188void ScriptInjectionManager::RVOHelper::OnExecuteDeclarativeScript(
189 int tab_id,
190 const ExtensionId& extension_id,
191 int script_id,
192 const GURL& url) {
193 blink::WebFrame* main_frame = render_view()->GetWebView()->mainFrame();
194 CHECK(main_frame);
195
196 // TODO(markdittmer): This would be cleaner if we compared page_ids instead.
197 // Begin script injeciton workflow only if the current URL is identical to
198 // the one that matched declarative conditions in the browser.
199 if (main_frame->top()->document().url() == url) {
200 manager_->HandleExecuteDeclarativeScript(main_frame,
201 tab_id,
202 extension_id,
203 script_id,
204 url);
205 }
206}
207
[email protected]ac2f89372014-06-23 21:44:25208void ScriptInjectionManager::RVOHelper::OnPermitScriptInjection(
209 int64 request_id) {
210 manager_->HandlePermitScriptInjection(request_id);
211}
212
213void ScriptInjectionManager::RVOHelper::RunIdle(blink::WebFrame* frame) {
[email protected]5672620d2014-07-30 10:07:17214 // Only notify the manager if the frame hasn't either been removed or already
215 // had idle run since the task to RunIdle() was posted.
216 if (pending_idle_frames_.count(frame) > 0) {
rdevlin.cronin1463eeaf2014-12-11 18:06:56217 manager_->StartInjectScripts(frame, UserScript::DOCUMENT_IDLE);
[email protected]5672620d2014-07-30 10:07:17218 pending_idle_frames_.erase(frame);
219 }
220}
221
222void ScriptInjectionManager::RVOHelper::InvalidateFrame(
223 blink::WebFrame* frame) {
224 pending_idle_frames_.erase(frame);
225 manager_->InvalidateForFrame(frame);
[email protected]ac2f89372014-06-23 21:44:25226}
227
228ScriptInjectionManager::ScriptInjectionManager(
229 const ExtensionSet* extensions,
[email protected]4c356902014-07-30 09:52:02230 UserScriptSetManager* user_script_set_manager)
[email protected]ac2f89372014-06-23 21:44:25231 : extensions_(extensions),
[email protected]4c356902014-07-30 09:52:02232 user_script_set_manager_(user_script_set_manager),
233 user_script_set_manager_observer_(this) {
234 user_script_set_manager_observer_.Add(user_script_set_manager_);
[email protected]ac2f89372014-06-23 21:44:25235}
236
237ScriptInjectionManager::~ScriptInjectionManager() {
238}
239
240void ScriptInjectionManager::OnRenderViewCreated(
241 content::RenderView* render_view) {
242 rvo_helpers_.push_back(new RVOHelper(render_view, this));
243}
244
hanxi9b841662015-03-04 14:36:41245void ScriptInjectionManager::OnExtensionUnloaded(
246 const std::string& extension_id) {
247 for (auto iter = pending_injections_.begin();
248 iter != pending_injections_.end();) {
249 if ((*iter)->host_id().id() == extension_id) {
250 (*iter)->OnHostRemoved();
251 iter = pending_injections_.erase(iter);
252 } else {
253 ++iter;
254 }
255 }
kozyatinskiyc8bc9a582015-03-06 09:33:41256}
257
258void ScriptInjectionManager::OnInjectionFinished(
259 ScriptInjection* injection) {
260 ScopedVector<ScriptInjection>::iterator iter =
261 std::find(running_injections_.begin(),
262 running_injections_.end(),
263 injection);
264 if (iter != running_injections_.end())
265 running_injections_.erase(iter);
hanxi9b841662015-03-04 14:36:41266}
267
[email protected]ac2f89372014-06-23 21:44:25268void ScriptInjectionManager::OnUserScriptsUpdated(
hanxi3df97b22015-03-11 23:40:06269 const std::set<HostID>& changed_hosts,
[email protected]ac2f89372014-06-23 21:44:25270 const std::vector<UserScript*>& scripts) {
271 for (ScopedVector<ScriptInjection>::iterator iter =
272 pending_injections_.begin();
273 iter != pending_injections_.end();) {
hanxi3df97b22015-03-11 23:40:06274 if (changed_hosts.count((*iter)->host_id()) > 0)
[email protected]ac2f89372014-06-23 21:44:25275 iter = pending_injections_.erase(iter);
276 else
277 ++iter;
278 }
279}
280
281void ScriptInjectionManager::RemoveObserver(RVOHelper* helper) {
282 for (ScopedVector<RVOHelper>::iterator iter = rvo_helpers_.begin();
283 iter != rvo_helpers_.end();
284 ++iter) {
285 if (*iter == helper) {
286 rvo_helpers_.erase(iter);
287 break;
288 }
289 }
290}
291
292void ScriptInjectionManager::InvalidateForFrame(blink::WebFrame* frame) {
293 for (ScopedVector<ScriptInjection>::iterator iter =
294 pending_injections_.begin();
295 iter != pending_injections_.end();) {
296 if ((*iter)->web_frame() == frame)
297 iter = pending_injections_.erase(iter);
298 else
299 ++iter;
300 }
301
302 frame_statuses_.erase(frame);
303}
304
rdevlin.cronin1463eeaf2014-12-11 18:06:56305void ScriptInjectionManager::StartInjectScripts(
[email protected]ac2f89372014-06-23 21:44:25306 blink::WebFrame* frame, UserScript::RunLocation run_location) {
307 FrameStatusMap::iterator iter = frame_statuses_.find(frame);
[email protected]5672620d2014-07-30 10:07:17308 // We also don't execute if we detect that the run location is somehow out of
309 // order. This can happen if:
310 // - The first run location reported for the frame isn't DOCUMENT_START, or
311 // - The run location reported doesn't immediately follow the previous
312 // reported run location.
313 // We don't want to run because extensions may have requirements that scripts
314 // running in an earlier run location have run by the time a later script
315 // runs. Better to just not run.
rdevlin.cronin1463eeaf2014-12-11 18:06:56316 // Note that we check run_location > NextRunLocation() in the second clause
317 // (as opposed to !=) because earlier signals (like DidCreateDocumentElement)
318 // can happen multiple times, so we can receive earlier/equal run locations.
[email protected]5672620d2014-07-30 10:07:17319 if ((iter == frame_statuses_.end() &&
320 run_location != UserScript::DOCUMENT_START) ||
rdevlin.cronin1463eeaf2014-12-11 18:06:56321 (iter != frame_statuses_.end() &&
322 run_location > NextRunLocation(iter->second))) {
[email protected]5672620d2014-07-30 10:07:17323 // We also invalidate the frame, because the run order of pending injections
324 // may also be bad.
325 InvalidateForFrame(frame);
326 return;
rdevlin.cronin1463eeaf2014-12-11 18:06:56327 } else if (iter != frame_statuses_.end() && iter->second >= run_location) {
[email protected]5672620d2014-07-30 10:07:17328 // Certain run location signals (like DidCreateDocumentElement) can happen
329 // multiple times. Ignore the subsequent signals.
330 return;
[email protected]ac2f89372014-06-23 21:44:25331 }
332
[email protected]5672620d2014-07-30 10:07:17333 // Otherwise, all is right in the world, and we can get on with the
334 // injections!
[email protected]5672620d2014-07-30 10:07:17335 frame_statuses_[frame] = run_location;
kozyatinskiyc8bc9a582015-03-06 09:33:41336 InjectScripts(frame, run_location);
rdevlin.cronin1463eeaf2014-12-11 18:06:56337}
338
339void ScriptInjectionManager::InjectScripts(
340 blink::WebFrame* frame,
341 UserScript::RunLocation run_location) {
rdevlin.cronind63148dc2014-12-16 19:22:34342 // Find any injections that want to run on the given frame.
rdevlin.cronind63148dc2014-12-16 19:22:34343 ScopedVector<ScriptInjection> frame_injections;
[email protected]ac2f89372014-06-23 21:44:25344 for (ScopedVector<ScriptInjection>::iterator iter =
345 pending_injections_.begin();
346 iter != pending_injections_.end();) {
rdevlin.cronind63148dc2014-12-16 19:22:34347 if ((*iter)->web_frame() == frame) {
348 frame_injections.push_back(*iter);
349 iter = pending_injections_.weak_erase(iter);
[email protected]ac2f89372014-06-23 21:44:25350 } else {
351 ++iter;
352 }
353 }
354
rdevlin.cronind63148dc2014-12-16 19:22:34355 // Add any injections for user scripts.
[email protected]ac2f89372014-06-23 21:44:25356 int tab_id = ExtensionHelper::Get(content::RenderView::FromWebView(
357 frame->top()->view()))->tab_id();
[email protected]4c356902014-07-30 09:52:02358 user_script_set_manager_->GetAllInjections(
rdevlin.cronind63148dc2014-12-16 19:22:34359 &frame_injections, frame, tab_id, run_location);
360
361 ScriptsRunInfo scripts_run_info;
kozyatinskiyc8bc9a582015-03-06 09:33:41362 std::vector<ScriptInjection*> released_injections;
363 frame_injections.release(&released_injections);
364 for (ScriptInjection* injection : released_injections)
365 TryToInject(make_scoped_ptr(injection), run_location, &scripts_run_info);
366
367 scripts_run_info.LogRun(frame, run_location);
368}
369
370void ScriptInjectionManager::TryToInject(
371 scoped_ptr<ScriptInjection> injection,
372 UserScript::RunLocation run_location,
373 ScriptsRunInfo* scripts_run_info) {
374 // Try to inject the script. If the injection is waiting (i.e., for
375 // permission), add it to the list of pending injections. If the injection
376 // has blocked, add it to the list of running injections.
377 switch (injection->TryToInject(
378 run_location,
379 scripts_run_info,
380 this)) {
381 case ScriptInjection::INJECTION_WAITING:
vaibhav1.ad7332682015-05-27 05:45:43382 pending_injections_.push_back(injection.Pass());
rdevlin.cronind63148dc2014-12-16 19:22:34383 break;
kozyatinskiyc8bc9a582015-03-06 09:33:41384 case ScriptInjection::INJECTION_BLOCKED:
vaibhav1.ad7332682015-05-27 05:45:43385 running_injections_.push_back(injection.Pass());
kozyatinskiyc8bc9a582015-03-06 09:33:41386 break;
387 case ScriptInjection::INJECTION_FINISHED:
388 break;
[email protected]ac2f89372014-06-23 21:44:25389 }
[email protected]ac2f89372014-06-23 21:44:25390}
391
392void ScriptInjectionManager::HandleExecuteCode(
393 const ExtensionMsg_ExecuteCode_Params& params,
394 content::RenderView* render_view) {
dcheng2e449172014-09-24 04:30:56395 // TODO(dcheng): Not sure how this can happen today. In an OOPI world, it
396 // would indicate a logic error--the browser must direct this request to the
397 // right renderer process to begin with.
398 blink::WebLocalFrame* main_frame =
399 render_view->GetWebView()->mainFrame()->toWebLocalFrame();
[email protected]ac2f89372014-06-23 21:44:25400 if (!main_frame) {
401 render_view->Send(
402 new ExtensionHostMsg_ExecuteCodeFinished(render_view->GetRoutingID(),
403 params.request_id,
404 "No main frame",
[email protected]ac2f89372014-06-23 21:44:25405 GURL(std::string()),
406 base::ListValue()));
407 return;
408 }
409
hanxi79f7a572015-03-09 20:46:59410 scoped_ptr<const InjectionHost> injection_host;
411 if (params.host_id.type() == HostID::EXTENSIONS) {
412 injection_host = ExtensionInjectionHost::Create(params.host_id.id(),
413 extensions_);
414 if (!injection_host)
415 return;
416 } else if (params.host_id.type() == HostID::WEBUI) {
417 injection_host.reset(
418 new WebUIInjectionHost(params.host_id));
419 }
hanxi9b841662015-03-04 14:36:41420
[email protected]c11e6592014-06-27 17:07:34421 scoped_ptr<ScriptInjection> injection(new ScriptInjection(
422 scoped_ptr<ScriptInjector>(
423 new ProgrammaticScriptInjector(params, main_frame)),
424 main_frame,
hanxi79f7a572015-03-09 20:46:59425 injection_host.Pass(),
[email protected]c11e6592014-06-27 17:07:34426 static_cast<UserScript::RunLocation>(params.run_at),
427 ExtensionHelper::Get(render_view)->tab_id()));
[email protected]ac2f89372014-06-23 21:44:25428
[email protected]c11e6592014-06-27 17:07:34429 ScriptsRunInfo scripts_run_info;
[email protected]ac2f89372014-06-23 21:44:25430 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame);
hanxia5c856cf2015-02-13 20:51:58431
kozyatinskiyc8bc9a582015-03-06 09:33:41432 TryToInject(
433 injection.Pass(),
434 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second,
435 &scripts_run_info);
[email protected]ac2f89372014-06-23 21:44:25436}
437
markdittmer9ea140f2014-08-29 02:46:15438void ScriptInjectionManager::HandleExecuteDeclarativeScript(
439 blink::WebFrame* web_frame,
440 int tab_id,
441 const ExtensionId& extension_id,
442 int script_id,
443 const GURL& url) {
dcheng2e449172014-09-24 04:30:56444 // TODO(dcheng): This function signature should really be a WebLocalFrame,
445 // rather than trying to coerce it here.
markdittmer9ea140f2014-08-29 02:46:15446 scoped_ptr<ScriptInjection> injection =
447 user_script_set_manager_->GetInjectionForDeclarativeScript(
448 script_id,
dcheng2e449172014-09-24 04:30:56449 web_frame->toWebLocalFrame(),
markdittmer9ea140f2014-08-29 02:46:15450 tab_id,
451 url,
hanxi9b841662015-03-04 14:36:41452 extension_id);
kozyatinskiyc8bc9a582015-03-06 09:33:41453 if (injection.get()) {
markdittmer9ea140f2014-08-29 02:46:15454 ScriptsRunInfo scripts_run_info;
455 // TODO(markdittmer): Use return value of TryToInject for error handling.
kozyatinskiyc8bc9a582015-03-06 09:33:41456 TryToInject(injection.Pass(),
457 UserScript::BROWSER_DRIVEN,
458 &scripts_run_info);
459
markdittmer9ea140f2014-08-29 02:46:15460 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN);
461 }
462}
463
[email protected]d2056002014-07-03 06:18:06464void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) {
[email protected]ac2f89372014-06-23 21:44:25465 ScopedVector<ScriptInjection>::iterator iter =
466 pending_injections_.begin();
467 for (; iter != pending_injections_.end(); ++iter) {
hanxi9b841662015-03-04 14:36:41468 if ((*iter)->request_id() == request_id) {
469 DCHECK((*iter)->host_id().type() == HostID::EXTENSIONS);
[email protected]ac2f89372014-06-23 21:44:25470 break;
hanxi9b841662015-03-04 14:36:41471 }
[email protected]ac2f89372014-06-23 21:44:25472 }
473 if (iter == pending_injections_.end())
474 return;
475
[email protected]d2056002014-07-03 06:18:06476 // At this point, because the request is present in pending_injections_, we
477 // know that this is the same page that issued the request (otherwise,
478 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be
479 // cleared out).
480
[email protected]ac2f89372014-06-23 21:44:25481 scoped_ptr<ScriptInjection> injection(*iter);
482 pending_injections_.weak_erase(iter);
483
[email protected]c11e6592014-06-27 17:07:34484 ScriptsRunInfo scripts_run_info;
kozyatinskiyc8bc9a582015-03-06 09:33:41485 ScriptInjection::InjectionResult res = injection->OnPermissionGranted(
486 &scripts_run_info);
487 if (res == ScriptInjection::INJECTION_BLOCKED)
488 running_injections_.push_back(injection.Pass());
489 scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED);
[email protected]ac2f89372014-06-23 21:44:25490}
491
492} // namespace extensions