summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/extensions.gypi2
-rw-r--r--extensions/renderer/dispatcher.cc2
-rw-r--r--extensions/renderer/extension_injection_host.cc23
-rw-r--r--extensions/renderer/extension_injection_host.h12
-rw-r--r--extensions/renderer/injection_host.h3
-rw-r--r--extensions/renderer/script_injection.cc54
-rw-r--r--extensions/renderer/script_injection.h24
-rw-r--r--extensions/renderer/script_injection_manager.cc73
-rw-r--r--extensions/renderer/script_injection_manager.h3
-rw-r--r--extensions/renderer/user_script_set.cc32
-rw-r--r--extensions/renderer/user_script_set.h5
-rw-r--r--extensions/renderer/user_script_set_manager.cc7
-rw-r--r--extensions/renderer/user_script_set_manager.h7
-rw-r--r--extensions/renderer/web_ui_injection_host.cc41
-rw-r--r--extensions/renderer/web_ui_injection_host.h33
15 files changed, 211 insertions, 110 deletions
diff --git a/extensions/extensions.gypi b/extensions/extensions.gypi
index 4c2e6cd..20ed947 100644
--- a/extensions/extensions.gypi
+++ b/extensions/extensions.gypi
@@ -970,6 +970,8 @@
'renderer/v8_context_native_handler.h',
'renderer/v8_schema_registry.cc',
'renderer/v8_schema_registry.h',
+ 'renderer/web_ui_injection_host.cc',
+ 'renderer/web_ui_injection_host.h',
],
'extensions_utility_sources': [
'utility/unpacker.cc',
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index e4287e5..38c3e03 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -1036,6 +1036,8 @@ void Dispatcher::OnUnloaded(const std::string& id) {
extensions_.Remove(id);
active_extension_ids_.erase(id);
+ script_injection_manager_->OnExtensionUnloaded(id);
+
// If the extension is later reloaded with a different set of permissions,
// we'd like it to get a new isolated world ID, so that it can pick up the
// changed origin whitelist.
diff --git a/extensions/renderer/extension_injection_host.cc b/extensions/renderer/extension_injection_host.cc
index 55ee1cc..7a27a08 100644
--- a/extensions/renderer/extension_injection_host.cc
+++ b/extensions/renderer/extension_injection_host.cc
@@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "extensions/common/extension_set.h"
#include "extensions/common/manifest_handlers/csp_info.h"
#include "extensions/renderer/extension_injection_host.h"
namespace extensions {
ExtensionInjectionHost::ExtensionInjectionHost(
- const scoped_refptr<const Extension>& extension)
+ const Extension* extension)
: InjectionHost(HostID(HostID::EXTENSIONS, extension->id())),
extension_(extension) {
}
@@ -16,8 +17,18 @@ ExtensionInjectionHost::ExtensionInjectionHost(
ExtensionInjectionHost::~ExtensionInjectionHost() {
}
-const std::string& ExtensionInjectionHost::GetContentSecurityPolicy() const {
- return CSPInfo::GetContentSecurityPolicy(extension_.get());
+// static
+scoped_ptr<const ExtensionInjectionHost> ExtensionInjectionHost::Create(
+ const std::string& extension_id, const ExtensionSet* extensions) {
+ const Extension* extension = extensions->GetByID(extension_id);
+ if (!extension)
+ return scoped_ptr<const ExtensionInjectionHost>();
+ return scoped_ptr<const ExtensionInjectionHost>(
+ new ExtensionInjectionHost(extension));
+}
+
+std::string ExtensionInjectionHost::GetContentSecurityPolicy() const {
+ return CSPInfo::GetContentSecurityPolicy(extension_);
}
const GURL& ExtensionInjectionHost::url() const {
@@ -43,7 +54,7 @@ PermissionsData::AccessType ExtensionInjectionHost::CanExecuteOnFrame(
// "content script access" logic.
if (is_declarative) {
return extension_->permissions_data()->GetPageAccess(
- extension_.get(),
+ extension_,
document_url,
top_frame_url,
tab_id,
@@ -51,7 +62,7 @@ PermissionsData::AccessType ExtensionInjectionHost::CanExecuteOnFrame(
nullptr /* ignore error */);
} else {
return extension_->permissions_data()->GetContentScriptAccess(
- extension_.get(),
+ extension_,
document_url,
top_frame_url,
tab_id,
@@ -66,7 +77,7 @@ bool ExtensionInjectionHost::ShouldNotifyBrowserOfInjection() const {
// otherwise been affected by the scripts-require-action feature.
return extension_->permissions_data()->withheld_permissions()->IsEmpty() &&
PermissionsData::ScriptsMayRequireActionForExtension(
- extension_.get(),
+ extension_,
extension_->permissions_data()->active_permissions().get());
}
diff --git a/extensions/renderer/extension_injection_host.h b/extensions/renderer/extension_injection_host.h
index d940c94..bdf6f41 100644
--- a/extensions/renderer/extension_injection_host.h
+++ b/extensions/renderer/extension_injection_host.h
@@ -10,17 +10,23 @@
#include "extensions/renderer/injection_host.h"
namespace extensions {
+class ExtensionSet;
// A wrapper class that holds an extension and implements the InjectionHost
// interface.
class ExtensionInjectionHost : public InjectionHost {
public:
- ExtensionInjectionHost(const scoped_refptr<const Extension>& extension);
+ ExtensionInjectionHost(const Extension* extension);
~ExtensionInjectionHost() override;
+ // Create an ExtensionInjectionHost object. If the extension is gone, returns
+ // a null scoped ptr.
+ static scoped_ptr<const ExtensionInjectionHost> Create(
+ const std::string& extension_id, const ExtensionSet* extensions);
+
private:
// InjectionHost:
- const std::string& GetContentSecurityPolicy() const override;
+ std::string GetContentSecurityPolicy() const override;
const GURL& url() const override;
const std::string& name() const override;
PermissionsData::AccessType CanExecuteOnFrame(
@@ -30,7 +36,7 @@ class ExtensionInjectionHost : public InjectionHost {
bool is_declarative) const override;
bool ShouldNotifyBrowserOfInjection() const override;
- scoped_refptr<const Extension> extension_;
+ const Extension* extension_;
DISALLOW_COPY_AND_ASSIGN(ExtensionInjectionHost);
};
diff --git a/extensions/renderer/injection_host.h b/extensions/renderer/injection_host.h
index 6c23c2d..4dcb225 100644
--- a/extensions/renderer/injection_host.h
+++ b/extensions/renderer/injection_host.h
@@ -15,7 +15,7 @@ class InjectionHost {
InjectionHost(const HostID& host_id);
virtual ~InjectionHost();
- virtual const std::string& GetContentSecurityPolicy() const = 0;
+ virtual std::string GetContentSecurityPolicy() const = 0;
// The base url for the host.
virtual const GURL& url() const = 0;
@@ -35,6 +35,7 @@ class InjectionHost {
virtual bool ShouldNotifyBrowserOfInjection() const = 0;
const HostID& id() const { return id_; }
+
private:
// The ID of the host.
HostID id_;
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index 58cf328..3bb279a 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -108,16 +108,17 @@ void ScriptInjection::RemoveIsolatedWorld(const std::string& host_id) {
ScriptInjection::ScriptInjection(
scoped_ptr<ScriptInjector> injector,
blink::WebLocalFrame* web_frame,
- const HostID& host_id,
+ scoped_ptr<const InjectionHost> injection_host,
UserScript::RunLocation run_location,
int tab_id)
: injector_(injector.Pass()),
web_frame_(web_frame),
- host_id_(host_id),
+ injection_host_(injection_host.Pass()),
run_location_(run_location),
tab_id_(tab_id),
request_id_(kInvalidRequestId),
complete_(false) {
+ CHECK(injection_host_.get());
}
ScriptInjection::~ScriptInjection() {
@@ -126,7 +127,6 @@ ScriptInjection::~ScriptInjection() {
}
bool ScriptInjection::TryToInject(UserScript::RunLocation current_location,
- const InjectionHost* injection_host,
ScriptsRunInfo* scripts_run_info) {
if (current_location < run_location_)
return false; // Wait for the right location.
@@ -134,13 +134,14 @@ bool ScriptInjection::TryToInject(UserScript::RunLocation current_location,
if (request_id_ != kInvalidRequestId)
return false; // We're waiting for permission right now, try again later.
- if (!injection_host) {
+ if (!injection_host_) {
NotifyWillNotInject(ScriptInjector::EXTENSION_REMOVED);
return true; // We're done.
}
- switch (injector_->CanExecuteOnFrame(injection_host, web_frame_, tab_id_,
- web_frame_->top()->document().url())) {
+ switch (injector_->CanExecuteOnFrame(
+ injection_host_.get(), web_frame_, tab_id_,
+ web_frame_->top()->document().url())) {
case PermissionsData::ACCESS_DENIED:
NotifyWillNotInject(ScriptInjector::NOT_ALLOWED);
return true; // We're done.
@@ -148,7 +149,7 @@ bool ScriptInjection::TryToInject(UserScript::RunLocation current_location,
SendInjectionMessage(true /* request permission */);
return false; // Wait around for permission.
case PermissionsData::ACCESS_ALLOWED:
- Inject(injection_host, scripts_run_info);
+ Inject(scripts_run_info);
return true; // We're done!
}
@@ -156,17 +157,20 @@ bool ScriptInjection::TryToInject(UserScript::RunLocation current_location,
return false;
}
-bool ScriptInjection::OnPermissionGranted(const InjectionHost* injection_host,
- ScriptsRunInfo* scripts_run_info) {
- if (!injection_host) {
+bool ScriptInjection::OnPermissionGranted(ScriptsRunInfo* scripts_run_info) {
+ if (!injection_host_) {
NotifyWillNotInject(ScriptInjector::EXTENSION_REMOVED);
return false;
}
- Inject(injection_host, scripts_run_info);
+ Inject(scripts_run_info);
return true;
}
+void ScriptInjection::OnHostRemoved() {
+ injection_host_.reset(nullptr);
+}
+
void ScriptInjection::SendInjectionMessage(bool request_permission) {
content::RenderView* render_view =
content::RenderView::FromWebView(web_frame()->top()->view());
@@ -176,7 +180,7 @@ void ScriptInjection::SendInjectionMessage(bool request_permission) {
request_id_ = request_permission ? g_next_pending_id++ : kInvalidRequestId;
render_view->Send(new ExtensionHostMsg_RequestScriptInjectionPermission(
render_view->GetRoutingID(),
- host_id_.id(),
+ host_id().id(),
injector_->script_type(),
request_id_));
}
@@ -187,13 +191,12 @@ void ScriptInjection::NotifyWillNotInject(
injector_->OnWillNotInject(reason);
}
-void ScriptInjection::Inject(const InjectionHost* injection_host,
- ScriptsRunInfo* scripts_run_info) {
- DCHECK(injection_host);
+void ScriptInjection::Inject(ScriptsRunInfo* scripts_run_info) {
+ DCHECK(injection_host_);
DCHECK(scripts_run_info);
DCHECK(!complete_);
- if (injection_host->ShouldNotifyBrowserOfInjection())
+ if (injection_host_->ShouldNotifyBrowserOfInjection())
SendInjectionMessage(false /* don't request permission */);
std::vector<blink::WebFrame*> frame_vector;
@@ -226,13 +229,14 @@ void ScriptInjection::Inject(const InjectionHost* injection_host,
// 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(injection_host, frame, tab_id_, top_url) ==
- PermissionsData::ACCESS_DENIED) {
+ if (injector_->CanExecuteOnFrame(
+ injection_host_.get(), frame, tab_id_, top_url) ==
+ PermissionsData::ACCESS_DENIED) {
DCHECK(frame->parent());
continue;
}
if (inject_js)
- InjectJs(injection_host, frame, execution_results.get());
+ InjectJs(frame, execution_results.get());
if (inject_css)
InjectCss(frame);
}
@@ -245,20 +249,20 @@ void ScriptInjection::Inject(const InjectionHost* injection_host,
run_location_);
}
-void ScriptInjection::InjectJs(const InjectionHost* injection_host,
- blink::WebLocalFrame* frame,
+void ScriptInjection::InjectJs(blink::WebLocalFrame* frame,
base::ListValue* execution_results) {
std::vector<blink::WebScriptSource> sources =
injector_->GetJsSources(run_location_);
bool in_main_world = injector_->ShouldExecuteInMainWorld();
int world_id = in_main_world
? DOMActivityLogger::kMainWorldId
- : GetIsolatedWorldIdForInstance(injection_host, frame);
+ : GetIsolatedWorldIdForInstance(injection_host_.get(),
+ frame);
bool expects_results = injector_->ExpectsResults();
base::ElapsedTimer exec_timer;
- if (injection_host->id().type() == HostID::EXTENSIONS)
- DOMActivityLogger::AttachToWorld(world_id, injection_host->id().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) {
@@ -283,7 +287,7 @@ void ScriptInjection::InjectJs(const InjectionHost* injection_host,
script_value = (*results)[0];
}
- if (injection_host->id().type() == HostID::EXTENSIONS)
+ if (injection_host_->id().type() == HostID::EXTENSIONS)
UMA_HISTOGRAM_TIMES("Extensions.InjectScriptTime", exec_timer.Elapsed());
if (expects_results) {
diff --git a/extensions/renderer/script_injection.h b/extensions/renderer/script_injection.h
index a883545..9f4691c 100644
--- a/extensions/renderer/script_injection.h
+++ b/extensions/renderer/script_injection.h
@@ -8,9 +8,9 @@
#include "base/basictypes.h"
#include "base/macros.h"
#include "extensions/common/user_script.h"
+#include "extensions/renderer/injection_host.h"
#include "extensions/renderer/script_injector.h"
-class InjectionHost;
struct HostID;
namespace blink {
@@ -32,7 +32,7 @@ class ScriptInjection {
ScriptInjection(scoped_ptr<ScriptInjector> injector,
blink::WebLocalFrame* web_frame,
- const HostID& host_id,
+ scoped_ptr<const InjectionHost> injection_host,
UserScript::RunLocation run_location,
int tab_id);
~ScriptInjection();
@@ -41,19 +41,19 @@ class ScriptInjection {
// the script has either injected or will never inject (i.e., if the object
// is done), and false if injection is delayed (either for permission purposes
// or because |current_location| is not the designated |run_location_|).
- // NOTE: |injection_host| may be NULL, if the injection_host is removed!
bool TryToInject(UserScript::RunLocation current_location,
- const InjectionHost* injection_host,
ScriptsRunInfo* scripts_run_info);
// Called when permission for the given injection has been granted.
// Returns true if the injection ran.
- bool OnPermissionGranted(const InjectionHost* injection_host,
- ScriptsRunInfo* scripts_run_info);
+ bool OnPermissionGranted(ScriptsRunInfo* scripts_run_info);
+
+ // Resets the pointer of the injection host when the host is gone.
+ void OnHostRemoved();
// Accessors.
blink::WebLocalFrame* web_frame() const { return web_frame_; }
- const HostID& host_id() const { return host_id_; }
+ const HostID& host_id() const { return injection_host_->id(); }
int64 request_id() const { return request_id_; }
private:
@@ -62,13 +62,11 @@ class ScriptInjection {
void SendInjectionMessage(bool request_permission);
// Injects the script, optionally populating |scripts_run_info|.
- void Inject(const InjectionHost* injection_host,
- ScriptsRunInfo* scripts_run_info);
+ void Inject(ScriptsRunInfo* scripts_run_info);
// Inject any JS scripts into the |frame|, optionally populating
// |execution_results|.
- void InjectJs(const InjectionHost* injection_host,
- blink::WebLocalFrame* frame,
+ void InjectJs(blink::WebLocalFrame* frame,
base::ListValue* execution_results);
// Inject any CSS source into the |frame|.
@@ -83,8 +81,8 @@ class ScriptInjection {
// The (main) WebFrame into which this should inject the script.
blink::WebLocalFrame* web_frame_;
- // The id of the associated injection_host.
- HostID host_id_;
+ // The associated injection host.
+ scoped_ptr<const InjectionHost> injection_host_;
// The location in the document load at which we inject the script.
UserScript::RunLocation run_location_;
diff --git a/extensions/renderer/script_injection_manager.cc b/extensions/renderer/script_injection_manager.cc
index 93862dd..7deb027 100644
--- a/extensions/renderer/script_injection_manager.cc
+++ b/extensions/renderer/script_injection_manager.cc
@@ -53,20 +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
-// is removed.
-scoped_ptr<ExtensionInjectionHost> GetExtensionInjectionHost(
- const std::string& extension_id, const ExtensionSet* extensions) {
- const Extension* extension = extensions->GetByID(extension_id);
- if (!extension)
- return scoped_ptr<ExtensionInjectionHost>();
- return scoped_ptr<ExtensionInjectionHost>(
- new ExtensionInjectionHost(extension));
-}
-
} // namespace
class ScriptInjectionManager::RVOHelper : public content::RenderViewObserver {
@@ -256,6 +242,23 @@ void ScriptInjectionManager::OnRenderViewCreated(
rvo_helpers_.push_back(new RVOHelper(render_view, this));
}
+void ScriptInjectionManager::OnExtensionUnloaded(
+ const std::string& extension_id) {
+ for (auto iter = pending_injections_.begin();
+ iter != pending_injections_.end();) {
+ if ((*iter)->host_id().id() == extension_id) {
+ (*iter)->OnHostRemoved();
+ iter = pending_injections_.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+ // If we are currently injection scripts, we need to make a note that this
+ // extension is "dirty" (invalidated).
+ if (injecting_scripts_)
+ invalidated_while_injecting_.insert(extension_id);
+}
+
void ScriptInjectionManager::OnUserScriptsUpdated(
const std::set<std::string>& changed_extensions,
const std::vector<UserScript*>& scripts) {
@@ -392,15 +395,12 @@ void ScriptInjectionManager::InjectScripts(
if (!IsFrameValid(frame))
break;
- 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 &&
+ // Try to inject the script if the injection host 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((*iter)->host_id().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);
@@ -433,23 +433,25 @@ void ScriptInjectionManager::HandleExecuteCode(
return;
}
+ scoped_ptr<const ExtensionInjectionHost> extension_injection_host =
+ ExtensionInjectionHost::Create(params.extension_id, extensions_);
+
+ if (!extension_injection_host)
+ return;
+
scoped_ptr<ScriptInjection> injection(new ScriptInjection(
scoped_ptr<ScriptInjector>(
new ProgrammaticScriptInjector(params, main_frame)),
main_frame,
- HostID(HostID::EXTENSIONS, params.extension_id),
+ extension_injection_host.Pass(),
static_cast<UserScript::RunLocation>(params.run_at),
ExtensionHelper::Get(render_view)->tab_id()));
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());
}
@@ -461,9 +463,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.
scoped_ptr<ScriptInjection> injection =
@@ -472,12 +471,11 @@ void ScriptInjectionManager::HandleExecuteDeclarativeScript(
web_frame->toWebLocalFrame(),
tab_id,
url,
- extension);
- if (injection.get()) {
+ extension_id);
+ if (injection) {
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);
scripts_run_info.LogRun(web_frame, UserScript::BROWSER_DRIVEN);
}
@@ -487,8 +485,10 @@ void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) {
ScopedVector<ScriptInjection>::iterator iter =
pending_injections_.begin();
for (; iter != pending_injections_.end(); ++iter) {
- if ((*iter)->request_id() == request_id)
+ if ((*iter)->request_id() == request_id) {
+ DCHECK((*iter)->host_id().type() == HostID::EXTENSIONS);
break;
+ }
}
if (iter == pending_injections_.end())
return;
@@ -502,10 +502,7 @@ void ScriptInjectionManager::HandlePermitScriptInjection(int64 request_id) {
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)) {
+ if (injection->OnPermissionGranted(&scripts_run_info)) {
scripts_run_info.LogRun(injection->web_frame(), UserScript::RUN_DEFERRED);
}
}
diff --git a/extensions/renderer/script_injection_manager.h b/extensions/renderer/script_injection_manager.h
index 8ec3d94..08cf1e1 100644
--- a/extensions/renderer/script_injection_manager.h
+++ b/extensions/renderer/script_injection_manager.h
@@ -45,6 +45,9 @@ class ScriptInjectionManager : public UserScriptSetManager::Observer {
// Notifies that a new render view has been created.
void OnRenderViewCreated(content::RenderView* render_view);
+ // Removes pending injections of the unloaded extension.
+ void OnExtensionUnloaded(const std::string& extension_id);
+
private:
// A RenderViewObserver implementation which watches the various render views
// in order to notify the ScriptInjectionManager of different document load
diff --git a/extensions/renderer/user_script_set.cc b/extensions/renderer/user_script_set.cc
index 1d66aaa..df7c7c9 100644
--- a/extensions/renderer/user_script_set.cc
+++ b/extensions/renderer/user_script_set.cc
@@ -12,9 +12,11 @@
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/renderer/extension_injection_host.h"
#include "extensions/renderer/extensions_renderer_client.h"
+#include "extensions/renderer/injection_host.h"
#include "extensions/renderer/script_context.h"
#include "extensions/renderer/script_injection.h"
#include "extensions/renderer/user_script_injector.h"
+#include "extensions/renderer/web_ui_injection_host.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "url/gurl.h"
@@ -55,6 +57,8 @@ void UserScriptSet::GetActiveExtensionIds(
for (ScopedVector<UserScript>::const_iterator iter = scripts_.begin();
iter != scripts_.end();
++iter) {
+ if ((*iter)->host_id().type() != HostID::EXTENSIONS)
+ continue;
DCHECK(!(*iter)->extension_id().empty());
ids->insert((*iter)->extension_id());
}
@@ -69,16 +73,12 @@ void UserScriptSet::GetInjections(
for (ScopedVector<UserScript>::const_iterator iter = scripts_.begin();
iter != scripts_.end();
++iter) {
- const Extension* extension = extensions_->GetByID((*iter)->extension_id());
- if (!extension)
- continue;
scoped_ptr<ScriptInjection> injection = GetInjectionForScript(
*iter,
web_frame,
tab_id,
run_location,
document_url,
- extension,
false /* is_declarative */);
if (injection.get())
injections->push_back(injection.release());
@@ -155,8 +155,7 @@ scoped_ptr<ScriptInjection> UserScriptSet::GetDeclarativeScriptInjection(
blink::WebFrame* web_frame,
int tab_id,
UserScript::RunLocation run_location,
- const GURL& document_url,
- const Extension* extension) {
+ const GURL& document_url) {
for (ScopedVector<UserScript>::const_iterator it = scripts_.begin();
it != scripts_.end();
++it) {
@@ -166,7 +165,6 @@ scoped_ptr<ScriptInjection> UserScriptSet::GetDeclarativeScriptInjection(
tab_id,
run_location,
document_url,
- extension,
true /* is_declarative */);
}
}
@@ -181,9 +179,20 @@ scoped_ptr<ScriptInjection> UserScriptSet::GetInjectionForScript(
int tab_id,
UserScript::RunLocation run_location,
const GURL& document_url,
- const Extension* extension,
bool is_declarative) {
scoped_ptr<ScriptInjection> injection;
+ scoped_ptr<const InjectionHost> injection_host;
+
+ const HostID& host_id = script->host_id();
+ if (host_id.type() == HostID::EXTENSIONS) {
+ injection_host = ExtensionInjectionHost::Create(host_id.id(), extensions_);
+ if (!injection_host)
+ return injection.Pass();
+ } else {
+ DCHECK_EQ(host_id.type(), HostID::WEBUI);
+ injection_host.reset(new WebUIInjectionHost(host_id));
+ }
+
if (web_frame->parent() && !script->match_all_frames())
return injection.Pass(); // Only match subframes if the script declared it.
@@ -196,11 +205,8 @@ scoped_ptr<ScriptInjection> UserScriptSet::GetInjectionForScript(
scoped_ptr<ScriptInjector> injector(new UserScriptInjector(script,
this,
is_declarative));
- HostID host_id(HostID::EXTENSIONS, extension->id());
- ExtensionInjectionHost extension_injection_host(
- make_scoped_refptr<const Extension>(extension));
if (injector->CanExecuteOnFrame(
- &extension_injection_host,
+ injection_host.get(),
web_frame,
-1, // Content scripts are not tab-specific.
web_frame->top()->document().url()) ==
@@ -216,7 +222,7 @@ scoped_ptr<ScriptInjection> UserScriptSet::GetInjectionForScript(
injection.reset(new ScriptInjection(
injector.Pass(),
web_frame->toWebLocalFrame(),
- host_id,
+ injection_host.Pass(),
run_location,
tab_id));
}
diff --git a/extensions/renderer/user_script_set.h b/extensions/renderer/user_script_set.h
index e8d48f9..ab2b585 100644
--- a/extensions/renderer/user_script_set.h
+++ b/extensions/renderer/user_script_set.h
@@ -24,7 +24,6 @@ class WebFrame;
}
namespace extensions {
-class Extension;
class ExtensionSet;
class ScriptInjection;
@@ -64,8 +63,7 @@ class UserScriptSet {
blink::WebFrame* web_frame,
int tab_id,
UserScript::RunLocation run_location,
- const GURL& document_url,
- const Extension* extension);
+ const GURL& document_url);
// Updates scripts given the shared memory region containing user scripts.
// Returns true if the scripts were successfully updated.
@@ -83,7 +81,6 @@ class UserScriptSet {
int tab_id,
UserScript::RunLocation run_location,
const GURL& document_url,
- const Extension* extension,
bool is_declarative);
// Shared memory containing raw script data.
diff --git a/extensions/renderer/user_script_set_manager.cc b/extensions/renderer/user_script_set_manager.cc
index 4379bab..2a6425f 100644
--- a/extensions/renderer/user_script_set_manager.cc
+++ b/extensions/renderer/user_script_set_manager.cc
@@ -38,9 +38,9 @@ UserScriptSetManager::GetInjectionForDeclarativeScript(
blink::WebFrame* web_frame,
int tab_id,
const GURL& url,
- const Extension* extension) {
+ const std::string& extension_id) {
UserScriptSet* user_script_set =
- GetProgrammaticScriptsByExtension(extension->id());
+ GetProgrammaticScriptsByExtension(extension_id);
if (!user_script_set)
return scoped_ptr<ScriptInjection>();
@@ -49,8 +49,7 @@ UserScriptSetManager::GetInjectionForDeclarativeScript(
web_frame,
tab_id,
UserScript::BROWSER_DRIVEN,
- url,
- extension);
+ url);
}
bool UserScriptSetManager::OnControlMessageReceived(
diff --git a/extensions/renderer/user_script_set_manager.h b/extensions/renderer/user_script_set_manager.h
index d102ea3..4b5e4f0 100644
--- a/extensions/renderer/user_script_set_manager.h
+++ b/extensions/renderer/user_script_set_manager.h
@@ -56,14 +56,15 @@ class UserScriptSetManager : public content::RenderProcessObserver {
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
- // Looks up the script injection associated with |script_id| and |extension|
- // in the context of the given |web_frame|, |tab_id|, and |url|.
+ // Looks up the script injection associated with |script_id| and
+ // |extension_id| in the context of the given |web_frame|, |tab_id|,
+ // and |url|.
scoped_ptr<ScriptInjection> GetInjectionForDeclarativeScript(
int script_id,
blink::WebFrame* web_frame,
int tab_id,
const GURL& url,
- const Extension* extension);
+ const std::string& extension_id);
// Append all injections from |static_scripts| and each of
// |programmatic_scripts_| to |injections|.
diff --git a/extensions/renderer/web_ui_injection_host.cc b/extensions/renderer/web_ui_injection_host.cc
new file mode 100644
index 0000000..334358a
--- /dev/null
+++ b/extensions/renderer/web_ui_injection_host.cc
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/web_ui_injection_host.h"
+
+WebUIInjectionHost::WebUIInjectionHost(const HostID& host_id)
+ : InjectionHost(host_id),
+ url_(host_id.id()) {
+}
+
+WebUIInjectionHost::~WebUIInjectionHost() {
+}
+
+
+std::string WebUIInjectionHost::GetContentSecurityPolicy() const {
+ return std::string();
+}
+
+const GURL& WebUIInjectionHost::url() const {
+ return url_;
+}
+
+const std::string& WebUIInjectionHost::name() const {
+ return id().id();
+}
+
+extensions::PermissionsData::AccessType WebUIInjectionHost::CanExecuteOnFrame(
+ const GURL& document_url,
+ const GURL& top_frame_url,
+ int tab_id,
+ bool is_declarative) const {
+ // Content scripts are allowed to inject on webviews created by WebUI.
+ return extensions::PermissionsData::AccessType::ACCESS_ALLOWED;
+}
+
+bool WebUIInjectionHost::ShouldNotifyBrowserOfInjection() const {
+ // We don't notify browser of any injection made from WebUI, since the
+ // decision for injection is made in the render.
+ return false;
+}
diff --git a/extensions/renderer/web_ui_injection_host.h b/extensions/renderer/web_ui_injection_host.h
new file mode 100644
index 0000000..c81dd5d
--- /dev/null
+++ b/extensions/renderer/web_ui_injection_host.h
@@ -0,0 +1,33 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_RENDERER_WEBUI_INJECTION_HOST_H_
+#define EXTENSIONS_RENDERER_WEBUI_INJECTION_HOST_H_
+
+#include "extensions/renderer/injection_host.h"
+
+class WebUIInjectionHost : public InjectionHost {
+ public:
+ WebUIInjectionHost(const HostID& host_id);
+ ~WebUIInjectionHost() override;
+
+ private:
+ // InjectionHost:
+ std::string GetContentSecurityPolicy() const override;
+ const GURL& url() const override;
+ const std::string& name() const override;
+ extensions::PermissionsData::AccessType CanExecuteOnFrame(
+ const GURL& document_url,
+ const GURL& top_frame_url,
+ int tab_id,
+ bool is_declarative) const override;
+ bool ShouldNotifyBrowserOfInjection() const override;
+
+ private:
+ GURL url_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebUIInjectionHost);
+};
+
+#endif // EXTENSIONS_RENDERER_WEBUI_INJECTION_HOST_H_