Chromium Code Reviews| Index: chrome/browser/extensions/extension_preference_api.cc |
| diff --git a/chrome/browser/extensions/extension_preference_api.cc b/chrome/browser/extensions/extension_preference_api.cc |
| index 871d99bcac5fca3cc678cfa9226c7510fe0f745a..b6421c804fd8a0f0e4565690f18fdcc5ab593e22 100644 |
| --- a/chrome/browser/extensions/extension_preference_api.cc |
| +++ b/chrome/browser/extensions/extension_preference_api.cc |
| @@ -29,8 +29,15 @@ |
| namespace { |
| struct PrefMappingEntry { |
| + // Name of the preference referenced by extension_api.json. |
| const char* extension_pref; |
| + |
| + // Name of the preference in the PrefStores. |
| const char* browser_pref; |
| + |
| + // Permission required to access this preference. |
| + // Use ExtensionAPIPermission::kInvalid for |permission| to express that no |
| + // permission is necessary. |
| ExtensionAPIPermission::ID permission; |
| }; |
| @@ -45,6 +52,10 @@ const char kValue[] = "value"; |
| const char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange"; |
| +const char* kReadOnlyPrefs[] = { |
| + prefs::kIncognitoModeAvailability |
| +}; |
| + |
| PrefMappingEntry kPrefMapping[] = { |
| { "alternateErrorPagesEnabled", |
| prefs::kAlternateErrorPagesEnabled, |
| @@ -94,9 +105,21 @@ PrefMappingEntry kPrefMapping[] = { |
| { "translationServiceEnabled", |
| prefs::kEnableTranslate, |
| ExtensionAPIPermission::kExperimental |
| + }, |
| + { "incognitoModeAvailability", |
| + prefs::kIncognitoModeAvailability, |
| + ExtensionAPIPermission::kInvalid // kInvalid = none required. |
| } |
| }; |
| +// Maps prefs::kIncognitoModeAvailability values (0 = enabled, ...) |
| +// to strings exposed to extensions. |
| +const char* kIncognitoModeAvailabilityStrings[] = { |
| + "enabled", |
| + "disabled", |
| + "forced" |
| +}; |
| + |
| class IdentityPrefTransformer : public PrefTransformerInterface { |
| public: |
| virtual Value* ExtensionToBrowserPref(const Value* extension_pref, |
| @@ -131,6 +154,47 @@ class InvertBooleanTransformer : public PrefTransformerInterface { |
| } |
| }; |
| +class IncognitoModeAvailabilityTransformer : public PrefTransformerInterface { |
| + public: |
| + virtual Value* ExtensionToBrowserPref(const Value* extension_pref, |
| + std::string* error, |
| + bool* bad_message) { |
| + // We do not allow extensions to modify the IncognitoModeAvailability |
| + // preference. Therefore, this function is never called. |
| + NOTREACHED(); |
| + return NULL; |
| + } |
| + |
| + virtual Value* BrowserToExtensionPref(const Value* browser_pref) { |
| + int browser_pref_value; |
| + if (!browser_pref->GetAsInteger(&browser_pref_value) || |
| + browser_pref_value < 0 || |
| + browser_pref_value >= |
| + static_cast<int>(arraysize(kIncognitoModeAvailabilityStrings))) { |
| + return NULL; |
| + } |
| + return Value::CreateStringValue( |
| + kIncognitoModeAvailabilityStrings[browser_pref_value]); |
| + } |
| +}; |
| + |
| +// Checks whether an extension has a specific permission but considers |
| +// ExtensionAPIPermission::kInvalid a wildcard that is possessed by every |
| +// extension. |
| +bool HasAPIPermission(const Extension* extension, |
| + ExtensionAPIPermission::ID permission) { |
| + return permission == ExtensionAPIPermission::kInvalid || |
| + extension->HasAPIPermission(permission); |
| +} |
| + |
| +bool IsReadOnlyPreference(const std::string& browser_pref) { |
| + for (size_t i = 0; i < arraysize(kReadOnlyPrefs); ++i) { |
|
Bernhard Bauer
2011/11/23 15:53:57
Nit: Indent only two spaces.
battre
2011/11/23 15:56:05
Done.
|
| + if (kReadOnlyPrefs[i] == browser_pref) |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| // Returns a string constant (defined in the API) indicating the level of |
| // control this extension has over the specified preference. |
| const char* GetLevelOfControl( |
| @@ -145,6 +209,9 @@ const char* GetLevelOfControl( |
| CHECK(pref); |
| ExtensionPrefs* ep = profile->GetExtensionService()->extension_prefs(); |
| + if (IsReadOnlyPreference(browser_pref)) |
| + return kNotControllable; |
| + |
| if (!pref->IsExtensionModifiable()) |
| return kNotControllable; |
| @@ -216,7 +283,9 @@ class PrefMapping { |
| DCHECK_EQ(arraysize(kPrefMapping), event_mapping_.size()); |
| RegisterPrefTransformer(prefs::kProxy, new ProxyPrefTransformer()); |
| RegisterPrefTransformer(prefs::kBlockThirdPartyCookies, |
| - new InvertBooleanTransformer()); |
| + new InvertBooleanTransformer()); |
| + RegisterPrefTransformer(prefs::kIncognitoModeAvailability, |
| + new IncognitoModeAvailabilityTransformer()); |
| } |
| ~PrefMapping() { |
| @@ -315,7 +384,7 @@ void ExtensionPreferenceEventRouter::OnPrefChanged( |
| std::string extension_id = (*it)->id(); |
| // TODO(bauerb): Only iterate over registered event listeners. |
| if (router->ExtensionHasEventListener(extension_id, event_name) && |
| - (*it)->HasAPIPermission(permission) && |
| + HasAPIPermission(it->get(), permission) && |
| (!incognito || extension_service->CanCrossIncognito(*it))) { |
| std::string level_of_control = |
| GetLevelOfControl(profile_, extension_id, browser_pref, incognito); |
| @@ -364,7 +433,7 @@ bool GetPreferenceFunction::RunImpl() { |
| EXTENSION_FUNCTION_VALIDATE( |
| PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| pref_key, &browser_pref, &permission)); |
| - if (!GetExtension()->HasAPIPermission(permission)) { |
| + if (!HasAPIPermission(GetExtension(), permission)) { |
| error_ = ExtensionErrorUtils::FormatErrorMessage( |
| keys::kPermissionErrorMessage, pref_key); |
| return false; |
| @@ -438,11 +507,18 @@ bool SetPreferenceFunction::RunImpl() { |
| EXTENSION_FUNCTION_VALIDATE( |
| PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| pref_key, &browser_pref, &permission)); |
| - if (!GetExtension()->HasAPIPermission(permission)) { |
| + if (!HasAPIPermission(GetExtension(), permission)) { |
| error_ = ExtensionErrorUtils::FormatErrorMessage( |
| keys::kPermissionErrorMessage, pref_key); |
| return false; |
| } |
| + |
| + if (IsReadOnlyPreference(browser_pref)) { |
| + error_ = ExtensionErrorUtils::FormatErrorMessage( |
| + keys::kCannotModifyReadOnlyMessage, pref_key); |
| + return false; |
| + } |
| + |
| ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); |
| const PrefService::Preference* pref = |
| prefs->pref_service()->FindPreference(browser_pref.c_str()); |
| @@ -502,11 +578,18 @@ bool ClearPreferenceFunction::RunImpl() { |
| EXTENSION_FUNCTION_VALIDATE( |
| PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| pref_key, &browser_pref, &permission)); |
| - if (!GetExtension()->HasAPIPermission(permission)) { |
| + if (!HasAPIPermission(GetExtension(), permission)) { |
| error_ = ExtensionErrorUtils::FormatErrorMessage( |
| keys::kPermissionErrorMessage, pref_key); |
| return false; |
| } |
| + |
| + if (IsReadOnlyPreference(browser_pref)) { |
| + error_ = ExtensionErrorUtils::FormatErrorMessage( |
| + keys::kCannotModifyReadOnlyMessage, pref_key); |
| + return false; |
| + } |
| + |
| ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); |
| prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); |
| return true; |