summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/permission_message_combinations_unittest.cc167
-rw-r--r--chrome/common/extensions/chrome_extensions_client.cc27
-rw-r--r--chrome/common/extensions/chrome_extensions_client.h3
-rw-r--r--chrome/common/extensions/manifest_handlers/automation.cc41
-rw-r--r--chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc13
-rw-r--r--extensions/common/api/bluetooth/bluetooth_manifest_permission.cc15
-rw-r--r--extensions/common/api/bluetooth/bluetooth_manifest_permission.h1
-rw-r--r--extensions/common/api/sockets/sockets_manifest_permission.cc75
-rw-r--r--extensions/common/api/sockets/sockets_manifest_permission.h19
-rw-r--r--extensions/common/extensions_client.h11
-rw-r--r--extensions/common/permissions/api_permission.h28
-rw-r--r--extensions/common/permissions/api_permission_set.cc43
-rw-r--r--extensions/common/permissions/api_permission_set.h49
-rw-r--r--extensions/common/permissions/coalesced_permission_message.cc25
-rw-r--r--extensions/common/permissions/coalesced_permission_message.h70
-rw-r--r--extensions/common/permissions/manifest_permission.h12
-rw-r--r--extensions/common/permissions/manifest_permission_set_unittest.cc2
-rw-r--r--extensions/common/permissions/permission_message.h2
-rw-r--r--extensions/common/permissions/permission_message_util.cc69
-rw-r--r--extensions/common/permissions/permission_message_util.h19
-rw-r--r--extensions/extensions.gyp2
-rw-r--r--extensions/shell/common/shell_extensions_client.cc7
-rw-r--r--extensions/shell/common/shell_extensions_client.h3
-rw-r--r--extensions/test/test_extensions_client.cc6
-rw-r--r--extensions/test/test_extensions_client.h3
25 files changed, 674 insertions, 38 deletions
diff --git a/chrome/browser/extensions/permission_message_combinations_unittest.cc b/chrome/browser/extensions/permission_message_combinations_unittest.cc
index 03c2cd6..42e2a20 100644
--- a/chrome/browser/extensions/permission_message_combinations_unittest.cc
+++ b/chrome/browser/extensions/permission_message_combinations_unittest.cc
@@ -589,6 +589,173 @@ TEST_F(PermissionMessageCombinationsUnittest, HostsPermissionMessages) {
ASSERT_TRUE(CheckManifestProducesHostPermissions());
}
+// Check that permission messages are generated correctly for the sockets
+// permission, which has host-like permission messages.
+TEST_F(PermissionMessageCombinationsUnittest, SocketsPermissionMessages) {
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'udp': {'send': '*'},"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with any computer on the local network or internet"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'udp': {'send': ':99'},"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with any computer on the local network or internet"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'tcp': {'connect': '127.0.0.1:80'},"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with the computer named 127.0.0.1"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'tcp': {'connect': 'www.example.com:23'},"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with the computer named www.example.com"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'tcpServer': {'listen': '127.0.0.1:80'}"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with the computer named 127.0.0.1"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'tcpServer': {'listen': ':8080'}"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with any computer on the local network or internet"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'tcpServer': {"
+ " 'listen': ["
+ " '127.0.0.1:80',"
+ " 'www.google.com',"
+ " 'www.example.com:*',"
+ " 'www.foo.com:200',"
+ " 'www.bar.com:200'"
+ " ]"
+ " }"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with the computers named: 127.0.0.1 www.bar.com "
+ "www.example.com www.foo.com www.google.com"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'tcp': {"
+ " 'connect': ["
+ " 'www.abc.com:*',"
+ " 'www.mywebsite.com:320',"
+ " 'www.freestuff.com',"
+ " 'www.foo.com:34',"
+ " 'www.test.com'"
+ " ]"
+ " },"
+ " 'tcpServer': {"
+ " 'listen': ["
+ " '127.0.0.1:80',"
+ " 'www.google.com',"
+ " 'www.example.com:*',"
+ " 'www.foo.com:200',"
+ " ]"
+ " }"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with the computers named: 127.0.0.1 www.abc.com "
+ "www.example.com www.foo.com www.freestuff.com www.google.com "
+ "www.mywebsite.com www.test.com"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+
+ CreateAndInstall(
+ "{"
+ " 'app': {"
+ " 'background': {"
+ " 'scripts': ['background.js']"
+ " }"
+ " },"
+ " 'sockets': {"
+ " 'tcp': {'send': '*:*'},"
+ " 'tcpServer': {'listen': '*:*'},"
+ " }"
+ "}");
+ ASSERT_TRUE(CheckManifestProducesPermissions(
+ "Exchange data with any computer on the local network or internet"));
+ ASSERT_TRUE(CheckManifestProducesHostPermissions());
+}
+
// Test that hosted apps are not given any messages for host permissions.
TEST_F(PermissionMessageCombinationsUnittest,
PackagedAppsHaveNoHostPermissions) {
diff --git a/chrome/common/extensions/chrome_extensions_client.cc b/chrome/common/extensions/chrome_extensions_client.cc
index 4f2fbc2..d6c4bff 100644
--- a/chrome/common/extensions/chrome_extensions_client.cc
+++ b/chrome/common/extensions/chrome_extensions_client.cc
@@ -175,6 +175,9 @@ void ChromeExtensionsClient::FilterHostPermissions(
const URLPatternSet& hosts,
URLPatternSet* new_hosts,
std::set<PermissionMessage>* messages) const {
+ // When editing this function, be sure to add the same functionality to
+ // FilterHostPermissions() below.
+ // TODO(sashab): Deprecate and remove this function.
for (URLPatternSet::const_iterator i = hosts.begin();
i != hosts.end(); ++i) {
// Filters out every URL pattern that matches chrome:// scheme.
@@ -193,6 +196,30 @@ void ChromeExtensionsClient::FilterHostPermissions(
}
}
+void ChromeExtensionsClient::FilterHostPermissions(
+ const URLPatternSet& hosts,
+ URLPatternSet* new_hosts,
+ PermissionIDSet* permissions) const {
+ // When editing this function, be sure to add the same functionality to
+ // FilterHostPermissions() above.
+ for (URLPatternSet::const_iterator i = hosts.begin(); i != hosts.end(); ++i) {
+ // Filters out every URL pattern that matches chrome:// scheme.
+ if (i->scheme() == content::kChromeUIScheme) {
+ // chrome://favicon is the only URL for chrome:// scheme that we
+ // want to support. We want to deprecate the "chrome" scheme.
+ // We should not add any additional "host" here.
+ if (GURL(chrome::kChromeUIFaviconURL).host() != i->host())
+ continue;
+ // TODO(sashab): Add the rule
+ // kFavicon -> IDS_EXTENSION_PROMPT_WARNING_FAVICON
+ // to ChromePermissionMessageProvider.
+ permissions->insert(APIPermission::kFavicon);
+ } else {
+ new_hosts->AddPattern(*i);
+ }
+ }
+}
+
void ChromeExtensionsClient::SetScriptingWhitelist(
const ExtensionsClient::ScriptingWhitelist& whitelist) {
scripting_whitelist_ = whitelist;
diff --git a/chrome/common/extensions/chrome_extensions_client.h b/chrome/common/extensions/chrome_extensions_client.h
index bdcf13a..2796c7e 100644
--- a/chrome/common/extensions/chrome_extensions_client.h
+++ b/chrome/common/extensions/chrome_extensions_client.h
@@ -35,6 +35,9 @@ class ChromeExtensionsClient : public ExtensionsClient {
const URLPatternSet& hosts,
URLPatternSet* new_hosts,
std::set<PermissionMessage>* messages) const override;
+ void FilterHostPermissions(const URLPatternSet& hosts,
+ URLPatternSet* new_hosts,
+ PermissionIDSet* permissions) const override;
void SetScriptingWhitelist(const ScriptingWhitelist& whitelist) override;
const ScriptingWhitelist& GetScriptingWhitelist() const override;
URLPatternSet GetPermittedChromeSchemeHosts(
diff --git a/chrome/common/extensions/manifest_handlers/automation.cc b/chrome/common/extensions/manifest_handlers/automation.cc
index 10287fb..6f4aae5 100644
--- a/chrome/common/extensions/manifest_handlers/automation.cc
+++ b/chrome/common/extensions/manifest_handlers/automation.cc
@@ -48,6 +48,8 @@ class AutomationManifestPermission : public ManifestPermission {
std::string id() const override;
+ PermissionIDSet GetPermissions() const override;
+
bool HasMessages() const override;
PermissionMessages GetMessages() const override;
@@ -78,7 +80,46 @@ bool AutomationManifestPermission::HasMessages() const {
return GetMessages().size() > 0;
}
+PermissionIDSet AutomationManifestPermission::GetPermissions() const {
+ // Meant to mimic the behavior of GetMessages().
+ PermissionIDSet permissions;
+ if (automation_info_->desktop) {
+ // TODO(sashab): Add the rule
+ // kFullAccess -> IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS
+ // to ChromePermissionMessageProvider, when it exists.
+ permissions.insert(APIPermission::kFullAccess);
+ } else if (automation_info_->matches.MatchesAllURLs()) {
+ if (automation_info_->interact) {
+ permissions.insert(APIPermission::kHostsAll);
+ // TODO(sashab): Add the rule
+ // kHostsAll -> IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS
+ // to ChromePermissionMessageProvider, when it exists.
+ } else {
+ permissions.insert(APIPermission::kHostsAllReadOnly);
+ // TODO(sashab): Add the rule
+ // kHostsAllReadOnly -> IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS_READ_ONLY
+ // to ChromePermissionMessageProvider, when it exists.
+ }
+ } else {
+ // Check if we get any additional permissions from FilterHostPermissions.
+ URLPatternSet regular_hosts;
+ ExtensionsClient::Get()->FilterHostPermissions(
+ automation_info_->matches, &regular_hosts, &permissions);
+ std::set<std::string> hosts =
+ permission_message_util::GetDistinctHosts(regular_hosts, true, true);
+ if (!hosts.empty()) {
+ permission_message_util::AddHostPermissions(
+ &permissions, hosts, automation_info_->interact
+ ? permission_message_util::kReadWrite
+ : permission_message_util::kReadOnly);
+ }
+ }
+ return permissions;
+}
+
PermissionMessages AutomationManifestPermission::GetMessages() const {
+ // When modifying this function, be careful to modify the functionality in
+ // GetPermissions() above as well.
PermissionMessages messages;
if (automation_info_->desktop) {
messages.push_back(PermissionMessage(
diff --git a/chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc b/chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc
index adf85f7..84120a2 100644
--- a/chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc
+++ b/chrome/common/extensions/manifest_handlers/ui_overrides_handler.cc
@@ -34,11 +34,24 @@ class UIOverridesHandler::ManifestPermissionImpl : public ManifestPermission {
std::string id() const override { return name(); }
+ PermissionIDSet GetPermissions() const override {
+ PermissionIDSet permissions;
+ if (override_bookmarks_ui_permission_) {
+ // TODO(sashab): Add rule to ChromePermissionMessageProvider:
+ // kOverrideBookmarksUI ->
+ // IDS_EXTENSION_PROMPT_WARNING_OVERRIDE_BOOKMARKS_UI
+ permissions.insert(APIPermission::kOverrideBookmarksUI);
+ }
+ return permissions;
+ }
+
bool HasMessages() const override {
return override_bookmarks_ui_permission_;
}
PermissionMessages GetMessages() const override {
+ // When making changes to this function, be careful to modify
+ // GetPermissions() above to have the same behaviour.
PermissionMessages result;
if (override_bookmarks_ui_permission_) {
result.push_back(PermissionMessage(
diff --git a/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc b/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc
index d56d2c1..9a10ccb 100644
--- a/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc
+++ b/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc
@@ -117,9 +117,24 @@ std::string BluetoothManifestPermission::name() const {
std::string BluetoothManifestPermission::id() const { return name(); }
+PermissionIDSet BluetoothManifestPermission::GetPermissions() const {
+ PermissionIDSet permissions;
+ // TODO(sashab): Add a rule to ChromePermissionMessageProvider:
+ // kBluetooth -> IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH
+ permissions.insert(APIPermission::kBluetooth);
+ if (!uuids_.empty()) {
+ // TODO(sashab): Add a rule to ChromePermissionMessageProvider:
+ // kBluetoothDevices -> IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_DEVICES
+ permissions.insert(APIPermission::kBluetoothDevices);
+ }
+ return permissions;
+}
+
bool BluetoothManifestPermission::HasMessages() const { return true; }
PermissionMessages BluetoothManifestPermission::GetMessages() const {
+ // When modifying this function, be careful to also modify GetPermissions()
+ // above to have the same functionality.
DCHECK(HasMessages());
PermissionMessages result;
diff --git a/extensions/common/api/bluetooth/bluetooth_manifest_permission.h b/extensions/common/api/bluetooth/bluetooth_manifest_permission.h
index eb71fa4b..c77eee5 100644
--- a/extensions/common/api/bluetooth/bluetooth_manifest_permission.h
+++ b/extensions/common/api/bluetooth/bluetooth_manifest_permission.h
@@ -43,6 +43,7 @@ class BluetoothManifestPermission : public ManifestPermission {
// extensions::ManifestPermission overrides.
std::string name() const override;
std::string id() const override;
+ PermissionIDSet GetPermissions() const override;
bool HasMessages() const override;
PermissionMessages GetMessages() const override;
bool FromValue(const base::Value* value) override;
diff --git a/extensions/common/api/sockets/sockets_manifest_permission.cc b/extensions/common/api/sockets/sockets_manifest_permission.cc
index f695494..d248d28 100644
--- a/extensions/common/api/sockets/sockets_manifest_permission.cc
+++ b/extensions/common/api/sockets/sockets_manifest_permission.cc
@@ -6,6 +6,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
+#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "extensions/common/api/extensions_manifest_types.h"
@@ -158,21 +159,23 @@ std::string SocketsManifestPermission::name() const {
std::string SocketsManifestPermission::id() const { return name(); }
+PermissionIDSet SocketsManifestPermission::GetPermissions() const {
+ PermissionMessages messages;
+ PermissionIDSet ids;
+ AddAllHostMessages(messages, ids);
+ return ids;
+}
+
bool SocketsManifestPermission::HasMessages() const {
bool is_empty = permissions_.empty();
return !is_empty;
}
PermissionMessages SocketsManifestPermission::GetMessages() const {
- // TODO(rpaquay): This function and callees is (almost) a copy/paste
- // from extensions::SocketPermissiona.
- PermissionMessages result;
- if (!AddAnyHostMessage(result)) {
- AddSpecificHostMessage(result);
- AddSubdomainHostMessage(result);
- }
- AddNetworkListMessage(result);
- return result;
+ PermissionMessages messages;
+ PermissionIDSet ids;
+ AddAllHostMessages(messages, ids);
+ return messages;
}
bool SocketsManifestPermission::FromValue(const base::Value* value) {
@@ -260,13 +263,27 @@ void SocketsManifestPermission::AddPermission(
permissions_.insert(entry);
}
-bool SocketsManifestPermission::AddAnyHostMessage(
- PermissionMessages& messages) const {
+void SocketsManifestPermission::AddAllHostMessages(PermissionMessages& messages,
+ PermissionIDSet& ids) const {
+ // TODO(rpaquay): This function and callees is (almost) a copy/paste from
+ // extensions::SocketPermission.
+ if (!AddAnyHostMessage(messages, ids)) {
+ AddSpecificHostMessage(messages, ids);
+ AddSubdomainHostMessage(messages, ids);
+ }
+ AddNetworkListMessage(messages, ids);
+}
+
+bool SocketsManifestPermission::AddAnyHostMessage(PermissionMessages& messages,
+ PermissionIDSet& ids) const {
for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
it != permissions_.end();
++it) {
if (it->IsAddressBoundType() &&
it->GetHostType() == SocketPermissionEntry::ANY_HOST) {
+ // TODO(sashab): Add a rule to ChromePermissionMessageProvider:
+ // kSocketAnyHost -> IDS_EXTENSION_PROMPT_WARNING_SOCKET_ANY_HOST
+ ids.insert(APIPermission::kSocketAnyHost);
messages.push_back(
PermissionMessage(PermissionMessage::kSocketAnyHost,
l10n_util::GetStringUTF16(
@@ -278,7 +295,8 @@ bool SocketsManifestPermission::AddAnyHostMessage(
}
void SocketsManifestPermission::AddSubdomainHostMessage(
- PermissionMessages& messages) const {
+ PermissionMessages& messages,
+ PermissionIDSet& ids) const {
std::set<base::string16> domains;
for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
it != permissions_.end();
@@ -287,6 +305,8 @@ void SocketsManifestPermission::AddSubdomainHostMessage(
domains.insert(base::UTF8ToUTF16(it->pattern().host));
}
if (!domains.empty()) {
+ // TODO(sashab): This is not correct for all languages - add proper
+ // internationalization of this string for all plural states.
int id = (domains.size() == 1)
? IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAIN
: IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAINS;
@@ -297,11 +317,22 @@ void SocketsManifestPermission::AddSubdomainHostMessage(
JoinString(
std::vector<base::string16>(domains.begin(), domains.end()),
' '))));
+ // TODO(sashab): Add rules to ChromePermissionMessageProvider:
+ // kSocketDomainHostsSingular ->
+ // IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAIN
+ // kSocketDomainHostsPlural ->
+ // IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAINS
+ APIPermission::ID pid = (domains.size() == 1)
+ ? APIPermission::kSocketDomainHostsSingular
+ : APIPermission::kSocketDomainHostsPlural;
+ for (const auto& domain : domains)
+ ids.insert(pid, domain);
}
}
void SocketsManifestPermission::AddSpecificHostMessage(
- PermissionMessages& messages) const {
+ PermissionMessages& messages,
+ PermissionIDSet& ids) const {
std::set<base::string16> hostnames;
for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
it != permissions_.end();
@@ -310,6 +341,8 @@ void SocketsManifestPermission::AddSpecificHostMessage(
hostnames.insert(base::UTF8ToUTF16(it->pattern().host));
}
if (!hostnames.empty()) {
+ // TODO(sashab): This is not correct for all languages - add proper
+ // internationalization of this string for all plural states.
int id = (hostnames.size() == 1)
? IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOST
: IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOSTS;
@@ -320,15 +353,29 @@ void SocketsManifestPermission::AddSpecificHostMessage(
JoinString(
std::vector<base::string16>(hostnames.begin(), hostnames.end()),
' '))));
+ // TODO(sashab): Add rules to ChromePermissionMessageProvider:
+ // kSocketSpecificHostsSingular ->
+ // IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOST
+ // kSocketSpecificHostsPlural ->
+ // IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOSTS
+ APIPermission::ID pid = (hostnames.size() == 1)
+ ? APIPermission::kSocketSpecificHostsSingular
+ : APIPermission::kSocketSpecificHostsPlural;
+ for (const auto& hostname : hostnames)
+ ids.insert(pid, hostname);
}
}
void SocketsManifestPermission::AddNetworkListMessage(
- PermissionMessages& messages) const {
+ PermissionMessages& messages,
+ PermissionIDSet& ids) const {
for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
it != permissions_.end();
++it) {
if (it->pattern().type == SocketPermissionRequest::NETWORK_STATE) {
+ // TODO(sashab): Add a rule to ChromePermissionMessageProvider:
+ // kNetworkState -> IDS_EXTENSION_PROMPT_WARNING_NETWORK_STATE
+ ids.insert(APIPermission::kNetworkState);
messages.push_back(
PermissionMessage(PermissionMessage::kNetworkState,
l10n_util::GetStringUTF16(
diff --git a/extensions/common/api/sockets/sockets_manifest_permission.h b/extensions/common/api/sockets/sockets_manifest_permission.h
index d636f22..bf844da 100644
--- a/extensions/common/api/sockets/sockets_manifest_permission.h
+++ b/extensions/common/api/sockets/sockets_manifest_permission.h
@@ -42,6 +42,7 @@ class SocketsManifestPermission : public ManifestPermission {
// extensions::ManifestPermission overrides.
std::string name() const override;
std::string id() const override;
+ PermissionIDSet GetPermissions() const override;
bool HasMessages() const override;
PermissionMessages GetMessages() const override;
bool FromValue(const base::Value* value) override;
@@ -53,10 +54,20 @@ class SocketsManifestPermission : public ManifestPermission {
const SocketPermissionEntrySet& entries() const { return permissions_; }
private:
- bool AddAnyHostMessage(PermissionMessages& messages) const;
- void AddSubdomainHostMessage(PermissionMessages& messages) const;
- void AddSpecificHostMessage(PermissionMessages& messages) const;
- void AddNetworkListMessage(PermissionMessages& messages) const;
+ // Add all host messages for this manifest permission into the given lists.
+ // TODO(sashab): Remove the |messages| argument from these methods, and remove
+ // the AddAllHostMessages() function (move all the logic into GetPermissions()
+ // above).
+ void AddAllHostMessages(PermissionMessages& messages,
+ PermissionIDSet& ids) const;
+ bool AddAnyHostMessage(PermissionMessages& messages,
+ PermissionIDSet& ids) const;
+ void AddSubdomainHostMessage(PermissionMessages& messages,
+ PermissionIDSet& ids) const;
+ void AddSpecificHostMessage(PermissionMessages& messages,
+ PermissionIDSet& ids) const;
+ void AddNetworkListMessage(PermissionMessages& messages,
+ PermissionIDSet& ids) const;
SocketPermissionEntrySet permissions_;
};
diff --git a/extensions/common/extensions_client.h b/extensions/common/extensions_client.h
index f2292b1..bfe67ca 100644
--- a/extensions/common/extensions_client.h
+++ b/extensions/common/extensions_client.h
@@ -11,6 +11,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
+#include "extensions/common/permissions/api_permission_set.h"
class GURL;
@@ -66,11 +67,21 @@ class ExtensionsClient {
// Takes the list of all hosts and filters out those with special
// permission strings. Adds the regular hosts to |new_hosts|,
// and adds the special permission messages to |messages|.
+ // TODO(sashab): Deprecate this in favour of FilterHostPermissions() below.
virtual void FilterHostPermissions(
const URLPatternSet& hosts,
URLPatternSet* new_hosts,
std::set<PermissionMessage>* messages) const = 0;
+ // Takes the list of all hosts and filters out those with special
+ // permission strings. Adds the regular hosts to |new_hosts|,
+ // and adds any additional permissions to |permissions|.
+ // TODO(sashab): Split this function in two: One to filter out ignored host
+ // permissions, and one to get permissions for the given hosts.
+ virtual void FilterHostPermissions(const URLPatternSet& hosts,
+ URLPatternSet* new_hosts,
+ PermissionIDSet* permissions) const = 0;
+
// Replaces the scripting whitelist with |whitelist|. Used in the renderer;
// only used for testing in the browser process.
virtual void SetScriptingWhitelist(const ScriptingWhitelist& whitelist) = 0;
diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h
index 8d663f0..924412b 100644
--- a/extensions/common/permissions/api_permission.h
+++ b/extensions/common/permissions/api_permission.h
@@ -29,6 +29,13 @@ class ChromeAPIPermissions;
// There is one instance per permission per loaded extension.
class APIPermission {
public:
+ // The IDs of all permissions available to apps. Add as many permissions here
+ // as needed to generate meaningful permission messages. Add the rules for the
+ // messages to ChromePermissionMessageProvider.
+ // Remove permissions from this list if they have no longer have a
+ // corresponding API permission and no permission message.
+ // TODO(sashab): Move this to a more central location, and rename it to
+ // PermissionID.
enum ID {
// Error codes.
kInvalid = -2,
@@ -195,6 +202,27 @@ class APIPermission {
kSystemNetwork,
kSystemInfoCpu,
kSystemInfoMemory,
+
+ // Permission message IDs that are not currently valid permissions on their
+ // own, but are needed by various manifest permissions to represent their
+ // permission message rule combinations.
+ // TODO(sashab): Move these in-line with the other permission IDs.
+ kBluetooth,
+ kBluetoothDevices,
+ kFavicon,
+ kFullAccess,
+ kHostReadOnly,
+ kHostReadWrite,
+ kHostsAll,
+ kHostsAllReadOnly,
+ kOverrideBookmarksUI,
+ kSocketAnyHost,
+ kSocketDomainHostsSingular,
+ kSocketDomainHostsPlural,
+ kSocketSpecificHostsSingular,
+ kSocketSpecificHostsPlural,
+ kNetworkState,
+
kEnumBoundary
};
diff --git a/extensions/common/permissions/api_permission_set.cc b/extensions/common/permissions/api_permission_set.cc
index d21ab43..38fb80e 100644
--- a/extensions/common/permissions/api_permission_set.cc
+++ b/extensions/common/permissions/api_permission_set.cc
@@ -183,4 +183,47 @@ void APIPermissionSet::AddImpliedPermissions() {
}
}
+PermissionIDSet::PermissionIDSet() : permissions() {
+}
+
+PermissionIDSet::~PermissionIDSet() {
+}
+
+PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one) {
+ insert(permission_one);
+}
+
+PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one,
+ APIPermission::ID permission_two) {
+ insert(permission_one);
+ insert(permission_two);
+}
+
+PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one,
+ APIPermission::ID permission_two,
+ APIPermission::ID permission_three) {
+ insert(permission_one);
+ insert(permission_two);
+ insert(permission_three);
+}
+
+PermissionIDSet::PermissionIDSet(APIPermission::ID permission_one,
+ APIPermission::ID permission_two,
+ APIPermission::ID permission_three,
+ APIPermission::ID permission_four) {
+ insert(permission_one);
+ insert(permission_two);
+ insert(permission_three);
+ insert(permission_four);
+}
+
+void PermissionIDSet::insert(APIPermission::ID permission) {
+ permissions.insert(PermissionID(permission, base::string16()));
+}
+
+void PermissionIDSet::insert(APIPermission::ID permission,
+ base::string16 permission_detail) {
+ permissions.insert(PermissionID(permission, permission_detail));
+}
+
} // namespace extensions
diff --git a/extensions/common/permissions/api_permission_set.h b/extensions/common/permissions/api_permission_set.h
index 4db19f6..64eb7be 100644
--- a/extensions/common/permissions/api_permission_set.h
+++ b/extensions/common/permissions/api_permission_set.h
@@ -60,6 +60,55 @@ class APIPermissionSet : public BaseSetOperators<APIPermissionSet> {
void AddImpliedPermissions();
};
+// A set of permissions for an app or extension. Used for passing around groups
+// of permissions, such as required or optional permissions. Has convenience
+// constructors so that it can be constructed inline.
+//
+// Each permission can also store a string, such as a hostname or device number,
+// as a parameter that helps identify the permission. This parameter can then
+// be used when the permission message is generated. For example, the permission
+// kHostReadOnly might have the parameter "google.com", which means that the app
+// or extension has the permission to read the host google.com. This parameter
+// may then be included in the permission message when it is generated later.
+//
+// Example:
+// // Create a PermissionIDSet.
+// PermissionIDSet p(APIPermission::kBluetooth, APIPermission::kFavicon);
+// // Add a permission to the set.
+// p.insertPermission(APIPermission::kNetworkState);
+// // Add a permission with a detail to the set.
+// p.insertPermission(APIPermission::kHostReadOnly,
+// base::ASCIIToUTF16("http://www.google.com"));
+//
+// TODO(sashab): Move this to its own file and rename it to PermissionSet after
+// APIPermission is removed, the current PermissionSet is no longer used, and
+// APIPermission::ID is the only type of Permission ID.
+typedef std::pair<APIPermission::ID, base::string16> PermissionID;
+class PermissionIDSet {
+ public:
+ PermissionIDSet();
+ virtual ~PermissionIDSet();
+
+ // Convenience constructors for inline initialization.
+ PermissionIDSet(APIPermission::ID permission_one);
+ PermissionIDSet(APIPermission::ID permission_one,
+ APIPermission::ID permission_two);
+ PermissionIDSet(APIPermission::ID permission_one,
+ APIPermission::ID permission_two,
+ APIPermission::ID permission_three);
+ PermissionIDSet(APIPermission::ID permission_one,
+ APIPermission::ID permission_two,
+ APIPermission::ID permission_three,
+ APIPermission::ID permission_four);
+
+ // Adds the given permission, and an optional permission detail, to the set.
+ void insert(APIPermission::ID permission);
+ void insert(APIPermission::ID permission, base::string16 permission_detail);
+
+ private:
+ std::set<PermissionID> permissions;
+};
+
} // namespace extensions
#endif // EXTENSIONS_COMMON_PERMISSIONS_API_PERMISSION_SET_H_
diff --git a/extensions/common/permissions/coalesced_permission_message.cc b/extensions/common/permissions/coalesced_permission_message.cc
new file mode 100644
index 0000000..8239ebe
--- /dev/null
+++ b/extensions/common/permissions/coalesced_permission_message.cc
@@ -0,0 +1,25 @@
+// Copyright 2013 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/common/permissions/coalesced_permission_message.h"
+
+namespace extensions {
+
+CoalescedPermissionMessage::CoalescedPermissionMessage(
+ const base::string16& message,
+ const PermissionIDSet& permissions)
+ : message_(message), permissions_(permissions) {
+}
+
+CoalescedPermissionMessage::CoalescedPermissionMessage(
+ const base::string16& message,
+ const PermissionIDSet& permissions,
+ const std::vector<base::string16>& submessages)
+ : message_(message), permissions_(permissions), submessages_(submessages) {
+}
+
+CoalescedPermissionMessage::~CoalescedPermissionMessage() {
+}
+
+} // namespace extensions
diff --git a/extensions/common/permissions/coalesced_permission_message.h b/extensions/common/permissions/coalesced_permission_message.h
new file mode 100644
index 0000000..7ff24c0
--- /dev/null
+++ b/extensions/common/permissions/coalesced_permission_message.h
@@ -0,0 +1,70 @@
+// Copyright 2013 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_COMMON_PERMISSIONS_COALESCED_PERMISSION_MESSAGE_H_
+#define EXTENSIONS_COMMON_PERMISSIONS_COALESCED_PERMISSION_MESSAGE_H_
+
+#include <set>
+#include <string>
+
+#include "base/memory/scoped_vector.h"
+#include "extensions/common/permissions/api_permission.h"
+#include "extensions/common/permissions/api_permission_set.h"
+
+namespace extensions {
+
+// The new kind of Chrome app/extension permission messages.
+//
+// A CoalescedPermissionMessage is an immutable object that represents a single
+// bullet in the list of an app or extension's permissions. It contains the
+// localized permission message to display, as well as the set of permissions
+// that contributed to that message (and should be revoked if this permission is
+// revoked). It can also optionally contain a list of sub-messages which should
+// appear as nested bullet points below the main one.
+//
+// |permissions| contains the permissions that are 'represented' by this
+// message and should be revoked if this permission message is revoked. Note
+// that other permissions could have contributed to the message, but these are
+// the ones 'contained' in this message - if this set is taken for all
+// CoalescedPermissionMessages, each permission will only be in at most one
+// CoalescedPermissionMessage.
+//
+// Some permissions may contain nested messages, stored in |submessages|. These
+// are appropriate to show as nested bullet points below the permission,
+// collapsed if needed. For example, host permission messages may list all the
+// sites the app has access to in |submessages|, with a summary message in
+// |message|.
+//
+// TODO(sashab): Add a custom revoke action for each permission and nested
+// permission message, registerable as a callback.
+// TODO(sashab): Once the existing PermissionMessage is no longer used, rename
+// this to PermissionMessage.
+class CoalescedPermissionMessage {
+ public:
+ CoalescedPermissionMessage(const base::string16& message,
+ const PermissionIDSet& permissions);
+ CoalescedPermissionMessage(const base::string16& message,
+ const PermissionIDSet& permissions,
+ const std::vector<base::string16>& submessages);
+ virtual ~CoalescedPermissionMessage();
+
+ const base::string16& message() const { return message_; }
+ const PermissionIDSet& permissions() const { return permissions_; }
+ const std::vector<base::string16>& submessages() const {
+ return submessages_;
+ }
+
+ private:
+ const base::string16 message_;
+ const PermissionIDSet permissions_;
+ const std::vector<base::string16> submessages_;
+
+ DISALLOW_COPY_AND_ASSIGN(CoalescedPermissionMessage);
+};
+
+typedef std::vector<CoalescedPermissionMessage> CoalescedPermissionMessages;
+
+} // namespace extensions
+
+#endif // EXTENSIONS_COMMON_PERMISSIONS_COALESCED_PERMISSION_MESSAGE_H_
diff --git a/extensions/common/permissions/manifest_permission.h b/extensions/common/permissions/manifest_permission.h
index fdfb3f4..5c405b4 100644
--- a/extensions/common/permissions/manifest_permission.h
+++ b/extensions/common/permissions/manifest_permission.h
@@ -9,6 +9,8 @@
#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
+#include "extensions/common/permissions/api_permission_set.h"
+#include "extensions/common/permissions/coalesced_permission_message.h"
#include "extensions/common/permissions/permission_message.h"
class PickleIterator;
@@ -37,10 +39,20 @@ class ManifestPermission {
// Same as name(), needed for compatibility with APIPermission.
virtual std::string id() const = 0;
+ // The set of permissions this manifest entry has. These permissions are used
+ // by PermissionMessageProvider to generate meaningful permission messages
+ // for the app.
+ // TODO(sashab): Use this in PermissionMessageProvider.
+ virtual PermissionIDSet GetPermissions() const = 0;
+
// Returns true if this permission has any PermissionMessages.
+ // TODO(sashab): Deprecate this, using GetPermissions() above and adding
+ // message rules to ChromePermissionMessageProvider.
virtual bool HasMessages() const = 0;
// Returns the localized permission messages of this permission.
+ // TODO(sashab): Deprecate this, using GetPermissions() above and adding
+ // message rules to ChromePermissionMessageProvider.
virtual PermissionMessages GetMessages() const = 0;
// Parses the ManifestPermission from |value|. Returns false if error happens.
diff --git a/extensions/common/permissions/manifest_permission_set_unittest.cc b/extensions/common/permissions/manifest_permission_set_unittest.cc
index 7716c9a..595663b 100644
--- a/extensions/common/permissions/manifest_permission_set_unittest.cc
+++ b/extensions/common/permissions/manifest_permission_set_unittest.cc
@@ -21,6 +21,8 @@ class MockManifestPermission : public ManifestPermission {
std::string id() const override { return name(); }
+ PermissionIDSet GetPermissions() const override { return PermissionIDSet(); }
+
bool HasMessages() const override { return false; }
PermissionMessages GetMessages() const override {
diff --git a/extensions/common/permissions/permission_message.h b/extensions/common/permissions/permission_message.h
index 2515de0..fa65ab2 100644
--- a/extensions/common/permissions/permission_message.h
+++ b/extensions/common/permissions/permission_message.h
@@ -21,6 +21,8 @@ class PermissionMessage {
public:
// Do not reorder this enumeration. If you need to add a new enum, add it just
// prior to kEnumBoundary.
+ // TODO(sashab): Deprecate these IDs - use whatever APIPermission::ID becomes
+ // instead.
enum ID {
kUnknown,
kNone,
diff --git a/extensions/common/permissions/permission_message_util.cc b/extensions/common/permissions/permission_message_util.cc
index e4c1d09..ed487f8 100644
--- a/extensions/common/permissions/permission_message_util.cc
+++ b/extensions/common/permissions/permission_message_util.cc
@@ -8,6 +8,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
+#include "extensions/common/permissions/coalesced_permission_message.h"
#include "extensions/common/permissions/permission_message.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/url_pattern_set.h"
@@ -15,10 +16,8 @@
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/url_constants.h"
-#include "base/strings/string_split.h"
using extensions::PermissionMessage;
-using extensions::PermissionSet;
using extensions::URLPatternSet;
namespace {
@@ -40,6 +39,32 @@ bool RcdBetterThan(const std::string& a, const std::string& b) {
namespace permission_message_util {
+// The number of host messages supported. The first N - 1 of these messages are
+// specific for the number of hosts; the last one is a catch-all for N or more
+// hosts.
+static const int kNumMessages = 4;
+
+std::vector<base::string16> GetHostListFromHosts(
+ const std::set<std::string>& hosts,
+ PermissionMessageProperties properties) {
+ int host_msg_id = hosts.size() < kNumMessages
+ ? IDS_EXTENSION_PROMPT_WARNING_HOST_AND_SUBDOMAIN
+ : IDS_EXTENSION_PROMPT_WARNING_HOST_AND_SUBDOMAIN_LIST;
+ std::vector<base::string16> host_list;
+ for (std::set<std::string>::const_iterator it = hosts.begin();
+ it != hosts.end();
+ ++it) {
+ std::string host = *it;
+ host_list.push_back(
+ host[0] == '*' && host[1] == '.'
+ ? l10n_util::GetStringFUTF16(host_msg_id,
+ base::UTF8ToUTF16(host.erase(0, 2)))
+ : base::UTF8ToUTF16(host));
+ }
+ DCHECK(host_list.size());
+ return host_list;
+}
+
PermissionMessage CreateFromHostList(const std::set<std::string>& hosts,
PermissionMessageProperties properties) {
typedef std::pair<PermissionMessage::ID, int> MsgPair;
@@ -64,25 +89,13 @@ PermissionMessage CreateFromHostList(const std::set<std::string>& hosts,
COMPILE_ASSERT(
arraysize(kReadWriteMessagesList) == arraysize(kReadOnlyMessagesList),
message_lists_different_size);
- static const int kNumMessages = arraysize(kReadWriteMessagesList);
+ COMPILE_ASSERT(kNumMessages == arraysize(kReadWriteMessagesList),
+ messages_array_different_size);
+
const MsgPair(&messages_list)[kNumMessages] =
properties == kReadOnly ? kReadOnlyMessagesList : kReadWriteMessagesList;
-
- int host_msg_id = hosts.size() < kNumMessages
- ? IDS_EXTENSION_PROMPT_WARNING_HOST_AND_SUBDOMAIN
- : IDS_EXTENSION_PROMPT_WARNING_HOST_AND_SUBDOMAIN_LIST;
- std::vector<base::string16> host_list;
- for (std::set<std::string>::const_iterator it = hosts.begin();
- it != hosts.end();
- ++it) {
- std::string host = *it;
- host_list.push_back(
- host[0] == '*' && host[1] == '.'
- ? l10n_util::GetStringFUTF16(host_msg_id,
- base::UTF8ToUTF16(host.erase(0, 2)))
- : base::UTF8ToUTF16(host));
- }
- DCHECK(host_list.size());
+ std::vector<base::string16> host_list =
+ GetHostListFromHosts(hosts, properties);
if (host_list.size() < kNumMessages) {
return PermissionMessage(
@@ -104,6 +117,24 @@ PermissionMessage CreateFromHostList(const std::set<std::string>& hosts,
details);
}
+void AddHostPermissions(extensions::PermissionIDSet* permissions,
+ const std::set<std::string>& hosts,
+ PermissionMessageProperties properties) {
+ std::vector<base::string16> host_list =
+ GetHostListFromHosts(hosts, properties);
+
+ // Create a separate permission for each host, and add it to the permissions
+ // list.
+ // TODO(sashab): Add coalescing rules for kHostReadOnly and kHostReadWrite
+ // to mimic the current behavior of CreateFromHostList() above.
+ for (const auto& host : host_list) {
+ permissions->insert(properties == kReadOnly
+ ? extensions::APIPermission::kHostReadOnly
+ : extensions::APIPermission::kHostReadWrite,
+ host);
+ }
+}
+
std::set<std::string> GetDistinctHosts(const URLPatternSet& host_patterns,
bool include_rcd,
bool exclude_file_scheme) {
diff --git a/extensions/common/permissions/permission_message_util.h b/extensions/common/permissions/permission_message_util.h
index 1046bfb..995d226 100644
--- a/extensions/common/permissions/permission_message_util.h
+++ b/extensions/common/permissions/permission_message_util.h
@@ -7,10 +7,13 @@
#include <set>
#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
namespace extensions {
+class PermissionIDSet;
class PermissionMessage;
-class PermissionSet;
class URLPatternSet;
}
@@ -18,13 +21,27 @@ namespace permission_message_util {
enum PermissionMessageProperties { kReadOnly, kReadWrite };
+// Get a list of hosts to display in a permission message from the given list of
+// hosts from the manifest.
+// TODO(sashab): Merge this into AddHostPermissions() once CreateFromHostList()
+// is deprecated.
+std::vector<base::string16> GetHostListFromHosts(
+ const std::set<std::string>& hosts,
+ PermissionMessageProperties properties);
+
// Creates the corresponding permission message for a list of hosts.
// The messages change depending on how many hosts are present, and whether
// |read_only| is true.
+// TODO(sashab): Deprecate this, prefer AddHostPermissions() instead.
extensions::PermissionMessage CreateFromHostList(
const std::set<std::string>& hosts,
PermissionMessageProperties);
+// Adds the appropriate permissions from given hosts to |permissions|.
+void AddHostPermissions(extensions::PermissionIDSet* permissions,
+ const std::set<std::string>& hosts,
+ PermissionMessageProperties properties);
+
std::set<std::string> GetDistinctHosts(
const extensions::URLPatternSet& host_patterns,
bool include_rcd,
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 21b17e0..e7c350c 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -207,6 +207,8 @@
'common/permissions/api_permission_set.cc',
'common/permissions/api_permission_set.h',
'common/permissions/base_set_operators.h',
+ 'common/permissions/coalesced_permission_message.cc',
+ 'common/permissions/coalesced_permission_message.h',
'common/permissions/extensions_api_permissions.cc',
'common/permissions/extensions_api_permissions.h',
'common/permissions/manifest_permission.cc',
diff --git a/extensions/shell/common/shell_extensions_client.cc b/extensions/shell/common/shell_extensions_client.cc
index a598ded..3f7bc48 100644
--- a/extensions/shell/common/shell_extensions_client.cc
+++ b/extensions/shell/common/shell_extensions_client.cc
@@ -147,6 +147,13 @@ void ShellExtensionsClient::FilterHostPermissions(
NOTIMPLEMENTED();
}
+void ShellExtensionsClient::FilterHostPermissions(
+ const URLPatternSet& hosts,
+ URLPatternSet* new_hosts,
+ PermissionIDSet* permissions) const {
+ NOTIMPLEMENTED();
+}
+
void ShellExtensionsClient::SetScriptingWhitelist(
const ScriptingWhitelist& whitelist) {
scripting_whitelist_ = whitelist;
diff --git a/extensions/shell/common/shell_extensions_client.h b/extensions/shell/common/shell_extensions_client.h
index cbb72e1..3e5e9bb 100644
--- a/extensions/shell/common/shell_extensions_client.h
+++ b/extensions/shell/common/shell_extensions_client.h
@@ -31,6 +31,9 @@ class ShellExtensionsClient : public ExtensionsClient {
const URLPatternSet& hosts,
URLPatternSet* new_hosts,
std::set<PermissionMessage>* messages) const override;
+ void FilterHostPermissions(const URLPatternSet& hosts,
+ URLPatternSet* new_hosts,
+ PermissionIDSet* permissions) const override;
void SetScriptingWhitelist(const ScriptingWhitelist& whitelist) override;
const ScriptingWhitelist& GetScriptingWhitelist() const override;
URLPatternSet GetPermittedChromeSchemeHosts(
diff --git a/extensions/test/test_extensions_client.cc b/extensions/test/test_extensions_client.cc
index 1f44750..a2989e8 100644
--- a/extensions/test/test_extensions_client.cc
+++ b/extensions/test/test_extensions_client.cc
@@ -104,6 +104,12 @@ void TestExtensionsClient::FilterHostPermissions(
std::set<PermissionMessage>* messages) const {
}
+void TestExtensionsClient::FilterHostPermissions(
+ const URLPatternSet& hosts,
+ URLPatternSet* new_hosts,
+ PermissionIDSet* permissions) const {
+}
+
void TestExtensionsClient::SetScriptingWhitelist(
const ExtensionsClient::ScriptingWhitelist& whitelist) {
scripting_whitelist_ = whitelist;
diff --git a/extensions/test/test_extensions_client.h b/extensions/test/test_extensions_client.h
index 2c49577..05ebb7f 100644
--- a/extensions/test/test_extensions_client.h
+++ b/extensions/test/test_extensions_client.h
@@ -28,6 +28,9 @@ class TestExtensionsClient : public ExtensionsClient {
const URLPatternSet& hosts,
URLPatternSet* new_hosts,
std::set<PermissionMessage>* messages) const override;
+ void FilterHostPermissions(const URLPatternSet& hosts,
+ URLPatternSet* new_hosts,
+ PermissionIDSet* permissions) const override;
void SetScriptingWhitelist(const ScriptingWhitelist& whitelist) override;
const ScriptingWhitelist& GetScriptingWhitelist() const override;
URLPatternSet GetPermittedChromeSchemeHosts(