| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_preference_api.h" | 5 #include "chrome/browser/extensions/extension_preference_api.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/memory/singleton.h" | 10 #include "base/memory/singleton.h" |
| 11 #include "base/stl_util-inl.h" | 11 #include "base/stl_util-inl.h" |
| 12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/extensions/extension_event_router.h" | 14 #include "chrome/browser/extensions/extension_event_router.h" |
| 15 #include "chrome/browser/extensions/extension_preference_api_constants.h" | 15 #include "chrome/browser/extensions/extension_preference_api_constants.h" |
| 16 #include "chrome/browser/extensions/extension_preference_helpers.h" | 16 #include "chrome/browser/extensions/extension_preference_helpers.h" |
| 17 #include "chrome/browser/extensions/extension_prefs.h" | 17 #include "chrome/browser/extensions/extension_prefs.h" |
| 18 #include "chrome/browser/extensions/extension_prefs_scope.h" | 18 #include "chrome/browser/extensions/extension_prefs_scope.h" |
| 19 #include "chrome/browser/extensions/extension_proxy_api.h" | 19 #include "chrome/browser/extensions/extension_proxy_api.h" |
| 20 #include "chrome/browser/extensions/extension_service.h" | 20 #include "chrome/browser/extensions/extension_service.h" |
| 21 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| 22 #include "chrome/common/extensions/extension_error_utils.h" | 22 #include "chrome/common/extensions/extension_error_utils.h" |
| 23 #include "chrome/common/extensions/extension_permission_set.h" |
| 23 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
| 24 #include "content/common/notification_type.h" | 25 #include "content/common/notification_type.h" |
| 25 #include "content/common/notification_service.h" | 26 #include "content/common/notification_service.h" |
| 26 | 27 |
| 27 namespace { | 28 namespace { |
| 28 | 29 |
| 29 struct PrefMappingEntry { | 30 struct PrefMappingEntry { |
| 30 const char* extension_pref; | 31 const char* extension_pref; |
| 31 const char* browser_pref; | 32 const char* browser_pref; |
| 32 const char* permission; | 33 ExtensionAPIPermission::ID permission; |
| 33 }; | 34 }; |
| 34 | 35 |
| 35 const char kNotControllable[] = "not_controllable"; | 36 const char kNotControllable[] = "not_controllable"; |
| 36 const char kControlledByOtherExtensions[] = "controlled_by_other_extensions"; | 37 const char kControlledByOtherExtensions[] = "controlled_by_other_extensions"; |
| 37 const char kControllableByThisExtension[] = "controllable_by_this_extension"; | 38 const char kControllableByThisExtension[] = "controllable_by_this_extension"; |
| 38 const char kControlledByThisExtension[] = "controlled_by_this_extension"; | 39 const char kControlledByThisExtension[] = "controlled_by_this_extension"; |
| 39 | 40 |
| 40 const char kIncognitoSpecific[] = "incognitoSpecific"; | 41 const char kIncognitoSpecific[] = "incognitoSpecific"; |
| 41 const char kLevelOfControl[] = "levelOfControl"; | 42 const char kLevelOfControl[] = "levelOfControl"; |
| 42 const char kValue[] = "value"; | 43 const char kValue[] = "value"; |
| 43 | 44 |
| 44 const char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange"; | 45 const char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange"; |
| 45 | 46 |
| 46 PrefMappingEntry kPrefMapping[] = { | 47 PrefMappingEntry kPrefMapping[] = { |
| 47 { "thirdPartyCookiesAllowed", | 48 { "thirdPartyCookiesAllowed", |
| 48 prefs::kBlockThirdPartyCookies, | 49 prefs::kBlockThirdPartyCookies, |
| 49 Extension::kContentSettingsPermission | 50 ExtensionAPIPermission::kContentSettings |
| 50 }, | 51 }, |
| 51 { "referrersEnabled", | 52 { "referrersEnabled", |
| 52 prefs::kEnableReferrers, | 53 prefs::kEnableReferrers, |
| 53 Extension::kContentSettingsPermission | 54 ExtensionAPIPermission::kContentSettings |
| 54 }, | 55 }, |
| 55 { "hyperlinkAuditingEnabled", | 56 { "hyperlinkAuditingEnabled", |
| 56 prefs::kEnableHyperlinkAuditing, | 57 prefs::kEnableHyperlinkAuditing, |
| 57 Extension::kContentSettingsPermission | 58 ExtensionAPIPermission::kContentSettings |
| 58 }, | 59 }, |
| 59 { "proxy", | 60 { "proxy", |
| 60 prefs::kProxy, | 61 prefs::kProxy, |
| 61 Extension::kProxyPermission | 62 ExtensionAPIPermission::kProxy |
| 62 }, | 63 }, |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 class IdentityPrefTransformer : public PrefTransformerInterface { | 66 class IdentityPrefTransformer : public PrefTransformerInterface { |
| 66 public: | 67 public: |
| 67 virtual Value* ExtensionToBrowserPref(const Value* extension_pref, | 68 virtual Value* ExtensionToBrowserPref(const Value* extension_pref, |
| 68 std::string* error, | 69 std::string* error, |
| 69 bool* bad_message) { | 70 bool* bad_message) { |
| 70 return extension_pref->DeepCopy(); | 71 return extension_pref->DeepCopy(); |
| 71 } | 72 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 } | 124 } |
| 124 | 125 |
| 125 class PrefMapping { | 126 class PrefMapping { |
| 126 public: | 127 public: |
| 127 static PrefMapping* GetInstance() { | 128 static PrefMapping* GetInstance() { |
| 128 return Singleton<PrefMapping>::get(); | 129 return Singleton<PrefMapping>::get(); |
| 129 } | 130 } |
| 130 | 131 |
| 131 bool FindBrowserPrefForExtensionPref(const std::string& extension_pref, | 132 bool FindBrowserPrefForExtensionPref(const std::string& extension_pref, |
| 132 std::string* browser_pref, | 133 std::string* browser_pref, |
| 133 std::string* permission) { | 134 ExtensionAPIPermission::ID* permission) { |
| 134 std::map<std::string, std::pair<std::string, std::string> >::iterator it = | 135 PrefMap::iterator it = mapping_.find(extension_pref); |
| 135 mapping_.find(extension_pref); | |
| 136 if (it != mapping_.end()) { | 136 if (it != mapping_.end()) { |
| 137 *browser_pref = it->second.first; | 137 *browser_pref = it->second.first; |
| 138 *permission = it->second.second; | 138 *permission = it->second.second; |
| 139 return true; | 139 return true; |
| 140 } | 140 } |
| 141 return false; | 141 return false; |
| 142 } | 142 } |
| 143 | 143 |
| 144 bool FindEventForBrowserPref(const std::string& browser_pref, | 144 bool FindEventForBrowserPref(const std::string& browser_pref, |
| 145 std::string* event_name, | 145 std::string* event_name, |
| 146 std::string* permission) { | 146 ExtensionAPIPermission::ID* permission) { |
| 147 std::map<std::string, std::pair<std::string, std::string> >::iterator it = | 147 PrefMap::iterator it = event_mapping_.find(browser_pref); |
| 148 event_mapping_.find(browser_pref); | |
| 149 if (it != event_mapping_.end()) { | 148 if (it != event_mapping_.end()) { |
| 150 *event_name = it->second.first; | 149 *event_name = it->second.first; |
| 151 *permission = it->second.second; | 150 *permission = it->second.second; |
| 152 return true; | 151 return true; |
| 153 } | 152 } |
| 154 return false; | 153 return false; |
| 155 } | 154 } |
| 156 | 155 |
| 157 PrefTransformerInterface* FindTransformerForBrowserPref( | 156 PrefTransformerInterface* FindTransformerForBrowserPref( |
| 158 const std::string& browser_pref) { | 157 const std::string& browser_pref) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 transformers_.end()); | 190 transformers_.end()); |
| 192 } | 191 } |
| 193 | 192 |
| 194 void RegisterPrefTransformer(const std::string& browser_pref, | 193 void RegisterPrefTransformer(const std::string& browser_pref, |
| 195 PrefTransformerInterface* transformer) { | 194 PrefTransformerInterface* transformer) { |
| 196 DCHECK_EQ(0u, transformers_.count(browser_pref)) << | 195 DCHECK_EQ(0u, transformers_.count(browser_pref)) << |
| 197 "Trying to register pref transformer for " << browser_pref << " twice"; | 196 "Trying to register pref transformer for " << browser_pref << " twice"; |
| 198 transformers_[browser_pref] = transformer; | 197 transformers_[browser_pref] = transformer; |
| 199 } | 198 } |
| 200 | 199 |
| 200 typedef std::map<std::string, |
| 201 std::pair<std::string, ExtensionAPIPermission::ID> > |
| 202 PrefMap; |
| 203 |
| 201 // Mapping from extension pref keys to browser pref keys and permissions. | 204 // Mapping from extension pref keys to browser pref keys and permissions. |
| 202 std::map<std::string, std::pair<std::string, std::string> > mapping_; | 205 PrefMap mapping_; |
| 203 | 206 |
| 204 // Mapping from browser pref keys to extension event names and permissions. | 207 // Mapping from browser pref keys to extension event names and permissions. |
| 205 std::map<std::string, std::pair<std::string, std::string> > event_mapping_; | 208 PrefMap event_mapping_; |
| 206 | 209 |
| 207 // Mapping from browser pref keys to transformers. | 210 // Mapping from browser pref keys to transformers. |
| 208 std::map<std::string, PrefTransformerInterface*> transformers_; | 211 std::map<std::string, PrefTransformerInterface*> transformers_; |
| 209 | 212 |
| 210 scoped_ptr<PrefTransformerInterface> identity_transformer_; | 213 scoped_ptr<PrefTransformerInterface> identity_transformer_; |
| 211 | 214 |
| 212 DISALLOW_COPY_AND_ASSIGN(PrefMapping); | 215 DISALLOW_COPY_AND_ASSIGN(PrefMapping); |
| 213 }; | 216 }; |
| 214 | 217 |
| 215 } // namespace | 218 } // namespace |
| (...skipping 25 matching lines...) Expand all Loading... |
| 241 NOTREACHED(); | 244 NOTREACHED(); |
| 242 } | 245 } |
| 243 } | 246 } |
| 244 | 247 |
| 245 void ExtensionPreferenceEventRouter::OnPrefChanged( | 248 void ExtensionPreferenceEventRouter::OnPrefChanged( |
| 246 PrefService* pref_service, | 249 PrefService* pref_service, |
| 247 const std::string& browser_pref) { | 250 const std::string& browser_pref) { |
| 248 bool incognito = (pref_service != profile_->GetPrefs()); | 251 bool incognito = (pref_service != profile_->GetPrefs()); |
| 249 | 252 |
| 250 std::string event_name; | 253 std::string event_name; |
| 251 std::string permission; | 254 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; |
| 252 bool rv = PrefMapping::GetInstance()->FindEventForBrowserPref( | 255 bool rv = PrefMapping::GetInstance()->FindEventForBrowserPref( |
| 253 browser_pref, &event_name, &permission); | 256 browser_pref, &event_name, &permission); |
| 254 DCHECK(rv); | 257 DCHECK(rv); |
| 255 | 258 |
| 256 ListValue args; | 259 ListValue args; |
| 257 DictionaryValue* dict = new DictionaryValue(); | 260 DictionaryValue* dict = new DictionaryValue(); |
| 258 args.Append(dict); | 261 args.Append(dict); |
| 259 const PrefService::Preference* pref = | 262 const PrefService::Preference* pref = |
| 260 pref_service->FindPreference(browser_pref.c_str()); | 263 pref_service->FindPreference(browser_pref.c_str()); |
| 261 CHECK(pref); | 264 CHECK(pref); |
| 262 ExtensionService* extension_service = profile_->GetExtensionService(); | 265 ExtensionService* extension_service = profile_->GetExtensionService(); |
| 263 PrefTransformerInterface* transformer = | 266 PrefTransformerInterface* transformer = |
| 264 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); | 267 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); |
| 265 dict->Set(kValue, transformer->BrowserToExtensionPref(pref->GetValue())); | 268 dict->Set(kValue, transformer->BrowserToExtensionPref(pref->GetValue())); |
| 266 if (incognito) { | 269 if (incognito) { |
| 267 ExtensionPrefs* ep = extension_service->extension_prefs(); | 270 ExtensionPrefs* ep = extension_service->extension_prefs(); |
| 268 dict->SetBoolean(kIncognitoSpecific, | 271 dict->SetBoolean(kIncognitoSpecific, |
| 269 ep->HasIncognitoPrefValue(browser_pref)); | 272 ep->HasIncognitoPrefValue(browser_pref)); |
| 270 } | 273 } |
| 271 | 274 |
| 272 ExtensionEventRouter* router = profile_->GetExtensionEventRouter(); | 275 ExtensionEventRouter* router = profile_->GetExtensionEventRouter(); |
| 273 if (!router || !router->HasEventListener(event_name)) | 276 if (!router || !router->HasEventListener(event_name)) |
| 274 return; | 277 return; |
| 275 const ExtensionList* extensions = extension_service->extensions(); | 278 const ExtensionList* extensions = extension_service->extensions(); |
| 276 for (ExtensionList::const_iterator it = extensions->begin(); | 279 for (ExtensionList::const_iterator it = extensions->begin(); |
| 277 it != extensions->end(); ++it) { | 280 it != extensions->end(); ++it) { |
| 278 std::string extension_id = (*it)->id(); | 281 std::string extension_id = (*it)->id(); |
| 279 // TODO(bauerb): Only iterate over registered event listeners. | 282 // TODO(bauerb): Only iterate over registered event listeners. |
| 280 if (router->ExtensionHasEventListener(extension_id, event_name) && | 283 if (router->ExtensionHasEventListener(extension_id, event_name) && |
| 281 (*it)->HasApiPermission(permission) && | 284 (*it)->HasAPIPermission(permission) && |
| 282 (!incognito || extension_service->CanCrossIncognito(*it))) { | 285 (!incognito || extension_service->CanCrossIncognito(*it))) { |
| 283 std::string level_of_control = | 286 std::string level_of_control = |
| 284 GetLevelOfControl(profile_, extension_id, browser_pref, incognito); | 287 GetLevelOfControl(profile_, extension_id, browser_pref, incognito); |
| 285 dict->SetString(kLevelOfControl, level_of_control); | 288 dict->SetString(kLevelOfControl, level_of_control); |
| 286 | 289 |
| 287 std::string json_args; | 290 std::string json_args; |
| 288 base::JSONWriter::Write(&args, false, &json_args); | 291 base::JSONWriter::Write(&args, false, &json_args); |
| 289 | 292 |
| 290 DispatchEvent(extension_id, event_name, json_args); | 293 DispatchEvent(extension_id, event_name, json_args); |
| 291 } | 294 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 316 &incognito)); | 319 &incognito)); |
| 317 | 320 |
| 318 if (incognito && !include_incognito()) { | 321 if (incognito && !include_incognito()) { |
| 319 error_ = keys::kIncognitoErrorMessage; | 322 error_ = keys::kIncognitoErrorMessage; |
| 320 return false; | 323 return false; |
| 321 } | 324 } |
| 322 | 325 |
| 323 PrefService* prefs = incognito ? profile_->GetOffTheRecordPrefs() | 326 PrefService* prefs = incognito ? profile_->GetOffTheRecordPrefs() |
| 324 : profile_->GetPrefs(); | 327 : profile_->GetPrefs(); |
| 325 std::string browser_pref; | 328 std::string browser_pref; |
| 326 std::string permission; | 329 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; |
| 327 EXTENSION_FUNCTION_VALIDATE( | 330 EXTENSION_FUNCTION_VALIDATE( |
| 328 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( | 331 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| 329 pref_key, &browser_pref, &permission)); | 332 pref_key, &browser_pref, &permission)); |
| 330 if (!GetExtension()->HasApiPermission(permission)) { | 333 if (!GetExtension()->HasAPIPermission(permission)) { |
| 331 error_ = ExtensionErrorUtils::FormatErrorMessage( | 334 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 332 keys::kPermissionErrorMessage, pref_key); | 335 keys::kPermissionErrorMessage, pref_key); |
| 333 return false; | 336 return false; |
| 334 } | 337 } |
| 335 | 338 |
| 336 const PrefService::Preference* pref = | 339 const PrefService::Preference* pref = |
| 337 prefs->FindPreference(browser_pref.c_str()); | 340 prefs->FindPreference(browser_pref.c_str()); |
| 338 CHECK(pref); | 341 CHECK(pref); |
| 339 std::string level_of_control = | 342 std::string level_of_control = |
| 340 GetLevelOfControl(profile_, extension_id(), browser_pref, incognito); | 343 GetLevelOfControl(profile_, extension_id(), browser_pref, incognito); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 } | 393 } |
| 391 } | 394 } |
| 392 | 395 |
| 393 if (scope == kExtensionPrefsScopeIncognitoSessionOnly && | 396 if (scope == kExtensionPrefsScopeIncognitoSessionOnly && |
| 394 !profile_->HasOffTheRecordProfile()) { | 397 !profile_->HasOffTheRecordProfile()) { |
| 395 error_ = keys::kIncognitoSessionOnlyErrorMessage; | 398 error_ = keys::kIncognitoSessionOnlyErrorMessage; |
| 396 return false; | 399 return false; |
| 397 } | 400 } |
| 398 | 401 |
| 399 std::string browser_pref; | 402 std::string browser_pref; |
| 400 std::string permission; | 403 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; |
| 401 EXTENSION_FUNCTION_VALIDATE( | 404 EXTENSION_FUNCTION_VALIDATE( |
| 402 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( | 405 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| 403 pref_key, &browser_pref, &permission)); | 406 pref_key, &browser_pref, &permission)); |
| 404 if (!GetExtension()->HasApiPermission(permission)) { | 407 if (!GetExtension()->HasAPIPermission(permission)) { |
| 405 error_ = ExtensionErrorUtils::FormatErrorMessage( | 408 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 406 keys::kPermissionErrorMessage, pref_key); | 409 keys::kPermissionErrorMessage, pref_key); |
| 407 return false; | 410 return false; |
| 408 } | 411 } |
| 409 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); | 412 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); |
| 410 const PrefService::Preference* pref = | 413 const PrefService::Preference* pref = |
| 411 prefs->pref_service()->FindPreference(browser_pref.c_str()); | 414 prefs->pref_service()->FindPreference(browser_pref.c_str()); |
| 412 CHECK(pref); | 415 CHECK(pref); |
| 413 EXTENSION_FUNCTION_VALIDATE(value->GetType() == pref->GetType()); | 416 EXTENSION_FUNCTION_VALIDATE(value->GetType() == pref->GetType()); |
| 414 PrefTransformerInterface* transformer = | 417 PrefTransformerInterface* transformer = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 } else { | 457 } else { |
| 455 // Incognito profiles can't access regular mode ever, they only exist in | 458 // Incognito profiles can't access regular mode ever, they only exist in |
| 456 // split mode. | 459 // split mode. |
| 457 if (profile()->IsOffTheRecord()) { | 460 if (profile()->IsOffTheRecord()) { |
| 458 error_ = "Can't modify regular settings from an incognito context."; | 461 error_ = "Can't modify regular settings from an incognito context."; |
| 459 return false; | 462 return false; |
| 460 } | 463 } |
| 461 } | 464 } |
| 462 | 465 |
| 463 std::string browser_pref; | 466 std::string browser_pref; |
| 464 std::string permission; | 467 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; |
| 465 EXTENSION_FUNCTION_VALIDATE( | 468 EXTENSION_FUNCTION_VALIDATE( |
| 466 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( | 469 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| 467 pref_key, &browser_pref, &permission)); | 470 pref_key, &browser_pref, &permission)); |
| 468 if (!GetExtension()->HasApiPermission(permission)) { | 471 if (!GetExtension()->HasAPIPermission(permission)) { |
| 469 error_ = ExtensionErrorUtils::FormatErrorMessage( | 472 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 470 keys::kPermissionErrorMessage, pref_key); | 473 keys::kPermissionErrorMessage, pref_key); |
| 471 return false; | 474 return false; |
| 472 } | 475 } |
| 473 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); | 476 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); |
| 474 prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); | 477 prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); |
| 475 return true; | 478 return true; |
| 476 } | 479 } |
| OLD | NEW |