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 <utility> | 8 #include <utility> |
8 | 9 |
9 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
10 #include "base/bind.h" | 11 #include "base/bind.h" |
11 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/ptr_util.h" |
12 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
13 #include "base/values.h" | 14 #include "base/values.h" |
14 #include "content/public/renderer/render_frame.h" | 15 #include "content/public/renderer/render_frame.h" |
15 #include "content/public/renderer/render_frame_observer.h" | 16 #include "content/public/renderer/render_frame_observer.h" |
16 #include "content/public/renderer/render_thread.h" | 17 #include "content/public/renderer/render_thread.h" |
17 #include "extensions/common/extension.h" | 18 #include "extensions/common/extension.h" |
18 #include "extensions/common/extension_messages.h" | 19 #include "extensions/common/extension_messages.h" |
19 #include "extensions/common/extension_set.h" | 20 #include "extensions/common/extension_set.h" |
20 #include "extensions/renderer/extension_frame_helper.h" | 21 #include "extensions/renderer/extension_frame_helper.h" |
21 #include "extensions/renderer/extension_injection_host.h" | 22 #include "extensions/renderer/extension_injection_host.h" |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 | 264 |
264 ScriptInjectionManager::~ScriptInjectionManager() { | 265 ScriptInjectionManager::~ScriptInjectionManager() { |
265 for (const auto& injection : pending_injections_) | 266 for (const auto& injection : pending_injections_) |
266 injection->invalidate_render_frame(); | 267 injection->invalidate_render_frame(); |
267 for (const auto& injection : running_injections_) | 268 for (const auto& injection : running_injections_) |
268 injection->invalidate_render_frame(); | 269 injection->invalidate_render_frame(); |
269 } | 270 } |
270 | 271 |
271 void ScriptInjectionManager::OnRenderFrameCreated( | 272 void ScriptInjectionManager::OnRenderFrameCreated( |
272 content::RenderFrame* render_frame) { | 273 content::RenderFrame* render_frame) { |
273 rfo_helpers_.push_back(make_scoped_ptr(new RFOHelper(render_frame, this))); | 274 rfo_helpers_.push_back(base::WrapUnique(new RFOHelper(render_frame, this))); |
274 } | 275 } |
275 | 276 |
276 void ScriptInjectionManager::OnExtensionUnloaded( | 277 void ScriptInjectionManager::OnExtensionUnloaded( |
277 const std::string& extension_id) { | 278 const std::string& extension_id) { |
278 for (auto iter = pending_injections_.begin(); | 279 for (auto iter = pending_injections_.begin(); |
279 iter != pending_injections_.end();) { | 280 iter != pending_injections_.end();) { |
280 if ((*iter)->host_id().id() == extension_id) { | 281 if ((*iter)->host_id().id() == extension_id) { |
281 (*iter)->OnHostRemoved(); | 282 (*iter)->OnHostRemoved(); |
282 iter = pending_injections_.erase(iter); | 283 iter = pending_injections_.erase(iter); |
283 } else { | 284 } else { |
284 ++iter; | 285 ++iter; |
285 } | 286 } |
286 } | 287 } |
287 } | 288 } |
288 | 289 |
289 void ScriptInjectionManager::OnInjectionFinished( | 290 void ScriptInjectionManager::OnInjectionFinished( |
290 ScriptInjection* injection) { | 291 ScriptInjection* injection) { |
291 auto iter = | 292 auto iter = |
292 std::find_if(running_injections_.begin(), running_injections_.end(), | 293 std::find_if(running_injections_.begin(), running_injections_.end(), |
293 [injection](const scoped_ptr<ScriptInjection>& mode) { | 294 [injection](const std::unique_ptr<ScriptInjection>& mode) { |
294 return injection == mode.get(); | 295 return injection == mode.get(); |
295 }); | 296 }); |
296 if (iter != running_injections_.end()) | 297 if (iter != running_injections_.end()) |
297 running_injections_.erase(iter); | 298 running_injections_.erase(iter); |
298 } | 299 } |
299 | 300 |
300 void ScriptInjectionManager::OnUserScriptsUpdated( | 301 void ScriptInjectionManager::OnUserScriptsUpdated( |
301 const std::set<HostID>& changed_hosts, | 302 const std::set<HostID>& changed_hosts, |
302 const std::vector<UserScript*>& scripts) { | 303 const std::vector<UserScript*>& scripts) { |
303 for (auto iter = pending_injections_.begin(); | 304 for (auto iter = pending_injections_.begin(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 | 392 |
392 // Note that we are running in |frame|. | 393 // Note that we are running in |frame|. |
393 active_injection_frames_.insert(frame); | 394 active_injection_frames_.insert(frame); |
394 | 395 |
395 ScriptsRunInfo scripts_run_info(frame, run_location); | 396 ScriptsRunInfo scripts_run_info(frame, run_location); |
396 for (auto iter = frame_injections.begin(); iter != frame_injections.end();) { | 397 for (auto iter = frame_injections.begin(); iter != frame_injections.end();) { |
397 // It's possible for the frame to be invalidated in the course of injection | 398 // It's possible for the frame to be invalidated in the course of injection |
398 // (if a script removes its own frame, for example). If this happens, abort. | 399 // (if a script removes its own frame, for example). If this happens, abort. |
399 if (!active_injection_frames_.count(frame)) | 400 if (!active_injection_frames_.count(frame)) |
400 break; | 401 break; |
401 scoped_ptr<ScriptInjection> injection(std::move(*iter)); | 402 std::unique_ptr<ScriptInjection> injection(std::move(*iter)); |
402 iter = frame_injections.erase(iter); | 403 iter = frame_injections.erase(iter); |
403 TryToInject(std::move(injection), run_location, &scripts_run_info); | 404 TryToInject(std::move(injection), run_location, &scripts_run_info); |
404 } | 405 } |
405 | 406 |
406 // We are done running in the frame. | 407 // We are done running in the frame. |
407 active_injection_frames_.erase(frame); | 408 active_injection_frames_.erase(frame); |
408 | 409 |
409 scripts_run_info.LogRun(); | 410 scripts_run_info.LogRun(); |
410 } | 411 } |
411 | 412 |
412 void ScriptInjectionManager::TryToInject( | 413 void ScriptInjectionManager::TryToInject( |
413 scoped_ptr<ScriptInjection> injection, | 414 std::unique_ptr<ScriptInjection> injection, |
414 UserScript::RunLocation run_location, | 415 UserScript::RunLocation run_location, |
415 ScriptsRunInfo* scripts_run_info) { | 416 ScriptsRunInfo* scripts_run_info) { |
416 // Try to inject the script. If the injection is waiting (i.e., for | 417 // Try to inject the script. If the injection is waiting (i.e., for |
417 // permission), add it to the list of pending injections. If the injection | 418 // permission), add it to the list of pending injections. If the injection |
418 // has blocked, add it to the list of running injections. | 419 // has blocked, add it to the list of running injections. |
419 // The Unretained below is safe because this object owns all the | 420 // The Unretained below is safe because this object owns all the |
420 // ScriptInjections, so is guaranteed to outlive them. | 421 // ScriptInjections, so is guaranteed to outlive them. |
421 switch (injection->TryToInject( | 422 switch (injection->TryToInject( |
422 run_location, | 423 run_location, |
423 scripts_run_info, | 424 scripts_run_info, |
424 base::Bind(&ScriptInjectionManager::OnInjectionFinished, | 425 base::Bind(&ScriptInjectionManager::OnInjectionFinished, |
425 base::Unretained(this)))) { | 426 base::Unretained(this)))) { |
426 case ScriptInjection::INJECTION_WAITING: | 427 case ScriptInjection::INJECTION_WAITING: |
427 pending_injections_.push_back(std::move(injection)); | 428 pending_injections_.push_back(std::move(injection)); |
428 break; | 429 break; |
429 case ScriptInjection::INJECTION_BLOCKED: | 430 case ScriptInjection::INJECTION_BLOCKED: |
430 running_injections_.push_back(std::move(injection)); | 431 running_injections_.push_back(std::move(injection)); |
431 break; | 432 break; |
432 case ScriptInjection::INJECTION_FINISHED: | 433 case ScriptInjection::INJECTION_FINISHED: |
433 break; | 434 break; |
434 } | 435 } |
435 } | 436 } |
436 | 437 |
437 void ScriptInjectionManager::HandleExecuteCode( | 438 void ScriptInjectionManager::HandleExecuteCode( |
438 const ExtensionMsg_ExecuteCode_Params& params, | 439 const ExtensionMsg_ExecuteCode_Params& params, |
439 content::RenderFrame* render_frame) { | 440 content::RenderFrame* render_frame) { |
440 scoped_ptr<const InjectionHost> injection_host; | 441 std::unique_ptr<const InjectionHost> injection_host; |
441 if (params.host_id.type() == HostID::EXTENSIONS) { | 442 if (params.host_id.type() == HostID::EXTENSIONS) { |
442 injection_host = ExtensionInjectionHost::Create(params.host_id.id()); | 443 injection_host = ExtensionInjectionHost::Create(params.host_id.id()); |
443 if (!injection_host) | 444 if (!injection_host) |
444 return; | 445 return; |
445 } else if (params.host_id.type() == HostID::WEBUI) { | 446 } else if (params.host_id.type() == HostID::WEBUI) { |
446 injection_host.reset( | 447 injection_host.reset( |
447 new WebUIInjectionHost(params.host_id)); | 448 new WebUIInjectionHost(params.host_id)); |
448 } | 449 } |
449 | 450 |
450 scoped_ptr<ScriptInjection> injection(new ScriptInjection( | 451 std::unique_ptr<ScriptInjection> injection(new ScriptInjection( |
451 scoped_ptr<ScriptInjector>( | 452 std::unique_ptr<ScriptInjector>( |
452 new ProgrammaticScriptInjector(params, render_frame)), | 453 new ProgrammaticScriptInjector(params, render_frame)), |
453 render_frame, std::move(injection_host), | 454 render_frame, std::move(injection_host), |
454 static_cast<UserScript::RunLocation>(params.run_at))); | 455 static_cast<UserScript::RunLocation>(params.run_at))); |
455 | 456 |
456 FrameStatusMap::const_iterator iter = frame_statuses_.find(render_frame); | 457 FrameStatusMap::const_iterator iter = frame_statuses_.find(render_frame); |
457 UserScript::RunLocation run_location = | 458 UserScript::RunLocation run_location = |
458 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second; | 459 iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second; |
459 | 460 |
460 ScriptsRunInfo scripts_run_info(render_frame, run_location); | 461 ScriptsRunInfo scripts_run_info(render_frame, run_location); |
461 TryToInject(std::move(injection), run_location, &scripts_run_info); | 462 TryToInject(std::move(injection), run_location, &scripts_run_info); |
462 } | 463 } |
463 | 464 |
464 void ScriptInjectionManager::HandleExecuteDeclarativeScript( | 465 void ScriptInjectionManager::HandleExecuteDeclarativeScript( |
465 content::RenderFrame* render_frame, | 466 content::RenderFrame* render_frame, |
466 int tab_id, | 467 int tab_id, |
467 const ExtensionId& extension_id, | 468 const ExtensionId& extension_id, |
468 int script_id, | 469 int script_id, |
469 const GURL& url) { | 470 const GURL& url) { |
470 scoped_ptr<ScriptInjection> injection = | 471 std::unique_ptr<ScriptInjection> injection = |
471 user_script_set_manager_->GetInjectionForDeclarativeScript( | 472 user_script_set_manager_->GetInjectionForDeclarativeScript( |
472 script_id, | 473 script_id, render_frame, tab_id, url, extension_id); |
473 render_frame, | |
474 tab_id, | |
475 url, | |
476 extension_id); | |
477 if (injection.get()) { | 474 if (injection.get()) { |
478 ScriptsRunInfo scripts_run_info(render_frame, UserScript::BROWSER_DRIVEN); | 475 ScriptsRunInfo scripts_run_info(render_frame, UserScript::BROWSER_DRIVEN); |
479 // TODO(markdittmer): Use return value of TryToInject for error handling. | 476 // TODO(markdittmer): Use return value of TryToInject for error handling. |
480 TryToInject(std::move(injection), UserScript::BROWSER_DRIVEN, | 477 TryToInject(std::move(injection), UserScript::BROWSER_DRIVEN, |
481 &scripts_run_info); | 478 &scripts_run_info); |
482 | 479 |
483 scripts_run_info.LogRun(); | 480 scripts_run_info.LogRun(); |
484 } | 481 } |
485 } | 482 } |
486 | 483 |
487 void ScriptInjectionManager::HandlePermitScriptInjection(int64_t request_id) { | 484 void ScriptInjectionManager::HandlePermitScriptInjection(int64_t request_id) { |
488 auto iter = pending_injections_.begin(); | 485 auto iter = pending_injections_.begin(); |
489 for (; iter != pending_injections_.end(); ++iter) { | 486 for (; iter != pending_injections_.end(); ++iter) { |
490 if ((*iter)->request_id() == request_id) { | 487 if ((*iter)->request_id() == request_id) { |
491 DCHECK((*iter)->host_id().type() == HostID::EXTENSIONS); | 488 DCHECK((*iter)->host_id().type() == HostID::EXTENSIONS); |
492 break; | 489 break; |
493 } | 490 } |
494 } | 491 } |
495 if (iter == pending_injections_.end()) | 492 if (iter == pending_injections_.end()) |
496 return; | 493 return; |
497 | 494 |
498 // At this point, because the request is present in pending_injections_, we | 495 // 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, | 496 // know that this is the same page that issued the request (otherwise, |
500 // RFOHelper::InvalidateAndResetFrame would have caused it to be cleared out). | 497 // RFOHelper::InvalidateAndResetFrame would have caused it to be cleared out). |
501 | 498 |
502 scoped_ptr<ScriptInjection> injection(std::move(*iter)); | 499 std::unique_ptr<ScriptInjection> injection(std::move(*iter)); |
503 pending_injections_.erase(iter); | 500 pending_injections_.erase(iter); |
504 | 501 |
505 ScriptsRunInfo scripts_run_info(injection->render_frame(), | 502 ScriptsRunInfo scripts_run_info(injection->render_frame(), |
506 UserScript::RUN_DEFERRED); | 503 UserScript::RUN_DEFERRED); |
507 ScriptInjection::InjectionResult res = injection->OnPermissionGranted( | 504 ScriptInjection::InjectionResult res = injection->OnPermissionGranted( |
508 &scripts_run_info); | 505 &scripts_run_info); |
509 if (res == ScriptInjection::INJECTION_BLOCKED) | 506 if (res == ScriptInjection::INJECTION_BLOCKED) |
510 running_injections_.push_back(std::move(injection)); | 507 running_injections_.push_back(std::move(injection)); |
511 scripts_run_info.LogRun(); | 508 scripts_run_info.LogRun(); |
512 } | 509 } |
513 | 510 |
514 } // namespace extensions | 511 } // namespace extensions |
OLD | NEW |