| Index: chrome/browser/extensions/extension_prefs.cc
|
| diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
|
| index 09b7dd6fcd8dfa1a0e68489d33a74572ecd24679..8ebcbe6fcfaa14a22b6289bc3c84011a412f9e3b 100644
|
| --- a/chrome/browser/extensions/extension_prefs.cc
|
| +++ b/chrome/browser/extensions/extension_prefs.cc
|
| @@ -8,6 +8,7 @@
|
| #include "base/string_number_conversions.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/common/extensions/extension.h"
|
| +#include "chrome/common/extensions/url_pattern.h"
|
| #include "chrome/common/notification_service.h"
|
| #include "chrome/common/pref_names.h"
|
|
|
| @@ -82,6 +83,15 @@ const char kUpdateUrlData[] = "update_url_data";
|
| // Whether the browser action is visible in the toolbar.
|
| const char kBrowserActionVisible[] = "browser_action_visible";
|
|
|
| +// Preferences that hold the permissions the user has granted the extension.
|
| +// We explicitly keep track of these so that extensions can contain unknown
|
| +// permissions, for backwards compatibility reasons, and we can still prompt
|
| +// the user to accept them once recognized.
|
| +const char kPrefGrantedPermissionsAPI[] = "granted_permissions.api";
|
| +const char kPrefGrantedPermissionsHost[] = "granted_permissions.host";
|
| +const char kPrefGrantedPermissionsInitialized[] =
|
| + "granted_permissions.initialized";
|
| +
|
| } // namespace
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -113,6 +123,15 @@ static void CleanupBadExtensionKeys(PrefService* prefs) {
|
| prefs->ScheduleSavePersistentPrefs();
|
| }
|
|
|
| +static void ExtentToStringSet(const ExtensionExtent& host_extent,
|
| + std::set<std::string>* result) {
|
| + ExtensionExtent::PatternList patterns = host_extent.patterns();
|
| + ExtensionExtent::PatternList::const_iterator i;
|
| +
|
| + for (i = patterns.begin(); i != patterns.end(); ++i)
|
| + result->insert(i->GetAsString());
|
| +}
|
| +
|
| } // namespace
|
|
|
| ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir)
|
| @@ -218,24 +237,17 @@ DictionaryValue* ExtensionPrefs::CopyCurrentExtensions() {
|
|
|
| bool ExtensionPrefs::ReadBooleanFromPref(
|
| DictionaryValue* ext, const std::string& pref_key) {
|
| - if (!ext->HasKey(pref_key)) return false;
|
| bool bool_value = false;
|
| - if (!ext->GetBoolean(pref_key, &bool_value)) {
|
| - NOTREACHED() << "Failed to fetch " << pref_key << " flag.";
|
| - // In case we could not fetch the flag, we treat it as false.
|
| + if (!ext->GetBoolean(pref_key, &bool_value))
|
| return false;
|
| - }
|
| +
|
| return bool_value;
|
| }
|
|
|
| bool ExtensionPrefs::ReadExtensionPrefBoolean(
|
| const std::string& extension_id, const std::string& pref_key) {
|
| - const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref);
|
| - if (!extensions)
|
| - return false;
|
| -
|
| - DictionaryValue* ext = NULL;
|
| - if (!extensions->GetDictionary(extension_id, &ext)) {
|
| + DictionaryValue* ext = GetExtensionPref(extension_id);
|
| + if (!ext) {
|
| // No such extension yet.
|
| return false;
|
| }
|
| @@ -244,29 +256,74 @@ bool ExtensionPrefs::ReadExtensionPrefBoolean(
|
|
|
| bool ExtensionPrefs::ReadIntegerFromPref(
|
| DictionaryValue* ext, const std::string& pref_key, int* out_value) {
|
| - if (!ext->HasKey(pref_key)) return false;
|
| - if (!ext->GetInteger(pref_key, out_value)) {
|
| - NOTREACHED() << "Failed to fetch " << pref_key << " flag.";
|
| - // In case we could not fetch the flag, we treat it as false.
|
| + if (!ext->GetInteger(pref_key, out_value))
|
| return false;
|
| - }
|
| +
|
| return out_value != NULL;
|
| }
|
|
|
| bool ExtensionPrefs::ReadExtensionPrefInteger(
|
| const std::string& extension_id, const std::string& pref_key,
|
| int* out_value) {
|
| - const DictionaryValue* extensions = prefs_->GetDictionary(kExtensionsPref);
|
| - if (!extensions)
|
| - return false;
|
| - DictionaryValue* ext = NULL;
|
| - if (!extensions->GetDictionary(extension_id, &ext)) {
|
| + DictionaryValue* ext = GetExtensionPref(extension_id);
|
| + if (!ext) {
|
| // No such extension yet.
|
| return false;
|
| }
|
| return ReadIntegerFromPref(ext, pref_key, out_value);
|
| }
|
|
|
| +bool ExtensionPrefs::ReadExtensionPrefList(
|
| + const std::string& extension_id, const std::string& pref_key,
|
| + ListValue** out_value) {
|
| + DictionaryValue* ext = GetExtensionPref(extension_id);
|
| + if (!ext || !ext->GetList(pref_key, out_value))
|
| + return false;
|
| +
|
| + return out_value != NULL;
|
| +}
|
| +
|
| +bool ExtensionPrefs::ReadExtensionPrefStringSet(
|
| + const std::string& extension_id,
|
| + const std::string& pref_key,
|
| + std::set<std::string>* result) {
|
| + ListValue* value = NULL;
|
| + if (!ReadExtensionPrefList(extension_id, pref_key, &value))
|
| + return false;
|
| +
|
| + result->clear();
|
| +
|
| + for (size_t i = 0; i < value->GetSize(); ++i) {
|
| + std::string item;
|
| + if (!value->GetString(i, &item))
|
| + return false;
|
| + result->insert(item);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void ExtensionPrefs::AddToExtensionPrefStringSet(
|
| + const std::string& extension_id,
|
| + const std::string& pref_key,
|
| + const std::set<std::string>& added_value) {
|
| + std::set<std::string> old_value;
|
| + std::set<std::string> new_value;
|
| + ReadExtensionPrefStringSet(extension_id, pref_key, &old_value);
|
| +
|
| + std::set_union(old_value.begin(), old_value.end(),
|
| + added_value.begin(), added_value.end(),
|
| + std::inserter(new_value, new_value.end()));
|
| +
|
| + ListValue* value = new ListValue();
|
| + for (std::set<std::string>::const_iterator iter = new_value.begin();
|
| + iter != new_value.end(); ++iter)
|
| + value->Append(Value::CreateStringValue(*iter));
|
| +
|
| + UpdateExtensionPref(extension_id, pref_key, value);
|
| + prefs_->ScheduleSavePersistentPrefs();
|
| +}
|
| +
|
| void ExtensionPrefs::SavePrefsAndNotify() {
|
| prefs_->ScheduleSavePersistentPrefs();
|
| prefs_->pref_notifier()->OnUserPreferenceSet(kExtensionsPref);
|
| @@ -411,6 +468,58 @@ void ExtensionPrefs::SetLastPingDayImpl(const Time& time,
|
| SavePrefsAndNotify();
|
| }
|
|
|
| +
|
| +bool ExtensionPrefs::GetGrantedPermissions(
|
| + const std::string& extension_id,
|
| + std::set<std::string>* api_permissions,
|
| + ExtensionExtent* host_extent) {
|
| + CHECK(Extension::IdIsValid(extension_id));
|
| +
|
| + if (!ReadExtensionPrefBoolean(extension_id,
|
| + kPrefGrantedPermissionsInitialized))
|
| + return false;
|
| +
|
| + ReadExtensionPrefStringSet(
|
| + extension_id, kPrefGrantedPermissionsAPI, api_permissions);
|
| +
|
| + std::set<std::string> host_permissions;
|
| + ReadExtensionPrefStringSet(
|
| + extension_id, kPrefGrantedPermissionsHost, &host_permissions);
|
| +
|
| + for (std::set<std::string>::iterator i = host_permissions.begin();
|
| + i != host_permissions.end(); ++i)
|
| + host_extent->AddPattern(URLPattern(
|
| + Extension::kValidWebExtentSchemes | UserScript::kValidUserScriptSchemes,
|
| + *i));
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void ExtensionPrefs::AddGrantedPermissions(
|
| + const std::string& extension_id,
|
| + const std::set<std::string>& api_permissions,
|
| + const ExtensionExtent& host_extent) {
|
| + CHECK(Extension::IdIsValid(extension_id));
|
| +
|
| + UpdateExtensionPref(extension_id, kPrefGrantedPermissionsInitialized,
|
| + Value::CreateBooleanValue(true));
|
| +
|
| + if (!api_permissions.empty()) {
|
| + AddToExtensionPrefStringSet(
|
| + extension_id, kPrefGrantedPermissionsAPI, api_permissions);
|
| + }
|
| +
|
| + if (!host_extent.is_empty()) {
|
| + std::set<std::string> host_permissions;
|
| + ExtentToStringSet(host_extent, &host_permissions);
|
| +
|
| + AddToExtensionPrefStringSet(
|
| + extension_id, kPrefGrantedPermissionsHost, host_permissions);
|
| + }
|
| +
|
| + SavePrefsAndNotify();
|
| +}
|
| +
|
| Time ExtensionPrefs::LastPingDay(const std::string& extension_id) const {
|
| DCHECK(Extension::IdIsValid(extension_id));
|
| return LastPingDayImpl(GetExtensionPref(extension_id));
|
|
|