Index: extensions/renderer/script_injection.cc |
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc |
index 9f3236f9d20d0a14ebb43803edca2d1294724213..94affa02ab23820adcc286a4cd30c98bd398152f 100644 |
--- a/extensions/renderer/script_injection.cc |
+++ b/extensions/renderer/script_injection.cc |
@@ -12,12 +12,13 @@ |
#include "base/values.h" |
#include "content/public/child/v8_value_converter.h" |
#include "content/public/renderer/render_view.h" |
-#include "extensions/common/extension.h" |
#include "extensions/common/extension_messages.h" |
#include "extensions/common/feature_switch.h" |
+#include "extensions/common/host_id.h" |
#include "extensions/common/manifest_handlers/csp_info.h" |
#include "extensions/renderer/dom_activity_logger.h" |
#include "extensions/renderer/extension_groups.h" |
+#include "extensions/renderer/extension_injection_host.h" |
#include "extensions/renderer/extensions_renderer_client.h" |
#include "third_party/WebKit/public/platform/WebString.h" |
#include "third_party/WebKit/public/web/WebDocument.h" |
@@ -31,7 +32,7 @@ namespace extensions { |
namespace { |
-typedef std::map<std::string, int> IsolatedWorldMap; |
+using IsolatedWorldMap = std::map<std::string, int>; |
base::LazyInstance<IsolatedWorldMap> g_isolated_worlds = |
LAZY_INSTANCE_INITIALIZER; |
@@ -55,38 +56,38 @@ void AppendAllChildFrames(blink::WebFrame* parent_frame, |
} |
} |
-// Gets the isolated world ID to use for the given |extension| in the given |
-// |frame|. If no isolated world has been created for that extension, |
-// one will be created and initialized. |
-int GetIsolatedWorldIdForExtension(const Extension* extension, |
- blink::WebLocalFrame* frame) { |
+// Gets the isolated world ID to use for the given |injection_host| |
+// in the given |frame|. If no isolated world has been created for that |
+// |injection_host| one will be created and initialized. |
+int GetIsolatedWorldIdForInstance(const InjectionHost* injection_host, |
+ blink::WebLocalFrame* frame) { |
static int g_next_isolated_world_id = |
ExtensionsRendererClient::Get()->GetLowestIsolatedWorldId(); |
IsolatedWorldMap& isolated_worlds = g_isolated_worlds.Get(); |
int id = 0; |
- IsolatedWorldMap::iterator iter = isolated_worlds.find(extension->id()); |
+ const std::string& key = injection_host->id().id(); |
+ IsolatedWorldMap::iterator iter = isolated_worlds.find(key); |
if (iter != isolated_worlds.end()) { |
id = iter->second; |
} else { |
id = g_next_isolated_world_id++; |
// This map will tend to pile up over time, but realistically, you're never |
- // going to have enough extensions for it to matter. |
- isolated_worlds[extension->id()] = id; |
+ // going to have enough injection hosts for it to matter. |
+ isolated_worlds[key] = id; |
} |
// We need to set the isolated world origin and CSP even if it's not a new |
// world since these are stored per frame, and we might not have used this |
// isolated world in this frame before. |
frame->setIsolatedWorldSecurityOrigin( |
- id, blink::WebSecurityOrigin::create(extension->url())); |
+ id, blink::WebSecurityOrigin::create(injection_host->url())); |
frame->setIsolatedWorldContentSecurityPolicy( |
- id, |
- blink::WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension))); |
+ id, blink::WebString::fromUTF8( |
+ injection_host->GetContentSecurityPolicy())); |
frame->setIsolatedWorldHumanReadableName( |
- id, |
- blink::WebString::fromUTF8(extension->name())); |
+ id, blink::WebString::fromUTF8(injection_host->name())); |
return id; |
} |
@@ -94,33 +95,30 @@ int GetIsolatedWorldIdForExtension(const Extension* extension, |
} // namespace |
// static |
-std::string ScriptInjection::GetExtensionIdForIsolatedWorld( |
- int isolated_world_id) { |
- IsolatedWorldMap& isolated_worlds = g_isolated_worlds.Get(); |
+std::string ScriptInjection::GetHostIdForIsolatedWorld(int isolated_world_id) { |
+ const IsolatedWorldMap& isolated_worlds = g_isolated_worlds.Get(); |
- for (IsolatedWorldMap::iterator iter = isolated_worlds.begin(); |
- iter != isolated_worlds.end(); |
- ++iter) { |
- if (iter->second == isolated_world_id) |
- return iter->first; |
+ for (const auto& iter : isolated_worlds) { |
+ if (iter.second == isolated_world_id) |
+ return iter.first; |
} |
return std::string(); |
} |
// static |
-void ScriptInjection::RemoveIsolatedWorld(const std::string& extension_id) { |
- g_isolated_worlds.Get().erase(extension_id); |
+void ScriptInjection::RemoveIsolatedWorld(const std::string& host_id) { |
+ g_isolated_worlds.Get().erase(host_id); |
} |
ScriptInjection::ScriptInjection( |
scoped_ptr<ScriptInjector> injector, |
blink::WebLocalFrame* web_frame, |
- const std::string& extension_id, |
+ const HostID& host_id, |
UserScript::RunLocation run_location, |
int tab_id) |
: injector_(injector.Pass()), |
web_frame_(web_frame), |
- extension_id_(extension_id), |
+ host_id_(host_id), |
run_location_(run_location), |
tab_id_(tab_id), |
request_id_(kInvalidRequestId), |
@@ -133,7 +131,7 @@ ScriptInjection::~ScriptInjection() { |
} |
bool ScriptInjection::TryToInject(UserScript::RunLocation current_location, |
- const Extension* extension, |
+ const InjectionHost* injection_host, |
ScriptsRunInfo* scripts_run_info) { |
if (current_location < run_location_) |
return false; // Wait for the right location. |
@@ -141,13 +139,13 @@ bool ScriptInjection::TryToInject(UserScript::RunLocation current_location, |
if (request_id_ != kInvalidRequestId) |
return false; // We're waiting for permission right now, try again later. |
- if (!extension) { |
+ if (!injection_host) { |
NotifyWillNotInject(ScriptInjector::EXTENSION_REMOVED); |
return true; // We're done. |
} |
- switch (injector_->CanExecuteOnFrame( |
- extension, web_frame_, tab_id_, web_frame_->top()->document().url())) { |
+ switch (injector_->CanExecuteOnFrame(injection_host, web_frame_, tab_id_, |
+ web_frame_->top()->document().url())) { |
case PermissionsData::ACCESS_DENIED: |
NotifyWillNotInject(ScriptInjector::NOT_ALLOWED); |
return true; // We're done. |
@@ -155,7 +153,7 @@ bool ScriptInjection::TryToInject(UserScript::RunLocation current_location, |
RequestPermission(); |
return false; // Wait around for permission. |
case PermissionsData::ACCESS_ALLOWED: |
- Inject(extension, scripts_run_info); |
+ Inject(injection_host, scripts_run_info); |
return true; // We're done! |
} |
@@ -164,14 +162,14 @@ bool ScriptInjection::TryToInject(UserScript::RunLocation current_location, |
return false; |
} |
-bool ScriptInjection::OnPermissionGranted(const Extension* extension, |
+bool ScriptInjection::OnPermissionGranted(const InjectionHost* injection_host, |
ScriptsRunInfo* scripts_run_info) { |
- if (!extension) { |
+ if (!injection_host) { |
NotifyWillNotInject(ScriptInjector::EXTENSION_REMOVED); |
return false; |
} |
- Inject(extension, scripts_run_info); |
+ Inject(injection_host, scripts_run_info); |
return true; |
} |
@@ -185,7 +183,7 @@ void ScriptInjection::RequestPermission() { |
: g_next_pending_id++; |
render_view->Send(new ExtensionHostMsg_RequestScriptInjectionPermission( |
render_view->GetRoutingID(), |
- extension_id_, |
+ host_id_.id(), |
injector_->script_type(), |
request_id_)); |
} |
@@ -196,13 +194,14 @@ void ScriptInjection::NotifyWillNotInject( |
injector_->OnWillNotInject(reason); |
} |
-void ScriptInjection::Inject(const Extension* extension, |
+void ScriptInjection::Inject(const InjectionHost* injection_host, |
ScriptsRunInfo* scripts_run_info) { |
- DCHECK(extension); |
+ DCHECK(injection_host); |
DCHECK(scripts_run_info); |
DCHECK(!complete_); |
- if (ShouldNotifyBrowserOfInjections()) |
+ if (ShouldNotifyBrowserOfInjections() && |
+ injection_host->id().type() == HostID::EXTENSIONS) |
RequestPermission(); |
std::vector<blink::WebFrame*> frame_vector; |
@@ -229,30 +228,32 @@ void ScriptInjection::Inject(const Extension* extension, |
// We recheck access here in the renderer for extra safety against races |
// with navigation, but different frames can have different URLs, and the |
- // extension might only have access to a subset of them. |
- // For child frames, we just skip ones the extension doesn't have access |
- // to and carry on. |
+ // injection host might only have access to a subset of them. |
+ // For child frames, we just skip ones the injection host doesn't have |
+ // access to and carry on. |
// Note: we don't consider ACCESS_WITHHELD because there is nowhere to |
// surface a request for a child frame. |
// TODO(rdevlin.cronin): We should ask for permission somehow. |
- if (injector_->CanExecuteOnFrame(extension, frame, tab_id_, top_url) == |
+ if (injector_->CanExecuteOnFrame(injection_host, frame, tab_id_, top_url) == |
PermissionsData::ACCESS_DENIED) { |
DCHECK(frame->parent()); |
continue; |
} |
if (inject_js) |
- InjectJs(extension, frame, execution_results.get()); |
+ InjectJs(injection_host, frame, execution_results.get()); |
if (inject_css) |
InjectCss(frame); |
} |
complete_ = true; |
+ |
+ // TODO(hanxi): don't log these metrics for webUIs' injections. |
injector_->OnInjectionComplete(execution_results.Pass(), |
scripts_run_info, |
run_location_); |
} |
-void ScriptInjection::InjectJs(const Extension* extension, |
+void ScriptInjection::InjectJs(const InjectionHost* injection_host, |
blink::WebLocalFrame* frame, |
base::ListValue* execution_results) { |
std::vector<blink::WebScriptSource> sources = |
@@ -260,11 +261,12 @@ void ScriptInjection::InjectJs(const Extension* extension, |
bool in_main_world = injector_->ShouldExecuteInMainWorld(); |
int world_id = in_main_world |
? DOMActivityLogger::kMainWorldId |
- : GetIsolatedWorldIdForExtension(extension, frame); |
+ : GetIsolatedWorldIdForInstance(injection_host, frame); |
bool expects_results = injector_->ExpectsResults(); |
base::ElapsedTimer exec_timer; |
- DOMActivityLogger::AttachToWorld(world_id, extension->id()); |
+ if (injection_host->id().type() == HostID::EXTENSIONS) |
+ DOMActivityLogger::AttachToWorld(world_id, injection_host->id().id()); |
v8::HandleScope scope(v8::Isolate::GetCurrent()); |
v8::Local<v8::Value> script_value; |
if (in_main_world) { |
@@ -289,7 +291,8 @@ void ScriptInjection::InjectJs(const Extension* extension, |
script_value = (*results)[0]; |
} |
- UMA_HISTOGRAM_TIMES("Extensions.InjectScriptTime", exec_timer.Elapsed()); |
+ if (injection_host->id().type() == HostID::EXTENSIONS) |
+ UMA_HISTOGRAM_TIMES("Extensions.InjectScriptTime", exec_timer.Elapsed()); |
if (expects_results) { |
// Right now, we only support returning single results (per frame). |