Index: chrome/browser/extensions/active_script_controller.cc |
diff --git a/chrome/browser/extensions/active_script_controller.cc b/chrome/browser/extensions/active_script_controller.cc |
index 906da8ec1d37f32ccda26e75a42be9f4903a5eb9..0f4e10fd07fe9224a4a4d013f87796bba320d9e3 100644 |
--- a/chrome/browser/extensions/active_script_controller.cc |
+++ b/chrome/browser/extensions/active_script_controller.cc |
@@ -25,11 +25,31 @@ |
#include "extensions/common/extension_messages.h" |
#include "extensions/common/extension_set.h" |
#include "extensions/common/feature_switch.h" |
+#include "extensions/common/manifest.h" |
#include "extensions/common/permissions/permissions_data.h" |
#include "ipc/ipc_message_macros.h" |
namespace extensions { |
+namespace { |
+ |
+// Returns true if the extension should be regarded as a "permitted" extension |
+// for the case of metrics. We need this because we only actually withhold |
+// permissions if the switch is enabled, but want to record metrics in all |
+// cases. |
+// "ExtensionWouldHaveHadHostPermissionsWithheldIfSwitchWasOn()" would be |
+// more accurate, but too long. |
+bool ShouldRecordExtension(const Extension* extension) { |
+ return extension->ShouldDisplayInExtensionSettings() && |
+ !Manifest::IsPolicyLocation(extension->location()) && |
+ !Manifest::IsComponentLocation(extension->location()) && |
+ !PermissionsData::CanExecuteScriptEverywhere(extension) && |
+ extension->permissions_data()->active_permissions() |
+ ->ShouldWarnAllHosts(); |
not at google - send to devlin
2014/06/27 23:24:33
don't you need to check withheld permissions as we
Devlin
2014/06/30 17:06:09
No.
This method is the yak shave for being able t
|
+} |
+ |
+} // namespace |
+ |
ActiveScriptController::PendingRequest::PendingRequest() : |
page_id(-1) { |
} |
@@ -70,40 +90,6 @@ ActiveScriptController* ActiveScriptController::GetForWebContents( |
return location_bar_controller->active_script_controller(); |
} |
-bool ActiveScriptController::RequiresUserConsentForScriptInjection( |
- const Extension* extension) { |
- CHECK(extension); |
- if (!extension->permissions_data()->RequiresActionForScriptExecution( |
- extension, |
- SessionID::IdForTab(web_contents()), |
- web_contents()->GetVisibleURL()) || |
- util::AllowedScriptingOnAllUrls(extension->id(), |
- web_contents()->GetBrowserContext())) { |
- return false; |
- } |
- |
- // If the feature is not enabled, we automatically allow all extensions to |
- // run scripts. |
- if (!enabled_) |
- permitted_extensions_.insert(extension->id()); |
- |
- return permitted_extensions_.count(extension->id()) == 0; |
-} |
- |
-void ActiveScriptController::RequestScriptInjection( |
- const Extension* extension, |
- int page_id, |
- const base::Closure& callback) { |
- CHECK(extension); |
- PendingRequestList& list = pending_requests_[extension->id()]; |
- list.push_back(PendingRequest(callback, page_id)); |
- |
- // If this was the first entry, notify the location bar that there's a new |
- // icon. |
- if (list.size() == 1u) |
- LocationBarController::NotifyChange(web_contents()); |
-} |
- |
void ActiveScriptController::OnActiveTabPermissionGranted( |
const Extension* extension) { |
RunPendingForExtension(extension); |
@@ -174,13 +160,55 @@ void ActiveScriptController::OnExtensionUnloaded(const Extension* extension) { |
pending_requests_.erase(iter); |
} |
+PermissionsData::AccessType |
+ActiveScriptController::RequiresUserConsentForScriptInjection( |
+ const Extension* extension, |
+ extension_misc::InjectedScriptType type) { |
+ CHECK(extension); |
+ |
+ // If the feature is not enabled, we automatically allow all extensions to |
+ // run scripts. |
+ if (!enabled_) |
+ permitted_extensions_.insert(extension->id()); |
+ |
+ // Allow the extension if it's been explicitly granted permission. |
+ if (permitted_extensions_.count(extension->id()) > 0) |
+ return PermissionsData::ALLOW_ACCESS; |
+ |
+ PermissionsData::AccessType access = PermissionsData::DENY_ACCESS; |
+ GURL url = web_contents()->GetVisibleURL(); |
+ int tab_id = SessionID::IdForTab(web_contents()); |
+ switch (type) { |
+ case extension_misc::CONTENT_SCRIPT: |
+ access = extension->permissions_data() |
+ ->CanRunContentScriptOnPageWithUserConsent( |
+ extension, url, url, tab_id, -1, NULL); |
+ break; |
+ case extension_misc::PROGRAMMATIC_SCRIPT: |
+ access = extension->permissions_data()->CanAccessPageWithUserConsent( |
+ extension, url, url, tab_id, -1, NULL); |
+ } |
not at google - send to devlin
2014/06/27 23:24:33
nit: I'd prefer to phrase this more succinctly wit
not at google - send to devlin
2014/06/30 14:37:03
I mean "without declaring |access|"
Devlin
2014/06/30 17:06:09
Sure, why not.
|
+ |
+ return access; |
+} |
+ |
+void ActiveScriptController::RequestScriptInjection( |
+ const Extension* extension, |
+ int page_id, |
+ const base::Closure& callback) { |
+ CHECK(extension); |
+ PendingRequestList& list = pending_requests_[extension->id()]; |
+ list.push_back(PendingRequest(callback, page_id)); |
+ |
+ // If this was the first entry, notify the location bar that there's a new |
+ // icon. |
+ if (list.size() == 1u) |
+ LocationBarController::NotifyChange(web_contents()); |
+} |
+ |
void ActiveScriptController::RunPendingForExtension( |
const Extension* extension) { |
DCHECK(extension); |
- PendingRequestMap::iterator iter = |
- pending_requests_.find(extension->id()); |
- if (iter == pending_requests_.end()) |
- return; |
content::NavigationEntry* visible_entry = |
web_contents()->GetController().GetVisibleEntry(); |
@@ -195,6 +223,12 @@ void ActiveScriptController::RunPendingForExtension( |
// *before* running them to guard against the crazy case where running the |
// callbacks adds more entries. |
permitted_extensions_.insert(extension->id()); |
+ |
+ PendingRequestMap::iterator iter = |
+ pending_requests_.find(extension->id()); |
+ if (iter == pending_requests_.end()) |
+ return; |
+ |
PendingRequestList requests; |
iter->second.swap(requests); |
pending_requests_.erase(extension->id()); |
@@ -221,6 +255,7 @@ void ActiveScriptController::RunPendingForExtension( |
void ActiveScriptController::OnRequestScriptInjectionPermission( |
const std::string& extension_id, |
+ extension_misc::InjectedScriptType script_type, |
int page_id, |
int request_id) { |
if (!Extension::IdIsValid(extension_id)) { |
@@ -240,22 +275,32 @@ void ActiveScriptController::OnRequestScriptInjectionPermission( |
// ran (because this feature is not enabled). Add the extension to the list of |
// permitted extensions (for metrics), and return immediately. |
if (request_id == -1) { |
- DCHECK(!enabled_); |
- permitted_extensions_.insert(extension->id()); |
+ if (ShouldRecordExtension(extension)) { |
+ DCHECK(!enabled_); |
+ permitted_extensions_.insert(extension->id()); |
+ } |
return; |
} |
- if (RequiresUserConsentForScriptInjection(extension)) { |
- // This base::Unretained() is safe, because the callback is only invoked by |
- // this object. |
- RequestScriptInjection( |
- extension, |
- page_id, |
- base::Bind(&ActiveScriptController::PermitScriptInjection, |
- base::Unretained(this), |
- request_id)); |
- } else { |
- PermitScriptInjection(request_id); |
+ switch (RequiresUserConsentForScriptInjection(extension, script_type)) { |
+ case PermissionsData::ALLOW_ACCESS: |
+ PermitScriptInjection(request_id); |
+ break; |
+ case PermissionsData::REQUEST_ACCESS: |
+ // This base::Unretained() is safe, because the callback is only invoked |
+ // by this object. |
+ RequestScriptInjection( |
+ extension, |
+ page_id, |
+ base::Bind(&ActiveScriptController::PermitScriptInjection, |
+ base::Unretained(this), |
+ request_id)); |
+ break; |
+ case PermissionsData::DENY_ACCESS: |
+ // We should usually only get a "deny access" if the page changed (as the |
+ // renderer wouldn't have requested permission if the answer was always |
+ // "no"). Just let the request fizzle and die. |
+ break; |
} |
} |