| 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 |