Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1319)

Unified Diff: extensions/renderer/script_injection.cc

Issue 885493007: Refactoring: de-couple Extensions from "script injection System" [render side] : 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Plumb script_injection_instance_id from WebViewGuest to script injection. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/renderer/script_injection.cc
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index ea588fe90a47b20b2353411dc9ede8a463d6fc84..cdd74e6b9e24bcb37afa0c8276ab0103c0e9f55b 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -13,6 +13,7 @@
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/v8_value_converter.h"
#include "extensions/common/extension.h"
+#include "extensions/common/extension_consumer.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/manifest_handlers/csp_info.h"
@@ -31,7 +32,8 @@ namespace extensions {
namespace {
-typedef std::map<std::string, int> IsolatedWorldMap;
+using IsolatedWorldKey = std::pair<HostID, int>;
+using IsolatedWorldMap = std::map<IsolatedWorldKey, int>;
base::LazyInstance<IsolatedWorldMap> g_isolated_worlds =
LAZY_INSTANCE_INITIALIZER;
@@ -55,38 +57,58 @@ 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 |host, instance_id|
+// in the given |frame|. If no isolated world has been created for that
+// |host, instance_id| one will be created and initialized.
+int GetIsolatedWorldIdForInstance(const Host* host,
+ int instance_id,
+ 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 HostID& host_id = host->id();
+ IsolatedWorldKey key(host_id, instance_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 hosts for it to matter.
+ isolated_worlds[key] = id;
}
+ GURL origin;
+ std::string name;
+ std::string name_web_view = "WebView";
+ const GURL* origin_ptr = &origin;
+ const std::string* name_ptr = &name;
+
+ if (host_id.type() == HostID::EXTENSIONS) {
+ const Extension* extension =
+ static_cast<const ExtensionConsumer*>(host)->extension();
Devlin 2015/02/04 17:01:14 Generally, having something like class AbstractCla
Xi Han 2015/02/05 16:06:20 Adds some of these functions in the Host class.
+ frame->setIsolatedWorldContentSecurityPolicy(
+ id,
+ blink::WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(
+ extension)));
+ if (instance_id == 0) { // The instance is a TAB.
+ origin_ptr = &extension->url();
+ name_ptr = &extension->name();
+ }
+ }
+ if (instance_id != 0) // The instance is a <webview>.
+ name_ptr = &name_web_view;
+
// 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()));
- frame->setIsolatedWorldContentSecurityPolicy(
- id,
- blink::WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension)));
+ id, blink::WebSecurityOrigin::create(*origin_ptr));
frame->setIsolatedWorldHumanReadableName(
- id,
- blink::WebString::fromUTF8(extension->name()));
+ id, blink::WebString::fromUTF8(*name_ptr));
return id;
}
@@ -94,33 +116,40 @@ int GetIsolatedWorldIdForExtension(const Extension* extension,
} // namespace
// static
-std::string ScriptInjection::GetExtensionIdForIsolatedWorld(
- int isolated_world_id) {
+HostID ScriptInjection::GetHostIdForIsolatedWorld(int isolated_world_id) {
IsolatedWorldMap& isolated_worlds = g_isolated_worlds.Get();
Devlin 2015/02/04 17:01:14 const &
Xi Han 2015/02/05 16:06:20 Done.
- for (IsolatedWorldMap::iterator iter = isolated_worlds.begin();
- iter != isolated_worlds.end();
- ++iter) {
- if (iter->second == isolated_world_id)
- return iter->first;
+ for (auto& kv : isolated_worlds) {
Devlin 2015/02/04 17:01:14 const auto&
Xi Han 2015/02/05 16:06:20 Done.
+ if (kv.second == isolated_world_id)
+ return kv.first.first;
}
- return std::string();
+ return HostID();
}
// static
-void ScriptInjection::RemoveIsolatedWorld(const std::string& extension_id) {
- g_isolated_worlds.Get().erase(extension_id);
+void ScriptInjection::RemoveIsolatedWorld(const std::string& host_id) {
+ std::set<IsolatedWorldKey> keys_to_delete;
+ IsolatedWorldMap& isolated_worlds = g_isolated_worlds.Get();
+ for (auto& kv: isolated_worlds) {
+ const IsolatedWorldKey& key = kv.first;
+ if (key.first.id() == host_id)
+ keys_to_delete.insert(key);
+ }
+ for (auto& key : keys_to_delete)
+ isolated_worlds.erase(key);
}
ScriptInjection::ScriptInjection(
scoped_ptr<ScriptInjector> injector,
blink::WebLocalFrame* web_frame,
- const std::string& extension_id,
+ const HostID& host_id,
+ int instance_id,
UserScript::RunLocation run_location,
int tab_id)
: injector_(injector.Pass()),
web_frame_(web_frame),
- extension_id_(extension_id),
+ host_id_(host_id),
+ instance_id_(instance_id),
run_location_(run_location),
tab_id_(tab_id),
request_id_(kInvalidRequestId),
@@ -133,7 +162,7 @@ ScriptInjection::~ScriptInjection() {
}
bool ScriptInjection::TryToInject(UserScript::RunLocation current_location,
- const Extension* extension,
+ const Host* host,
ScriptsRunInfo* scripts_run_info) {
if (current_location < run_location_)
return false; // Wait for the right location.
@@ -141,11 +170,16 @@ 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 (!host) {
NotifyWillNotInject(ScriptInjector::EXTENSION_REMOVED);
return true; // We're done.
}
+ const Extension* extension =
+ static_cast<const ExtensionConsumer*>(host)->extension();
Devlin 2015/02/04 17:01:14 This feels very unfinished to me. I think I'd rat
Xi Han 2015/02/05 16:06:20 I updated all the if(!host) check, it is a great c
+
+ // TODO(hanxi): refactor ScriptInjection::CanExecuteOnFrame(...) and pass in
+ // Host.
switch (injector_->CanExecuteOnFrame(
extension, web_frame_, tab_id_, web_frame_->top()->document().url())) {
case PermissionsData::ACCESS_DENIED:
@@ -155,7 +189,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(host, scripts_run_info);
return true; // We're done!
}
@@ -164,14 +198,14 @@ bool ScriptInjection::TryToInject(UserScript::RunLocation current_location,
return false;
}
-bool ScriptInjection::OnPermissionGranted(const Extension* extension,
+bool ScriptInjection::OnPermissionGranted(const Host* host,
ScriptsRunInfo* scripts_run_info) {
- if (!extension) {
+ if (!host) {
NotifyWillNotInject(ScriptInjector::EXTENSION_REMOVED);
return false;
}
- Inject(extension, scripts_run_info);
+ Inject(host, scripts_run_info);
return true;
}
@@ -185,7 +219,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,9 +230,9 @@ void ScriptInjection::NotifyWillNotInject(
injector_->OnWillNotInject(reason);
}
-void ScriptInjection::Inject(const Extension* extension,
+void ScriptInjection::Inject(const Host* host,
ScriptsRunInfo* scripts_run_info) {
- DCHECK(extension);
+ DCHECK(host);
DCHECK(scripts_run_info);
DCHECK(!complete_);
@@ -229,19 +263,21 @@ 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
+ // host might only have access to a subset of them.
+ // For child frames, we just skip ones the 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.
+ const Extension* extension =
+ static_cast<const ExtensionConsumer*>(host)->extension();
if (injector_->CanExecuteOnFrame(extension, frame, tab_id_, top_url) ==
PermissionsData::ACCESS_DENIED) {
DCHECK(frame->parent());
continue;
}
if (inject_js)
- InjectJs(extension, frame, execution_results.get());
+ InjectJs(host, frame, execution_results.get());
if (inject_css)
InjectCss(frame);
}
@@ -252,7 +288,7 @@ void ScriptInjection::Inject(const Extension* extension,
run_location_);
}
-void ScriptInjection::InjectJs(const Extension* extension,
+void ScriptInjection::InjectJs(const Host* host,
blink::WebLocalFrame* frame,
base::ListValue* execution_results) {
std::vector<blink::WebScriptSource> sources =
@@ -260,11 +296,11 @@ void ScriptInjection::InjectJs(const Extension* extension,
bool in_main_world = injector_->ShouldExecuteInMainWorld();
int world_id = in_main_world
? DOMActivityLogger::kMainWorldId
- : GetIsolatedWorldIdForExtension(extension, frame);
+ : GetIsolatedWorldIdForInstance(host, instance_id_, frame);
bool expects_results = injector_->ExpectsResults();
base::ElapsedTimer exec_timer;
- DOMActivityLogger::AttachToWorld(world_id, extension->id());
+ DOMActivityLogger::AttachToWorld(world_id, host->id().id());
v8::HandleScope scope(v8::Isolate::GetCurrent());
v8::Local<v8::Value> script_value;
if (in_main_world) {

Powered by Google App Engine
This is Rietveld 408576698