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 "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
11 #include "content/public/renderer/render_thread.h" | 11 #include "content/public/renderer/render_thread.h" |
12 #include "content/public/renderer/render_view.h" | 12 #include "content/public/renderer/render_view.h" |
13 #include "content/public/renderer/render_view_observer.h" | 13 #include "content/public/renderer/render_view_observer.h" |
14 #include "extensions/common/extension.h" | 14 #include "extensions/common/extension.h" |
15 #include "extensions/common/extension_messages.h" | 15 #include "extensions/common/extension_messages.h" |
16 #include "extensions/common/extension_set.h" | 16 #include "extensions/common/extension_set.h" |
17 #include "extensions/renderer/extension_helper.h" | 17 #include "extensions/renderer/extension_helper.h" |
18 #include "extensions/renderer/extension_injection_host.h" | |
18 #include "extensions/renderer/programmatic_script_injector.h" | 19 #include "extensions/renderer/programmatic_script_injector.h" |
19 #include "extensions/renderer/script_injection.h" | 20 #include "extensions/renderer/script_injection.h" |
20 #include "extensions/renderer/scripts_run_info.h" | 21 #include "extensions/renderer/scripts_run_info.h" |
21 #include "ipc/ipc_message_macros.h" | 22 #include "ipc/ipc_message_macros.h" |
22 #include "third_party/WebKit/public/web/WebDocument.h" | 23 #include "third_party/WebKit/public/web/WebDocument.h" |
23 #include "third_party/WebKit/public/web/WebFrame.h" | 24 #include "third_party/WebKit/public/web/WebFrame.h" |
24 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 25 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
25 #include "third_party/WebKit/public/web/WebView.h" | 26 #include "third_party/WebKit/public/web/WebView.h" |
26 #include "url/gurl.h" | 27 #include "url/gurl.h" |
27 | 28 |
(...skipping 17 matching lines...) Expand all Loading... | |
45 case UserScript::UNDEFINED: | 46 case UserScript::UNDEFINED: |
46 case UserScript::RUN_DEFERRED: | 47 case UserScript::RUN_DEFERRED: |
47 case UserScript::BROWSER_DRIVEN: | 48 case UserScript::BROWSER_DRIVEN: |
48 case UserScript::RUN_LOCATION_LAST: | 49 case UserScript::RUN_LOCATION_LAST: |
49 break; | 50 break; |
50 } | 51 } |
51 NOTREACHED(); | 52 NOTREACHED(); |
52 return UserScript::RUN_LOCATION_LAST; | 53 return UserScript::RUN_LOCATION_LAST; |
53 } | 54 } |
54 | 55 |
56 | |
57 // TODO(hanxi): let ScriptInjection own an InjectionHost to avoid constructing | |
58 // an ExtensionInjectionHost many times. | |
59 // Note: the ScriptInjection should be able to know when the backing extension | |
60 // is removed. | |
61 scoped_ptr<ExtensionInjectionHost> GetExtensionInjectionHost( | |
62 const std::string& extension_id, const ExtensionSet* extensions) { | |
63 const Extension* extension = extensions->GetByID(extension_id); | |
64 if (!extension) | |
65 return scoped_ptr<ExtensionInjectionHost>(); | |
66 return scoped_ptr<ExtensionInjectionHost>( | |
67 new ExtensionInjectionHost(extension)); | |
68 } | |
69 | |
55 } // namespace | 70 } // namespace |
56 | 71 |
57 class ScriptInjectionManager::RVOHelper : public content::RenderViewObserver { | 72 class ScriptInjectionManager::RVOHelper : public content::RenderViewObserver { |
58 public: | 73 public: |
59 RVOHelper(content::RenderView* render_view, ScriptInjectionManager* manager); | 74 RVOHelper(content::RenderView* render_view, ScriptInjectionManager* manager); |
60 ~RVOHelper() override; | 75 ~RVOHelper() override; |
61 | 76 |
62 private: | 77 private: |
63 // RenderViewObserver implementation. | 78 // RenderViewObserver implementation. |
64 bool OnMessageReceived(const IPC::Message& message) override; | 79 bool OnMessageReceived(const IPC::Message& message) override; |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 content::RenderView* render_view) { | 255 content::RenderView* render_view) { |
241 rvo_helpers_.push_back(new RVOHelper(render_view, this)); | 256 rvo_helpers_.push_back(new RVOHelper(render_view, this)); |
242 } | 257 } |
243 | 258 |
244 void ScriptInjectionManager::OnUserScriptsUpdated( | 259 void ScriptInjectionManager::OnUserScriptsUpdated( |
245 const std::set<std::string>& changed_extensions, | 260 const std::set<std::string>& changed_extensions, |
246 const std::vector<UserScript*>& scripts) { | 261 const std::vector<UserScript*>& scripts) { |
247 for (ScopedVector<ScriptInjection>::iterator iter = | 262 for (ScopedVector<ScriptInjection>::iterator iter = |
248 pending_injections_.begin(); | 263 pending_injections_.begin(); |
249 iter != pending_injections_.end();) { | 264 iter != pending_injections_.end();) { |
250 if (changed_extensions.count((*iter)->extension_id()) > 0) | 265 if (changed_extensions.count((*iter)->host_id().id()) > 0) |
251 iter = pending_injections_.erase(iter); | 266 iter = pending_injections_.erase(iter); |
252 else | 267 else |
253 ++iter; | 268 ++iter; |
254 } | 269 } |
255 | 270 |
256 // If we are currently injecting scripts, we need to make a note that these | 271 // If we are currently injecting scripts, we need to make a note that these |
257 // extensions were updated. | 272 // extensions were updated. |
258 if (injecting_scripts_) { | 273 if (injecting_scripts_) { |
259 invalidated_while_injecting_.insert(changed_extensions.begin(), | 274 invalidated_while_injecting_.insert(changed_extensions.begin(), |
260 changed_extensions.end()); | 275 changed_extensions.end()); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 &frame_injections, frame, tab_id, run_location); | 385 &frame_injections, frame, tab_id, run_location); |
371 | 386 |
372 ScriptsRunInfo scripts_run_info; | 387 ScriptsRunInfo scripts_run_info; |
373 for (ScopedVector<ScriptInjection>::iterator iter = frame_injections.begin(); | 388 for (ScopedVector<ScriptInjection>::iterator iter = frame_injections.begin(); |
374 iter != frame_injections.end();) { | 389 iter != frame_injections.end();) { |
375 // If a blocking script was injected, there is potentially a possibility | 390 // If a blocking script was injected, there is potentially a possibility |
376 // that the frame has been invalidated in the time since. Check. | 391 // that the frame has been invalidated in the time since. Check. |
377 if (!IsFrameValid(frame)) | 392 if (!IsFrameValid(frame)) |
378 break; | 393 break; |
379 | 394 |
395 const std::string extension_id = (*iter)->host_id().id(); | |
396 scoped_ptr<ExtensionInjectionHost> extension_injection_host = | |
397 GetExtensionInjectionHost(extension_id, extensions_); | |
380 // Try to inject the script if the extension is not "dirty" (invalidated by | 398 // Try to inject the script if the extension is not "dirty" (invalidated by |
381 // an update). If the injection does not finish (i.e., it is waiting for | 399 // an update). If the injection does not finish (i.e., it is waiting for |
382 // permission), add it to the list of pending injections. | 400 // permission), add it to the list of pending injections. |
383 if (invalidated_while_injecting_.count((*iter)->extension_id()) == 0 && | 401 if (invalidated_while_injecting_.count(extension_id) == 0 && |
384 !(*iter)->TryToInject(run_location, | 402 !(*iter)->TryToInject(run_location, |
385 extensions_->GetByID((*iter)->extension_id()), | 403 extension_injection_host.get(), |
386 &scripts_run_info)) { | 404 &scripts_run_info)) { |
387 pending_injections_.insert(pending_injections_.begin(), *iter); | 405 pending_injections_.insert(pending_injections_.begin(), *iter); |
388 iter = frame_injections.weak_erase(iter); | 406 iter = frame_injections.weak_erase(iter); |
389 } else { | 407 } else { |
390 ++iter; | 408 ++iter; |
391 } | 409 } |
392 } | 410 } |
393 | 411 |
394 if (IsFrameValid(frame)) | 412 if (IsFrameValid(frame)) |
395 scripts_run_info.LogRun(frame, run_location); | 413 scripts_run_info.LogRun(frame, run_location); |
(...skipping 16 matching lines...) Expand all Loading... | |
412 "No main frame", | 430 "No main frame", |
413 GURL(std::string()), | 431 GURL(std::string()), |
414 base::ListValue())); | 432 base::ListValue())); |
415 return; | 433 return; |
416 } | 434 } |
417 | 435 |
418 scoped_ptr<ScriptInjection> injection(new ScriptInjection( | 436 scoped_ptr<ScriptInjection> injection(new ScriptInjection( |
419 scoped_ptr<ScriptInjector>( | 437 scoped_ptr<ScriptInjector>( |
420 new ProgrammaticScriptInjector(params, main_frame)), | 438 new ProgrammaticScriptInjector(params, main_frame)), |
421 main_frame, | 439 main_frame, |
422 params.extension_id, | 440 HostID(HostID::EXTENSIONS, params.extension_id), |
441 params.is_web_view ? params.instance_id : HostID::kDefaultInstanceId, | |
Devlin
2015/02/11 00:00:48
I think there was a thread on this part that I los
Xi Han
2015/02/11 16:00:24
Sorry I might not make myself clear. I add this ch
Devlin
2015/02/11 20:19:44
But we already explicitly set params.instance_id t
Xi Han
2015/02/11 21:19:09
As discussed offline, we will remove this check he
| |
423 static_cast<UserScript::RunLocation>(params.run_at), | 442 static_cast<UserScript::RunLocation>(params.run_at), |
424 ExtensionHelper::Get(render_view)->tab_id())); | 443 ExtensionHelper::Get(render_view)->tab_id())); |
425 | 444 |
426 ScriptsRunInfo scripts_run_info; | 445 ScriptsRunInfo scripts_run_info; |
427 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame); | 446 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame); |
447 | |
448 scoped_ptr<ExtensionInjectionHost> extension_injection_host = | |
449 GetExtensionInjectionHost(injection->host_id().id(), extensions_); | |
450 | |
428 if (!injection->TryToInject( | 451 if (!injection->TryToInject( |
429 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second, | 452 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second, |
430 extensions_->GetByID(injection->extension_id()), | 453 extension_injection_host.get(), |
431 &scripts_run_info)) { | 454 &scripts_run_info)) { |
432 pending_injections_.push_back(injection.release()); | 455 pending_injections_.push_back(injection.release()); |
433 } | 456 } |
434 } | 457 } |
435 | 458 |
436 void ScriptInjectionManager::HandleExecuteDeclarativeScript( | 459 void ScriptInjectionManager::HandleExecuteDeclarativeScript( |
437 blink::WebFrame* web_frame, | 460 blink::WebFrame* web_frame, |
438 int tab_id, | 461 int tab_id, |
439 const ExtensionId& extension_id, | 462 const ExtensionId& extension_id, |
440 int script_id, | 463 int script_id, |
441 const GURL& url) { | 464 const GURL& url) { |
465 scoped_ptr<ExtensionInjectionHost> extension_injection_host = | |
466 GetExtensionInjectionHost(extension_id, extensions_); | |
442 const Extension* extension = extensions_->GetByID(extension_id); | 467 const Extension* extension = extensions_->GetByID(extension_id); |
443 // TODO(dcheng): This function signature should really be a WebLocalFrame, | 468 // TODO(dcheng): This function signature should really be a WebLocalFrame, |
444 // rather than trying to coerce it here. | 469 // rather than trying to coerce it here. |
445 scoped_ptr<ScriptInjection> injection = | 470 scoped_ptr<ScriptInjection> injection = |
446 user_script_set_manager_->GetInjectionForDeclarativeScript( | 471 user_script_set_manager_->GetInjectionForDeclarativeScript( |
447 script_id, | 472 script_id, |
448 web_frame->toWebLocalFrame(), | 473 web_frame->toWebLocalFrame(), |
449 tab_id, | 474 tab_id, |
450 url, | 475 url, |
451 extension); | 476 extension); |
452 if (injection.get()) { | 477 if (injection.get()) { |
453 ScriptsRunInfo scripts_run_info; | 478 ScriptsRunInfo scripts_run_info; |
454 // TODO(markdittmer): Use return value of TryToInject for error handling. | 479 // TODO(markdittmer): Use return value of TryToInject for error handling. |
455 injection->TryToInject(UserScript::BROWSER_DRIVEN, | 480 injection->TryToInject(UserScript::BROWSER_DRIVEN, |
456 extension, | 481 extension_injection_host.get(), |
457 &scripts_run_info); | 482 &scripts_run_info); |
458 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN); | 483 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN); |
459 } | 484 } |
460 } | 485 } |
461 | 486 |
462 void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) { | 487 void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) { |
463 ScopedVector<ScriptInjection>::iterator iter = | 488 ScopedVector<ScriptInjection>::iterator iter = |
464 pending_injections_.begin(); | 489 pending_injections_.begin(); |
465 for (; iter != pending_injections_.end(); ++iter) { | 490 for (; iter != pending_injections_.end(); ++iter) { |
466 if ((*iter)->request_id() == request_id) | 491 if ((*iter)->request_id() == request_id) |
467 break; | 492 break; |
468 } | 493 } |
469 if (iter == pending_injections_.end()) | 494 if (iter == pending_injections_.end()) |
470 return; | 495 return; |
471 | 496 |
472 // At this point, because the request is present in pending_injections_, we | 497 // At this point, because the request is present in pending_injections_, we |
473 // know that this is the same page that issued the request (otherwise, | 498 // know that this is the same page that issued the request (otherwise, |
474 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be | 499 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be |
475 // cleared out). | 500 // cleared out). |
476 | 501 |
477 scoped_ptr<ScriptInjection> injection(*iter); | 502 scoped_ptr<ScriptInjection> injection(*iter); |
478 pending_injections_.weak_erase(iter); | 503 pending_injections_.weak_erase(iter); |
479 | 504 |
480 ScriptsRunInfo scripts_run_info; | 505 ScriptsRunInfo scripts_run_info; |
481 if (injection->OnPermissionGranted(extensions_->GetByID( | 506 scoped_ptr<ExtensionInjectionHost> extension_injection_host = |
482 injection->extension_id()), | 507 GetExtensionInjectionHost(injection->host_id().id(), extensions_); |
508 if (injection->OnPermissionGranted(extension_injection_host.get(), | |
483 &scripts_run_info)) { | 509 &scripts_run_info)) { |
484 scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED); | 510 scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED); |
485 } | 511 } |
486 } | 512 } |
487 | 513 |
488 } // namespace extensions | 514 } // namespace extensions |
OLD | NEW |