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

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: Reset InjectionHost in ScriptInjection when extension is unloaded. 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(
Devlin 2015/02/20 22:39:13 Unfortunately, for the time being, if a script blo
Xi Han 2015/02/23 16:14:59 Thanks for pointing out this. Add a check for |inj
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)->set_injection_host(nullptr);
251 iter = pending_injections_.erase(iter);
252 }
253 else
254 ++iter;
255 }
256 }
257
259 void ScriptInjectionManager::OnUserScriptsUpdated( 258 void ScriptInjectionManager::OnUserScriptsUpdated(
260 const std::set<std::string>& changed_extensions, 259 const std::set<std::string>& changed_extensions,
261 const std::vector<UserScript*>& scripts) { 260 const std::vector<UserScript*>& scripts) {
262 for (ScopedVector<ScriptInjection>::iterator iter = 261 for (ScopedVector<ScriptInjection>::iterator iter =
263 pending_injections_.begin(); 262 pending_injections_.begin();
264 iter != pending_injections_.end();) { 263 iter != pending_injections_.end();) {
265 if (changed_extensions.count((*iter)->host_id().id()) > 0) 264 if (changed_extensions.count((*iter)->host_id().id()) > 0)
266 iter = pending_injections_.erase(iter); 265 iter = pending_injections_.erase(iter);
267 else 266 else
268 ++iter; 267 ++iter;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 &frame_injections, frame, tab_id, run_location); 384 &frame_injections, frame, tab_id, run_location);
386 385
387 ScriptsRunInfo scripts_run_info; 386 ScriptsRunInfo scripts_run_info;
388 for (ScopedVector<ScriptInjection>::iterator iter = frame_injections.begin(); 387 for (ScopedVector<ScriptInjection>::iterator iter = frame_injections.begin();
389 iter != frame_injections.end();) { 388 iter != frame_injections.end();) {
390 // If a blocking script was injected, there is potentially a possibility 389 // If a blocking script was injected, there is potentially a possibility
391 // that the frame has been invalidated in the time since. Check. 390 // that the frame has been invalidated in the time since. Check.
392 if (!IsFrameValid(frame)) 391 if (!IsFrameValid(frame))
393 break; 392 break;
394 393
395 const std::string& extension_id = (*iter)->host_id().id(); 394 // Try to inject the script if the injection host is not "dirty"
396 scoped_ptr<ExtensionInjectionHost> extension_injection_host = 395 // (invalidated by an update). If the injection does not finish
397 GetExtensionInjectionHost(extension_id, extensions_); 396 // (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 397 // injections.
399 // an update). If the injection does not finish (i.e., it is waiting for 398 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, 399 !(*iter)->TryToInject(run_location,
403 extension_injection_host.get(),
404 &scripts_run_info)) { 400 &scripts_run_info)) {
405 pending_injections_.insert(pending_injections_.begin(), *iter); 401 pending_injections_.insert(pending_injections_.begin(), *iter);
406 iter = frame_injections.weak_erase(iter); 402 iter = frame_injections.weak_erase(iter);
407 } else { 403 } else {
408 ++iter; 404 ++iter;
409 } 405 }
410 } 406 }
411 407
412 if (IsFrameValid(frame)) 408 if (IsFrameValid(frame))
413 scripts_run_info.LogRun(frame, run_location); 409 scripts_run_info.LogRun(frame, run_location);
(...skipping 12 matching lines...) Expand all
426 if (!main_frame) { 422 if (!main_frame) {
427 render_view->Send( 423 render_view->Send(
428 new ExtensionHostMsg_ExecuteCodeFinished(render_view->GetRoutingID(), 424 new ExtensionHostMsg_ExecuteCodeFinished(render_view->GetRoutingID(),
429 params.request_id, 425 params.request_id,
430 "No main frame", 426 "No main frame",
431 GURL(std::string()), 427 GURL(std::string()),
432 base::ListValue())); 428 base::ListValue()));
433 return; 429 return;
434 } 430 }
435 431
432 scoped_ptr<const ExtensionInjectionHost> extension_injection_host =
433 ExtensionInjectionHost::Create(params.extension_id, extensions_);
434
435 if (!extension_injection_host.get())
Devlin 2015/02/20 22:39:13 remove the get
Xi Han 2015/02/23 16:14:59 Done.
436 return;
437
436 scoped_ptr<ScriptInjection> injection(new ScriptInjection( 438 scoped_ptr<ScriptInjection> injection(new ScriptInjection(
437 scoped_ptr<ScriptInjector>( 439 scoped_ptr<ScriptInjector>(
438 new ProgrammaticScriptInjector(params, main_frame)), 440 new ProgrammaticScriptInjector(params, main_frame)),
439 main_frame, 441 main_frame,
440 HostID(HostID::EXTENSIONS, params.extension_id), 442 extension_injection_host.Pass(),
441 params.is_web_view ? UserScript::ConsumerInstanceType::WEBVIEW 443 params.is_web_view ? UserScript::ConsumerInstanceType::WEBVIEW
442 : UserScript::ConsumerInstanceType::TAB, 444 : UserScript::ConsumerInstanceType::TAB,
443 static_cast<UserScript::RunLocation>(params.run_at), 445 static_cast<UserScript::RunLocation>(params.run_at),
444 ExtensionHelper::Get(render_view)->tab_id())); 446 ExtensionHelper::Get(render_view)->tab_id()));
445 447
446 ScriptsRunInfo scripts_run_info; 448 ScriptsRunInfo scripts_run_info;
447 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame); 449 FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame);
448 450
449 scoped_ptr<ExtensionInjectionHost> extension_injection_host =
450 GetExtensionInjectionHost(injection->host_id().id(), extensions_);
451
452 if (!injection->TryToInject( 451 if (!injection->TryToInject(
453 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second, 452 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second,
454 extension_injection_host.get(),
455 &scripts_run_info)) { 453 &scripts_run_info)) {
456 pending_injections_.push_back(injection.release()); 454 pending_injections_.push_back(injection.release());
457 } 455 }
458 } 456 }
459 457
460 void ScriptInjectionManager::HandleExecuteDeclarativeScript( 458 void ScriptInjectionManager::HandleExecuteDeclarativeScript(
461 blink::WebFrame* web_frame, 459 blink::WebFrame* web_frame,
462 int tab_id, 460 int tab_id,
463 const ExtensionId& extension_id, 461 const ExtensionId& extension_id,
464 int script_id, 462 int script_id,
465 const GURL& url) { 463 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, 464 // TODO(dcheng): This function signature should really be a WebLocalFrame,
470 // rather than trying to coerce it here. 465 // rather than trying to coerce it here.
471 scoped_ptr<ScriptInjection> injection = 466 scoped_ptr<ScriptInjection> injection =
472 user_script_set_manager_->GetInjectionForDeclarativeScript( 467 user_script_set_manager_->GetInjectionForDeclarativeScript(
473 script_id, 468 script_id,
474 web_frame->toWebLocalFrame(), 469 web_frame->toWebLocalFrame(),
475 tab_id, 470 tab_id,
476 url, 471 url,
477 extension); 472 extension_id);
478 if (injection.get()) { 473 if (injection.get()) {
479 ScriptsRunInfo scripts_run_info; 474 ScriptsRunInfo scripts_run_info;
480 // TODO(markdittmer): Use return value of TryToInject for error handling. 475 // TODO(markdittmer): Use return value of TryToInject for error handling.
481 injection->TryToInject(UserScript::BROWSER_DRIVEN, 476 injection->TryToInject(UserScript::BROWSER_DRIVEN,
482 extension_injection_host.get(),
483 &scripts_run_info); 477 &scripts_run_info);
484 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN); 478 scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN);
485 } 479 }
486 } 480 }
487 481
488 void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) { 482 void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) {
489 ScopedVector<ScriptInjection>::iterator iter = 483 ScopedVector<ScriptInjection>::iterator iter =
490 pending_injections_.begin(); 484 pending_injections_.begin();
491 for (; iter != pending_injections_.end(); ++iter) { 485 for (; iter != pending_injections_.end(); ++iter) {
492 if ((*iter)->request_id() == request_id) 486 if ((*iter)->request_id() == request_id &&
487 (*iter)->host_id().type() == HostID::EXTENSIONS)
Devlin 2015/02/20 22:39:13 Is there any time when the script injection could
Xi Han 2015/02/23 16:14:59 DCHECK makes more sense, updated.
493 break; 488 break;
494 } 489 }
495 if (iter == pending_injections_.end()) 490 if (iter == pending_injections_.end())
496 return; 491 return;
497 492
498 // At this point, because the request is present in pending_injections_, we 493 // 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, 494 // know that this is the same page that issued the request (otherwise,
500 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be 495 // RVOHelper's DidStartProvisionalLoad callback would have caused it to be
501 // cleared out). 496 // cleared out).
502 497
503 scoped_ptr<ScriptInjection> injection(*iter); 498 scoped_ptr<ScriptInjection> injection(*iter);
504 pending_injections_.weak_erase(iter); 499 pending_injections_.weak_erase(iter);
505 500
506 ScriptsRunInfo scripts_run_info; 501 ScriptsRunInfo scripts_run_info;
507 scoped_ptr<ExtensionInjectionHost> extension_injection_host = 502 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); 503 scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED);
512 } 504 }
513 } 505 }
514 506
515 } // namespace extensions 507 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698