Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: extensions/renderer/script_injection_manager.cc

Issue 934763003: Refactoring: de-couple Extensions from "script injection System" [render side]:3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@decouple_brower_isolated_world_routingid_user_script_1
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « extensions/renderer/script_injection_manager.h ('k') | extensions/renderer/user_script_set.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 case UserScript::UNDEFINED: 46 case UserScript::UNDEFINED:
47 case UserScript::RUN_DEFERRED: 47 case UserScript::RUN_DEFERRED:
48 case UserScript::BROWSER_DRIVEN: 48 case UserScript::BROWSER_DRIVEN:
49 case UserScript::RUN_LOCATION_LAST: 49 case UserScript::RUN_LOCATION_LAST:
50 break; 50 break;
51 } 51 }
52 NOTREACHED(); 52 NOTREACHED();
53 return UserScript::RUN_LOCATION_LAST; 53 return UserScript::RUN_LOCATION_LAST;
54 } 54 }
55 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
70 } // namespace 56 } // namespace
71 57
72 class ScriptInjectionManager::RVOHelper : public content::RenderViewObserver { 58 class ScriptInjectionManager::RVOHelper : public content::RenderViewObserver {
73 public: 59 public:
74 RVOHelper(content::RenderView* render_view, ScriptInjectionManager* manager); 60 RVOHelper(content::RenderView* render_view, ScriptInjectionManager* manager);
75 ~RVOHelper() override; 61 ~RVOHelper() override;
76 62
77 private: 63 private:
78 // RenderViewObserver implementation. 64 // RenderViewObserver implementation.
79 bool OnMessageReceived(const IPC::Message& message) override; 65 bool OnMessageReceived(const IPC::Message& message) override;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 } 235 }
250 236
251 ScriptInjectionManager::~ScriptInjectionManager() { 237 ScriptInjectionManager::~ScriptInjectionManager() {
252 } 238 }
253 239
254 void ScriptInjectionManager::OnRenderViewCreated( 240 void ScriptInjectionManager::OnRenderViewCreated(
255 content::RenderView* render_view) { 241 content::RenderView* render_view) {
256 rvo_helpers_.push_back(new RVOHelper(render_view, this)); 242 rvo_helpers_.push_back(new RVOHelper(render_view, this));
257 } 243 }
258 244
245 void 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 }
256 // If we are currently injection scripts, we need to make a note that this
257 // extension is "dirty" (invalidated).
258 if (injecting_scripts_)
259 invalidated_while_injecting_.insert(extension_id);
260 }
261
259 void ScriptInjectionManager::OnUserScriptsUpdated( 262 void ScriptInjectionManager::OnUserScriptsUpdated(
260 const std::set<std::string>& changed_extensions, 263 const std::set<std::string>& changed_extensions,
261 const std::vector<UserScript*>& scripts) { 264 const std::vector<UserScript*>& scripts) {
262 for (ScopedVector<ScriptInjection>::iterator iter = 265 for (ScopedVector<ScriptInjection>::iterator iter =
263 pending_injections_.begin(); 266 pending_injections_.begin();
264 iter != pending_injections_.end();) { 267 iter != pending_injections_.end();) {
265 if (changed_extensions.count((*iter)->host_id().id()) > 0) 268 if (changed_extensions.count((*iter)->host_id().id()) > 0)
266 iter = pending_injections_.erase(iter); 269 iter = pending_injections_.erase(iter);
267 else 270 else
268 ++iter; 271 ++iter;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 &frame_injections, frame, tab_id, run_location); 388 &frame_injections, frame, tab_id, run_location);
386 389
387 ScriptsRunInfo scripts_run_info; 390 ScriptsRunInfo scripts_run_info;
388 for (ScopedVector<ScriptInjection>::iterator iter = frame_injections.begin(); 391 for (ScopedVector<ScriptInjection>::iterator iter = frame_injections.begin();
389 iter != frame_injections.end();) { 392 iter != frame_injections.end();) {
390 // If a blocking script was injected, there is potentially a possibility 393 // If a blocking script was injected, there is potentially a possibility
391 // that the frame has been invalidated in the time since. Check. 394 // that the frame has been invalidated in the time since. Check.
392 if (!IsFrameValid(frame)) 395 if (!IsFrameValid(frame))
393 break; 396 break;
394 397
395 const std::string& extension_id = (*iter)->host_id().id(); 398 // Try to inject the script if the injection host is not "dirty"
396 scoped_ptr<ExtensionInjectionHost> extension_injection_host = 399 // (invalidated by an update). If the injection does not finish
397 GetExtensionInjectionHost(extension_id, extensions_); 400 // (i.e., it is waiting for permission), add it to the list of pending
398 // Try to inject the script if the extension is not "dirty" (invalidated by 401 // injections.
399 // an update). If the injection does not finish (i.e., it is waiting for 402 if (invalidated_while_injecting_.count((*iter)->host_id().id()) == 0 &&
400 // permission), add it to the list of pending injections.
401 if (invalidated_while_injecting_.count(extension_id) == 0 &&
402 !(*iter)->TryToInject(run_location, 403 !(*iter)->TryToInject(run_location,
403 extension_injection_host.get(),
404 &scripts_run_info)) { 404 &scripts_run_info)) {
405 pending_injections_.insert(pending_injections_.begin(), *iter); 405 pending_injections_.insert(pending_injections_.begin(), *iter);
406 iter = frame_injections.weak_erase(iter); 406 iter = frame_injections.weak_erase(iter);
407 } else { 407 } else {
408 ++iter; 408 ++iter;
409 } 409 }
410 } 410 }
411 411
412 if (IsFrameValid(frame)) 412 if (IsFrameValid(frame))
413 scripts_run_info.LogRun(frame, run_location); 413 scripts_run_info.LogRun(frame, run_location);
(...skipping 12 matching lines...) Expand all
426 if (!main_frame) { 426 if (!main_frame) {
427 render_view->Send( 427 render_view->Send(
428 new ExtensionHostMsg_ExecuteCodeFinished(render_view->GetRoutingID(), 428 new ExtensionHostMsg_ExecuteCodeFinished(render_view->GetRoutingID(),
429 params.request_id, 429 params.request_id,
430 "No main frame", 430 "No main frame",
431 GURL(std::string()), 431 GURL(std::string()),
432 base::ListValue())); 432 base::ListValue()));
433 return; 433 return;
434 } 434 }
435 435
436 scoped_ptr<const ExtensionInjectionHost> extension_injection_host =
437 ExtensionInjectionHost::Create(params.extension_id, extensions_);
438
439 if (!extension_injection_host)
440 return;
441
436 scoped_ptr<ScriptInjection> injection(new ScriptInjection( 442 scoped_ptr<ScriptInjection> injection(new ScriptInjection(
437 scoped_ptr<ScriptInjector>( 443 scoped_ptr<ScriptInjector>(
438 new ProgrammaticScriptInjector(params, main_frame)), 444 new ProgrammaticScriptInjector(params, main_frame)),
439 main_frame, 445 main_frame,
440 HostID(HostID::EXTENSIONS, params.extension_id), 446 extension_injection_host.Pass(),
441 static_cast<UserScript::RunLocation>(params.run_at), 447 static_cast<UserScript::RunLocation>(params.run_at),
442 ExtensionHelper::Get(render_view)->tab_id())); 448 ExtensionHelper::Get(render_view)->tab_id()));
443 449
444 ScriptsRunInfo scripts_run_info; 450 ScriptsRunInfo scripts_run_info;
445 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame); 451 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame);
446 452
447 scoped_ptr<ExtensionInjectionHost> extension_injection_host =
448 GetExtensionInjectionHost(injection->host_id().id(), extensions_);
449
450 if (!injection->TryToInject( 453 if (!injection->TryToInject(
451 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second, 454 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second,
452 extension_injection_host.get(),
453 &scripts_run_info)) { 455 &scripts_run_info)) {
454 pending_injections_.push_back(injection.release()); 456 pending_injections_.push_back(injection.release());
455 } 457 }
456 } 458 }
457 459
458 void ScriptInjectionManager::HandleExecuteDeclarativeScript( 460 void ScriptInjectionManager::HandleExecuteDeclarativeScript(
459 blink::WebFrame* web_frame, 461 blink::WebFrame* web_frame,
460 int tab_id, 462 int tab_id,
461 const ExtensionId& extension_id, 463 const ExtensionId& extension_id,
462 int script_id, 464 int script_id,
463 const GURL& url) { 465 const GURL& url) {
464 scoped_ptr<ExtensionInjectionHost> extension_injection_host =
465 GetExtensionInjectionHost(extension_id, extensions_);
466 const Extension* extension = extensions_->GetByID(extension_id);
467 // TODO(dcheng): This function signature should really be a WebLocalFrame, 466 // TODO(dcheng): This function signature should really be a WebLocalFrame,
468 // rather than trying to coerce it here. 467 // rather than trying to coerce it here.
469 scoped_ptr<ScriptInjection> injection = 468 scoped_ptr<ScriptInjection> injection =
470 user_script_set_manager_->GetInjectionForDeclarativeScript( 469 user_script_set_manager_->GetInjectionForDeclarativeScript(
471 script_id, 470 script_id,
472 web_frame->toWebLocalFrame(), 471 web_frame->toWebLocalFrame(),
473 tab_id, 472 tab_id,
474 url, 473 url,
475 extension); 474 extension_id);
476 if (injection.get()) { 475 if (injection) {
477 ScriptsRunInfo scripts_run_info; 476 ScriptsRunInfo scripts_run_info;
478 // TODO(markdittmer): Use return value of TryToInject for error handling. 477 // TODO(markdittmer): Use return value of TryToInject for error handling.
479 injection->TryToInject(UserScript::BROWSER_DRIVEN, 478 injection->TryToInject(UserScript::BROWSER_DRIVEN,
480 extension_injection_host.get(),
481 &scripts_run_info); 479 &scripts_run_info);
482 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN); 480 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN);
483 } 481 }
484 } 482 }
485 483
486 void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) { 484 void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) {
487 ScopedVector<ScriptInjection>::iterator iter = 485 ScopedVector<ScriptInjection>::iterator iter =
488 pending_injections_.begin(); 486 pending_injections_.begin();
489 for (; iter != pending_injections_.end(); ++iter) { 487 for (; iter != pending_injections_.end(); ++iter) {
490 if ((*iter)->request_id() == request_id) 488 if ((*iter)->request_id() == request_id) {
489 DCHECK((*iter)->host_id().type() == HostID::EXTENSIONS);
491 break; 490 break;
491 }
492 } 492 }
493 if (iter == pending_injections_.end()) 493 if (iter == pending_injections_.end())
494 return; 494 return;
495 495
496 // At this point, because the request is present in pending_injections_, we 496 // At this point, because the request is present in pending_injections_, we
497 // know that this is the same page that issued the request (otherwise, 497 // know that this is the same page that issued the request (otherwise,
498 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be 498 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be
499 // cleared out). 499 // cleared out).
500 500
501 scoped_ptr<ScriptInjection> injection(*iter); 501 scoped_ptr<ScriptInjection> injection(*iter);
502 pending_injections_.weak_erase(iter); 502 pending_injections_.weak_erase(iter);
503 503
504 ScriptsRunInfo scripts_run_info; 504 ScriptsRunInfo scripts_run_info;
505 scoped_ptr<ExtensionInjectionHost> extension_injection_host = 505 if (injection->OnPermissionGranted(&scripts_run_info)) {
506 GetExtensionInjectionHost(injection->host_id().id(), extensions_);
507 if (injection->OnPermissionGranted(extension_injection_host.get(),
508 &scripts_run_info)) {
509 scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED); 506 scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED);
510 } 507 }
511 } 508 }
512 509
513 } // namespace extensions 510 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/script_injection_manager.h ('k') | extensions/renderer/user_script_set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698