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 <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 void InvalidateAndResetFrame(); | 96 void InvalidateAndResetFrame(); |
97 | 97 |
98 // The owning ScriptInjectionManager. | 98 // The owning ScriptInjectionManager. |
99 ScriptInjectionManager* manager_; | 99 ScriptInjectionManager* manager_; |
100 | 100 |
101 bool should_run_idle_; | 101 bool should_run_idle_; |
102 | 102 |
103 base::WeakPtrFactory<RFOHelper> weak_factory_; | 103 base::WeakPtrFactory<RFOHelper> weak_factory_; |
104 }; | 104 }; |
105 | 105 |
106 class ScriptInjectionManager::ScriptInjectionWatcher { | |
107 public: | |
108 ScriptInjectionWatcher(ScriptInjection* injection, | |
109 ScriptInjectionManager* manager) | |
110 : injection_(injection), manager_(manager), host_id_(injection->host_id()) { | |
111 manager_->injection_watchers_.push_back(this); | |
112 } | |
113 | |
114 ~ScriptInjectionWatcher() { | |
115 auto& watchers = manager_->injection_watchers_; | |
116 for (auto it = watchers.begin(); it != watchers.end(); ++it) { | |
117 if (*it == this) { | |
118 watchers.erase(it); | |
119 break; | |
120 } | |
121 } | |
122 } | |
123 | |
124 void InvalidateHost() { | |
125 injection_->OnHostRemoved(); | |
126 } | |
127 | |
128 const HostID& host_id() const { return host_id_; } | |
129 | |
130 private: | |
131 ScriptInjection* injection_; | |
132 ScriptInjectionManager* manager_; | |
133 HostID host_id_; | |
134 }; | |
135 | |
106 ScriptInjectionManager::RFOHelper::RFOHelper(content::RenderFrame* render_frame, | 136 ScriptInjectionManager::RFOHelper::RFOHelper(content::RenderFrame* render_frame, |
107 ScriptInjectionManager* manager) | 137 ScriptInjectionManager* manager) |
108 : content::RenderFrameObserver(render_frame), | 138 : content::RenderFrameObserver(render_frame), |
109 manager_(manager), | 139 manager_(manager), |
110 should_run_idle_(true), | 140 should_run_idle_(true), |
111 weak_factory_(this) { | 141 weak_factory_(this) { |
112 } | 142 } |
113 | 143 |
114 ScriptInjectionManager::RFOHelper::~RFOHelper() { | 144 ScriptInjectionManager::RFOHelper::~RFOHelper() { |
115 } | 145 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 const std::string& extension_id) { | 308 const std::string& extension_id) { |
279 for (auto iter = pending_injections_.begin(); | 309 for (auto iter = pending_injections_.begin(); |
280 iter != pending_injections_.end();) { | 310 iter != pending_injections_.end();) { |
281 if ((*iter)->host_id().id() == extension_id) { | 311 if ((*iter)->host_id().id() == extension_id) { |
282 (*iter)->OnHostRemoved(); | 312 (*iter)->OnHostRemoved(); |
283 iter = pending_injections_.erase(iter); | 313 iter = pending_injections_.erase(iter); |
284 } else { | 314 } else { |
285 ++iter; | 315 ++iter; |
286 } | 316 } |
287 } | 317 } |
318 | |
319 for (auto watcher : injection_watchers_) { | |
320 if (watcher->host_id().id() == extension_id) | |
321 watcher->InvalidateHost(); | |
322 } | |
288 } | 323 } |
289 | 324 |
290 void ScriptInjectionManager::OnInjectionFinished( | 325 void ScriptInjectionManager::OnInjectionFinished( |
291 ScriptInjection* injection) { | 326 ScriptInjection* injection) { |
292 auto iter = | 327 auto iter = |
293 std::find_if(running_injections_.begin(), running_injections_.end(), | 328 std::find_if(running_injections_.begin(), running_injections_.end(), |
294 [injection](const std::unique_ptr<ScriptInjection>& mode) { | 329 [injection](const std::unique_ptr<ScriptInjection>& mode) { |
295 return injection == mode.get(); | 330 return injection == mode.get(); |
296 }); | 331 }); |
297 if (iter != running_injections_.end()) | 332 if (iter != running_injections_.end()) |
298 running_injections_.erase(iter); | 333 running_injections_.erase(iter); |
299 } | 334 } |
300 | 335 |
301 void ScriptInjectionManager::OnUserScriptsUpdated( | 336 void ScriptInjectionManager::OnUserScriptsUpdated( |
302 const std::set<HostID>& changed_hosts, | 337 const std::set<HostID>& changed_hosts, |
303 const std::vector<UserScript*>& scripts) { | 338 const std::vector<UserScript*>& scripts) { |
304 for (auto iter = pending_injections_.begin(); | 339 for (auto iter = pending_injections_.begin(); |
305 iter != pending_injections_.end();) { | 340 iter != pending_injections_.end();) { |
306 if (changed_hosts.count((*iter)->host_id()) > 0) | 341 if (changed_hosts.count((*iter)->host_id()) > 0) { |
342 (*iter)->OnHostRemoved(); | |
307 iter = pending_injections_.erase(iter); | 343 iter = pending_injections_.erase(iter); |
308 else | 344 } else { |
309 ++iter; | 345 ++iter; |
346 } | |
347 } | |
348 | |
349 for (auto watcher : injection_watchers_) { | |
350 if (changed_hosts.count(watcher->host_id()) > 0) | |
351 watcher->InvalidateHost(); | |
310 } | 352 } |
311 } | 353 } |
312 | 354 |
313 void ScriptInjectionManager::RemoveObserver(RFOHelper* helper) { | 355 void ScriptInjectionManager::RemoveObserver(RFOHelper* helper) { |
314 for (auto iter = rfo_helpers_.begin(); iter != rfo_helpers_.end(); ++iter) { | 356 for (auto iter = rfo_helpers_.begin(); iter != rfo_helpers_.end(); ++iter) { |
315 if (iter->get() == helper) { | 357 if (iter->get() == helper) { |
316 rfo_helpers_.erase(iter); | 358 rfo_helpers_.erase(iter); |
317 break; | 359 break; |
318 } | 360 } |
319 } | 361 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
394 active_injection_frames_.insert(frame); | 436 active_injection_frames_.insert(frame); |
395 | 437 |
396 ScriptsRunInfo scripts_run_info(frame, run_location); | 438 ScriptsRunInfo scripts_run_info(frame, run_location); |
397 for (auto iter = frame_injections.begin(); iter != frame_injections.end();) { | 439 for (auto iter = frame_injections.begin(); iter != frame_injections.end();) { |
398 // It's possible for the frame to be invalidated in the course of injection | 440 // It's possible for the frame to be invalidated in the course of injection |
399 // (if a script removes its own frame, for example). If this happens, abort. | 441 // (if a script removes its own frame, for example). If this happens, abort. |
400 if (!active_injection_frames_.count(frame)) | 442 if (!active_injection_frames_.count(frame)) |
401 break; | 443 break; |
402 std::unique_ptr<ScriptInjection> injection(std::move(*iter)); | 444 std::unique_ptr<ScriptInjection> injection(std::move(*iter)); |
403 iter = frame_injections.erase(iter); | 445 iter = frame_injections.erase(iter); |
446 ScriptInjectionWatcher watcher(injection.get(), this); | |
Devlin
2016/07/08 20:51:09
Hmm... I think this isn't quite sufficient. Consi
robwu
2016/07/09 05:22:02
You're right - I solved the issue by constructing
| |
404 TryToInject(std::move(injection), run_location, &scripts_run_info); | 447 TryToInject(std::move(injection), run_location, &scripts_run_info); |
405 } | 448 } |
406 | 449 |
407 // We are done running in the frame. | 450 // We are done running in the frame. |
408 active_injection_frames_.erase(frame); | 451 active_injection_frames_.erase(frame); |
409 | 452 |
410 scripts_run_info.LogRun(activity_logging_enabled_); | 453 scripts_run_info.LogRun(activity_logging_enabled_); |
411 } | 454 } |
412 | 455 |
413 void ScriptInjectionManager::TryToInject( | 456 void ScriptInjectionManager::TryToInject( |
(...skipping 10 matching lines...) Expand all Loading... | |
424 scripts_run_info, | 467 scripts_run_info, |
425 base::Bind(&ScriptInjectionManager::OnInjectionFinished, | 468 base::Bind(&ScriptInjectionManager::OnInjectionFinished, |
426 base::Unretained(this)))) { | 469 base::Unretained(this)))) { |
427 case ScriptInjection::INJECTION_WAITING: | 470 case ScriptInjection::INJECTION_WAITING: |
428 pending_injections_.push_back(std::move(injection)); | 471 pending_injections_.push_back(std::move(injection)); |
429 break; | 472 break; |
430 case ScriptInjection::INJECTION_BLOCKED: | 473 case ScriptInjection::INJECTION_BLOCKED: |
431 running_injections_.push_back(std::move(injection)); | 474 running_injections_.push_back(std::move(injection)); |
432 break; | 475 break; |
433 case ScriptInjection::INJECTION_FINISHED: | 476 case ScriptInjection::INJECTION_FINISHED: |
477 case ScriptInjection::INJECTION_CANCELED: | |
434 break; | 478 break; |
435 } | 479 } |
436 } | 480 } |
437 | 481 |
438 void ScriptInjectionManager::HandleExecuteCode( | 482 void ScriptInjectionManager::HandleExecuteCode( |
439 const ExtensionMsg_ExecuteCode_Params& params, | 483 const ExtensionMsg_ExecuteCode_Params& params, |
440 content::RenderFrame* render_frame) { | 484 content::RenderFrame* render_frame) { |
441 std::unique_ptr<const InjectionHost> injection_host; | 485 std::unique_ptr<const InjectionHost> injection_host; |
442 if (params.host_id.type() == HostID::EXTENSIONS) { | 486 if (params.host_id.type() == HostID::EXTENSIONS) { |
443 injection_host = ExtensionInjectionHost::Create(params.host_id.id()); | 487 injection_host = ExtensionInjectionHost::Create(params.host_id.id()); |
444 if (!injection_host) | 488 if (!injection_host) |
445 return; | 489 return; |
446 } else if (params.host_id.type() == HostID::WEBUI) { | 490 } else if (params.host_id.type() == HostID::WEBUI) { |
447 injection_host.reset( | 491 injection_host.reset( |
448 new WebUIInjectionHost(params.host_id)); | 492 new WebUIInjectionHost(params.host_id)); |
449 } | 493 } |
450 | 494 |
451 std::unique_ptr<ScriptInjection> injection(new ScriptInjection( | 495 std::unique_ptr<ScriptInjection> injection(new ScriptInjection( |
452 std::unique_ptr<ScriptInjector>( | 496 std::unique_ptr<ScriptInjector>( |
453 new ProgrammaticScriptInjector(params, render_frame)), | 497 new ProgrammaticScriptInjector(params, render_frame)), |
454 render_frame, std::move(injection_host), | 498 render_frame, std::move(injection_host), |
455 static_cast<UserScript::RunLocation>(params.run_at), | 499 static_cast<UserScript::RunLocation>(params.run_at), |
456 activity_logging_enabled_)); | 500 activity_logging_enabled_)); |
457 | 501 |
458 FrameStatusMap::const_iterator iter = frame_statuses_.find(render_frame); | 502 FrameStatusMap::const_iterator iter = frame_statuses_.find(render_frame); |
459 UserScript::RunLocation run_location = | 503 UserScript::RunLocation run_location = |
460 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second; | 504 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second; |
461 | 505 |
462 ScriptsRunInfo scripts_run_info(render_frame, run_location); | 506 ScriptsRunInfo scripts_run_info(render_frame, run_location); |
507 ScriptInjectionWatcher watcher(injection.get(), this); | |
463 TryToInject(std::move(injection), run_location, &scripts_run_info); | 508 TryToInject(std::move(injection), run_location, &scripts_run_info); |
464 } | 509 } |
465 | 510 |
466 void ScriptInjectionManager::HandleExecuteDeclarativeScript( | 511 void ScriptInjectionManager::HandleExecuteDeclarativeScript( |
467 content::RenderFrame* render_frame, | 512 content::RenderFrame* render_frame, |
468 int tab_id, | 513 int tab_id, |
469 const ExtensionId& extension_id, | 514 const ExtensionId& extension_id, |
470 int script_id, | 515 int script_id, |
471 const GURL& url) { | 516 const GURL& url) { |
472 std::unique_ptr<ScriptInjection> injection = | 517 std::unique_ptr<ScriptInjection> injection = |
473 user_script_set_manager_->GetInjectionForDeclarativeScript( | 518 user_script_set_manager_->GetInjectionForDeclarativeScript( |
474 script_id, render_frame, tab_id, url, extension_id); | 519 script_id, render_frame, tab_id, url, extension_id); |
475 if (injection.get()) { | 520 if (injection.get()) { |
476 ScriptsRunInfo scripts_run_info(render_frame, UserScript::BROWSER_DRIVEN); | 521 ScriptsRunInfo scripts_run_info(render_frame, UserScript::BROWSER_DRIVEN); |
522 ScriptInjectionWatcher watcher(injection.get(), this); | |
477 // TODO(markdittmer): Use return value of TryToInject for error handling. | 523 // TODO(markdittmer): Use return value of TryToInject for error handling. |
478 TryToInject(std::move(injection), UserScript::BROWSER_DRIVEN, | 524 TryToInject(std::move(injection), UserScript::BROWSER_DRIVEN, |
479 &scripts_run_info); | 525 &scripts_run_info); |
480 | 526 |
481 scripts_run_info.LogRun(activity_logging_enabled_); | 527 scripts_run_info.LogRun(activity_logging_enabled_); |
482 } | 528 } |
483 } | 529 } |
484 | 530 |
485 void ScriptInjectionManager::HandlePermitScriptInjection(int64_t request_id) { | 531 void ScriptInjectionManager::HandlePermitScriptInjection(int64_t request_id) { |
486 auto iter = pending_injections_.begin(); | 532 auto iter = pending_injections_.begin(); |
487 for (; iter != pending_injections_.end(); ++iter) { | 533 for (; iter != pending_injections_.end(); ++iter) { |
488 if ((*iter)->request_id() == request_id) { | 534 if ((*iter)->request_id() == request_id) { |
489 DCHECK((*iter)->host_id().type() == HostID::EXTENSIONS); | 535 DCHECK((*iter)->host_id().type() == HostID::EXTENSIONS); |
490 break; | 536 break; |
491 } | 537 } |
492 } | 538 } |
493 if (iter == pending_injections_.end()) | 539 if (iter == pending_injections_.end()) |
494 return; | 540 return; |
495 | 541 |
496 // At this point, because the request is present in pending_injections_, we | 542 // 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, | 543 // know that this is the same page that issued the request (otherwise, |
498 // RFOHelper::InvalidateAndResetFrame would have caused it to be cleared out). | 544 // RFOHelper::InvalidateAndResetFrame would have caused it to be cleared out). |
499 | 545 |
500 std::unique_ptr<ScriptInjection> injection(std::move(*iter)); | 546 std::unique_ptr<ScriptInjection> injection(std::move(*iter)); |
501 pending_injections_.erase(iter); | 547 pending_injections_.erase(iter); |
502 | 548 |
503 ScriptsRunInfo scripts_run_info(injection->render_frame(), | 549 ScriptsRunInfo scripts_run_info(injection->render_frame(), |
504 UserScript::RUN_DEFERRED); | 550 UserScript::RUN_DEFERRED); |
551 ScriptInjectionWatcher watcher(injection.get(), this); | |
505 ScriptInjection::InjectionResult res = injection->OnPermissionGranted( | 552 ScriptInjection::InjectionResult res = injection->OnPermissionGranted( |
506 &scripts_run_info); | 553 &scripts_run_info); |
507 if (res == ScriptInjection::INJECTION_BLOCKED) | 554 if (res == ScriptInjection::INJECTION_BLOCKED) |
508 running_injections_.push_back(std::move(injection)); | 555 running_injections_.push_back(std::move(injection)); |
509 scripts_run_info.LogRun(activity_logging_enabled_); | 556 scripts_run_info.LogRun(activity_logging_enabled_); |
510 } | 557 } |
511 | 558 |
512 } // namespace extensions | 559 } // namespace extensions |
OLD | NEW |