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; |