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

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: Devlin's comments. Created 5 years, 10 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
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();
Devlin 2015/02/23 17:27:38 need a space after 'for'
Xi Han 2015/02/24 16:39:50 Done.
248 iter != pending_injections_.end();) {
249 if ((*iter)->host_id().id() == extension_id) {
250 (*iter)->OnHostRemoved();
251 iter = pending_injections_.erase(iter);
252 }
253 else
Devlin 2015/02/23 17:27:39 bracketing should be if (...) { ... ... } els
Xi Han 2015/02/24 16:39:50 Done.
254 ++iter;
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 params.is_web_view ? UserScript::ConsumerInstanceType::WEBVIEW 447 params.is_web_view ? UserScript::ConsumerInstanceType::WEBVIEW
442 : UserScript::ConsumerInstanceType::TAB, 448 : UserScript::ConsumerInstanceType::TAB,
443 static_cast<UserScript::RunLocation>(params.run_at), 449 static_cast<UserScript::RunLocation>(params.run_at),
444 ExtensionHelper::Get(render_view)->tab_id())); 450 ExtensionHelper::Get(render_view)->tab_id()));
445 451
446 ScriptsRunInfo scripts_run_info; 452 ScriptsRunInfo scripts_run_info;
447 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame); 453 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame);
448 454
449 scoped_ptr<ExtensionInjectionHost> extension_injection_host =
450 GetExtensionInjectionHost(injection->host_id().id(), extensions_);
451
452 if (!injection->TryToInject( 455 if (!injection->TryToInject(
453 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second, 456 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second,
454 extension_injection_host.get(),
455 &scripts_run_info)) { 457 &scripts_run_info)) {
456 pending_injections_.push_back(injection.release()); 458 pending_injections_.push_back(injection.release());
457 } 459 }
458 } 460 }
459 461
460 void ScriptInjectionManager::HandleExecuteDeclarativeScript( 462 void ScriptInjectionManager::HandleExecuteDeclarativeScript(
461 blink::WebFrame* web_frame, 463 blink::WebFrame* web_frame,
462 int tab_id, 464 int tab_id,
463 const ExtensionId& extension_id, 465 const ExtensionId& extension_id,
464 int script_id, 466 int script_id,
465 const GURL& url) { 467 const GURL& url) {
466 scoped_ptr<ExtensionInjectionHost> extension_injection_host =
467 GetExtensionInjectionHost(extension_id, extensions_);
468 const Extension* extension = extensions_->GetByID(extension_id);
469 // TODO(dcheng): This function signature should really be a WebLocalFrame, 468 // TODO(dcheng): This function signature should really be a WebLocalFrame,
470 // rather than trying to coerce it here. 469 // rather than trying to coerce it here.
471 scoped_ptr<ScriptInjection> injection = 470 scoped_ptr<ScriptInjection> injection =
472 user_script_set_manager_->GetInjectionForDeclarativeScript( 471 user_script_set_manager_->GetInjectionForDeclarativeScript(
473 script_id, 472 script_id,
474 web_frame->toWebLocalFrame(), 473 web_frame->toWebLocalFrame(),
475 tab_id, 474 tab_id,
476 url, 475 url,
477 extension); 476 extension_id);
478 if (injection.get()) { 477 if (injection) {
479 ScriptsRunInfo scripts_run_info; 478 ScriptsRunInfo scripts_run_info;
480 // TODO(markdittmer): Use return value of TryToInject for error handling. 479 // TODO(markdittmer): Use return value of TryToInject for error handling.
481 injection->TryToInject(UserScript::BROWSER_DRIVEN, 480 injection->TryToInject(UserScript::BROWSER_DRIVEN,
482 extension_injection_host.get(),
483 &scripts_run_info); 481 &scripts_run_info);
484 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN); 482 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN);
485 } 483 }
486 } 484 }
487 485
488 void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) { 486 void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) {
489 ScopedVector<ScriptInjection>::iterator iter = 487 ScopedVector<ScriptInjection>::iterator iter =
490 pending_injections_.begin(); 488 pending_injections_.begin();
491 for (; iter != pending_injections_.end(); ++iter) { 489 for (; iter != pending_injections_.end(); ++iter) {
492 if ((*iter)->request_id() == request_id) 490 if ((*iter)->request_id() == request_id) {
491 DCHECK((*iter)->host_id().type() == HostID::EXTENSIONS);
493 break; 492 break;
493 }
494 } 494 }
495 if (iter == pending_injections_.end()) 495 if (iter == pending_injections_.end())
496 return; 496 return;
497 497
498 // At this point, because the request is present in pending_injections_, we 498 // At this point, because the request is present in pending_injections_, we
499 // know that this is the same page that issued the request (otherwise, 499 // know that this is the same page that issued the request (otherwise,
500 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be 500 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be
501 // cleared out). 501 // cleared out).
502 502
503 scoped_ptr<ScriptInjection> injection(*iter); 503 scoped_ptr<ScriptInjection> injection(*iter);
504 pending_injections_.weak_erase(iter); 504 pending_injections_.weak_erase(iter);
505 505
506 ScriptsRunInfo scripts_run_info; 506 ScriptsRunInfo scripts_run_info;
507 scoped_ptr<ExtensionInjectionHost> extension_injection_host = 507 if (injection->OnPermissionGranted(&scripts_run_info)) {
508 GetExtensionInjectionHost(injection->host_id().id(), extensions_);
509 if (injection->OnPermissionGranted(extension_injection_host.get(),
510 &scripts_run_info)) {
511 scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED); 508 scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED);
512 } 509 }
513 } 510 }
514 511
515 } // namespace extensions 512 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698