| Index: extensions/renderer/script_injection_manager.cc
|
| diff --git a/extensions/renderer/script_injection_manager.cc b/extensions/renderer/script_injection_manager.cc
|
| index 93862dd04bdfe1109bf23c223ccef4cb734ec90e..fe7d5351ab0cee347966f93f987296b73c15d91b 100644
|
| --- a/extensions/renderer/script_injection_manager.cc
|
| +++ b/extensions/renderer/script_injection_manager.cc
|
| @@ -53,7 +53,6 @@ UserScript::RunLocation NextRunLocation(UserScript::RunLocation run_location) {
|
| return UserScript::RUN_LOCATION_LAST;
|
| }
|
|
|
| -
|
| // TODO(hanxi): let ScriptInjection own an InjectionHost to avoid constructing
|
| // an ExtensionInjectionHost many times.
|
| // Note: the ScriptInjection should be able to know when the backing extension
|
| @@ -242,7 +241,6 @@ ScriptInjectionManager::ScriptInjectionManager(
|
| const ExtensionSet* extensions,
|
| UserScriptSetManager* user_script_set_manager)
|
| : extensions_(extensions),
|
| - injecting_scripts_(false),
|
| user_script_set_manager_(user_script_set_manager),
|
| user_script_set_manager_observer_(this) {
|
| user_script_set_manager_observer_.Add(user_script_set_manager_);
|
| @@ -256,6 +254,16 @@ void ScriptInjectionManager::OnRenderViewCreated(
|
| rvo_helpers_.push_back(new RVOHelper(render_view, this));
|
| }
|
|
|
| +void ScriptInjectionManager::OnInjectionFinished(
|
| + ScriptInjection* injection) {
|
| + ScopedVector<ScriptInjection>::iterator iter =
|
| + std::find(running_injections_.begin(),
|
| + running_injections_.end(),
|
| + injection);
|
| + if (iter != running_injections_.end())
|
| + running_injections_.erase(iter);
|
| +}
|
| +
|
| void ScriptInjectionManager::OnUserScriptsUpdated(
|
| const std::set<std::string>& changed_extensions,
|
| const std::vector<UserScript*>& scripts) {
|
| @@ -267,13 +275,6 @@ void ScriptInjectionManager::OnUserScriptsUpdated(
|
| else
|
| ++iter;
|
| }
|
| -
|
| - // If we are currently injecting scripts, we need to make a note that these
|
| - // extensions were updated.
|
| - if (injecting_scripts_) {
|
| - invalidated_while_injecting_.insert(changed_extensions.begin(),
|
| - changed_extensions.end());
|
| - }
|
| }
|
|
|
| void ScriptInjectionManager::RemoveObserver(RVOHelper* helper) {
|
| @@ -300,10 +301,6 @@ void ScriptInjectionManager::InvalidateForFrame(blink::WebFrame* frame) {
|
| frame_statuses_.erase(frame);
|
| }
|
|
|
| -bool ScriptInjectionManager::IsFrameValid(blink::WebFrame* frame) const {
|
| - return frame_statuses_.find(frame) != frame_statuses_.end();
|
| -}
|
| -
|
| void ScriptInjectionManager::StartInjectScripts(
|
| blink::WebFrame* frame, UserScript::RunLocation run_location) {
|
| FrameStatusMap::iterator iter = frame_statuses_.find(frame);
|
| @@ -334,38 +331,14 @@ void ScriptInjectionManager::StartInjectScripts(
|
|
|
| // Otherwise, all is right in the world, and we can get on with the
|
| // injections!
|
| -
|
| frame_statuses_[frame] = run_location;
|
| -
|
| - // If a content script injects blocking code (such as a javascript alert()),
|
| - // then there is a chance that we are running in a nested message loop, and
|
| - // shouldn't inject scripts right now (to avoid conflicts).
|
| - if (!injecting_scripts_) {
|
| - InjectScripts(frame, run_location);
|
| - // As above, we might have been blocked, but that means that, in the mean
|
| - // time, it's possible the frame advanced. Inject any scripts for run
|
| - // locations that were registered, but never ran.
|
| - while ((iter = frame_statuses_.find(frame)) != frame_statuses_.end() &&
|
| - iter->second > run_location) {
|
| - run_location = NextRunLocation(run_location);
|
| - DCHECK_LE(run_location, UserScript::DOCUMENT_IDLE);
|
| - InjectScripts(frame, run_location);
|
| - }
|
| - }
|
| + InjectScripts(frame, run_location);
|
| }
|
|
|
| void ScriptInjectionManager::InjectScripts(
|
| blink::WebFrame* frame,
|
| UserScript::RunLocation run_location) {
|
| - DCHECK(!injecting_scripts_);
|
| - DCHECK(invalidated_while_injecting_.empty());
|
| - base::AutoReset<bool>(&injecting_scripts_, true);
|
| -
|
| // Find any injections that want to run on the given frame.
|
| - // We create a separate vector for these because there is a chance that
|
| - // injected scripts can block, which can create a nested message loop. When
|
| - // this happens, other signals (like IPCs) can cause |pending_injections_| to
|
| - // be changed, so we don't want to risk that.
|
| ScopedVector<ScriptInjection> frame_injections;
|
| for (ScopedVector<ScriptInjection>::iterator iter =
|
| pending_injections_.begin();
|
| @@ -385,34 +358,36 @@ void ScriptInjectionManager::InjectScripts(
|
| &frame_injections, frame, tab_id, run_location);
|
|
|
| ScriptsRunInfo scripts_run_info;
|
| - for (ScopedVector<ScriptInjection>::iterator iter = frame_injections.begin();
|
| - iter != frame_injections.end();) {
|
| - // If a blocking script was injected, there is potentially a possibility
|
| - // that the frame has been invalidated in the time since. Check.
|
| - if (!IsFrameValid(frame))
|
| - break;
|
| + std::vector<ScriptInjection*> released_injections;
|
| + frame_injections.release(&released_injections);
|
| + for (ScriptInjection* injection : released_injections)
|
| + TryToInject(make_scoped_ptr(injection), run_location, &scripts_run_info);
|
|
|
| - const std::string& extension_id = (*iter)->host_id().id();
|
| - scoped_ptr<ExtensionInjectionHost> extension_injection_host =
|
| - GetExtensionInjectionHost(extension_id, extensions_);
|
| - // Try to inject the script if the extension is not "dirty" (invalidated by
|
| - // an update). If the injection does not finish (i.e., it is waiting for
|
| - // permission), add it to the list of pending injections.
|
| - if (invalidated_while_injecting_.count(extension_id) == 0 &&
|
| - !(*iter)->TryToInject(run_location,
|
| - extension_injection_host.get(),
|
| - &scripts_run_info)) {
|
| - pending_injections_.insert(pending_injections_.begin(), *iter);
|
| - iter = frame_injections.weak_erase(iter);
|
| - } else {
|
| - ++iter;
|
| - }
|
| - }
|
| -
|
| - if (IsFrameValid(frame))
|
| - scripts_run_info.LogRun(frame, run_location);
|
| + scripts_run_info.LogRun(frame, run_location);
|
| +}
|
|
|
| - invalidated_while_injecting_.clear();
|
| +void ScriptInjectionManager::TryToInject(
|
| + scoped_ptr<ScriptInjection> injection,
|
| + UserScript::RunLocation run_location,
|
| + ScriptsRunInfo* scripts_run_info) {
|
| + scoped_ptr<ExtensionInjectionHost> extension_injection_host =
|
| + GetExtensionInjectionHost(injection->host_id().id(), extensions_);
|
| + // Try to inject the script. If the injection is waiting (i.e., for
|
| + // permission), add it to the list of pending injections. If the injection
|
| + // has blocked, add it to the list of running injections.
|
| + switch (injection->TryToInject(
|
| + run_location,
|
| + extension_injection_host.get(),
|
| + scripts_run_info,
|
| + this)) {
|
| + case ScriptInjection::INJECTION_WAITING:
|
| + pending_injections_.push_back(injection.release());
|
| + case ScriptInjection::INJECTION_BLOCKED:
|
| + running_injections_.push_back(injection.release());
|
| + break;
|
| + case ScriptInjection::INJECTION_FINISHED:
|
| + break;
|
| + }
|
| }
|
|
|
| void ScriptInjectionManager::HandleExecuteCode(
|
| @@ -444,15 +419,10 @@ void ScriptInjectionManager::HandleExecuteCode(
|
| ScriptsRunInfo scripts_run_info;
|
| FrameStatusMap::const_iterator iter = frame_statuses_.find(main_frame);
|
|
|
| - scoped_ptr<ExtensionInjectionHost> extension_injection_host =
|
| - GetExtensionInjectionHost(injection->host_id().id(), extensions_);
|
| -
|
| - if (!injection->TryToInject(
|
| - iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second,
|
| - extension_injection_host.get(),
|
| - &scripts_run_info)) {
|
| - pending_injections_.push_back(injection.release());
|
| - }
|
| + TryToInject(
|
| + injection.Pass(),
|
| + iter == frame_statuses_.end() ? UserScript::UNDEFINED : iter->second,
|
| + &scripts_run_info);
|
| }
|
|
|
| void ScriptInjectionManager::HandleExecuteDeclarativeScript(
|
| @@ -461,8 +431,6 @@ void ScriptInjectionManager::HandleExecuteDeclarativeScript(
|
| const ExtensionId& extension_id,
|
| int script_id,
|
| const GURL& url) {
|
| - scoped_ptr<ExtensionInjectionHost> extension_injection_host =
|
| - GetExtensionInjectionHost(extension_id, extensions_);
|
| const Extension* extension = extensions_->GetByID(extension_id);
|
| // TODO(dcheng): This function signature should really be a WebLocalFrame,
|
| // rather than trying to coerce it here.
|
| @@ -475,10 +443,12 @@ void ScriptInjectionManager::HandleExecuteDeclarativeScript(
|
| extension);
|
| if (injection.get()) {
|
| ScriptsRunInfo scripts_run_info;
|
| +
|
| // TODO(markdittmer): Use return value of TryToInject for error handling.
|
| - injection->TryToInject(UserScript::BROWSER_DRIVEN,
|
| - extension_injection_host.get(),
|
| - &scripts_run_info);
|
| + TryToInject(injection.Pass(),
|
| + UserScript::BROWSER_DRIVEN,
|
| + &scripts_run_info);
|
| +
|
| scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN);
|
| }
|
| }
|
| @@ -501,13 +471,15 @@ void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) {
|
| scoped_ptr<ScriptInjection> injection(*iter);
|
| pending_injections_.weak_erase(iter);
|
|
|
| - ScriptsRunInfo scripts_run_info;
|
| scoped_ptr<ExtensionInjectionHost> extension_injection_host =
|
| GetExtensionInjectionHost(injection->host_id().id(), extensions_);
|
| - if (injection->OnPermissionGranted(extension_injection_host.get(),
|
| - &scripts_run_info)) {
|
| + ScriptsRunInfo scripts_run_info;
|
| + ScriptInjection::InjectionResult res = injection->OnPermissionGranted(
|
| + extension_injection_host.get(), &scripts_run_info);
|
| + if (res == ScriptInjection::INJECTION_BLOCKED)
|
| + running_injections_.push_back(injection.Pass());
|
| + if (extension_injection_host.get())
|
| scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED);
|
| - }
|
| }
|
|
|
| } // namespace extensions
|
|
|