Chromium Code Reviews| Index: chrome/browser/extensions/extension_prefs.cc |
| diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc |
| index 57c5c9ba1427f06adde28d8a4b042800ca494958..2175aad7a490f598e289bdafbc041aa28da0d93f 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,20 @@ 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()); |
| +} |
| + |
| +static void AddPattern(ExtensionExtent* extent, const std::string& pattern) { |
| + int schemes = URLPattern::SCHEME_ALL; |
| + extent->AddPattern(URLPattern(schemes, pattern)); |
| +} |
| + |
| } // namespace |
| ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir) |
| @@ -218,24 +242,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 +261,79 @@ 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) { |
| + DCHECK(Extension::IdIsValid(extension_id)); |
| + DCHECK(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) { |
| + DCHECK(Extension::IdIsValid(extension_id)); |
| + |
| + 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 +478,57 @@ void ExtensionPrefs::SetLastPingDayImpl(const Time& time, |
| SavePrefsAndNotify(); |
| } |
| + |
| +bool ExtensionPrefs::GetGrantedPermissions( |
| + const std::string& extension_id, |
| + std::set<std::string>* api_permissions, |
| + ExtensionExtent* host_extent) { |
| + DCHECK(Extension::IdIsValid(extension_id)); |
|
Aaron Boodman
2010/11/22 07:57:53
You can leave these if you like, but it's a little
jstritar
2010/11/22 23:01:08
Got rid of all of them except the Extension::IdIsV
|
| + DCHECK(api_permissions); |
| + DCHECK(host_extent); |
| + |
| + 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) |
| + AddPattern(host_extent, *i); |
|
Aaron Boodman
2010/11/22 07:57:53
No need for the helper function here since what it
jstritar
2010/11/22 23:01:08
Done.
|
| + |
| + return true; |
| +} |
| + |
| +void ExtensionPrefs::AddGrantedPermissions( |
| + const std::string& extension_id, |
| + const std::set<std::string>& api_permissions, |
| + const ExtensionExtent& host_extent) { |
| + DCHECK(Extension::IdIsValid(extension_id)); |
|
Aaron Boodman
2010/11/22 07:57:53
DCHECK->CHECK
jstritar
2010/11/22 23:01:08
Done.
|
| + UpdateExtensionPref(extension_id, kPrefGrantedPermissionsInitialized, |
|
Aaron Boodman
2010/11/22 07:57:53
Is it possible to remove this and just use the pre
jstritar
2010/11/22 23:01:08
I think we need this because empty lists and dicti
Aaron Boodman
2010/11/23 00:06:38
I see. It's a shame to bloat the preferences file
|
| + 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)); |