OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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.h" | 11 #include "base/stl_util.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/chrome_notification_types.h" | 22 #include "chrome/common/chrome_notification_types.h" |
23 #include "chrome/common/extensions/extension_error_utils.h" | 23 #include "chrome/common/extensions/extension_error_utils.h" |
24 #include "chrome/common/extensions/extension_permission_set.h" | 24 #include "chrome/common/extensions/extension_permission_set.h" |
25 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
26 #include "content/public/browser/notification_details.h" | 26 #include "content/public/browser/notification_details.h" |
27 #include "content/public/browser/notification_source.h" | 27 #include "content/public/browser/notification_source.h" |
28 | 28 |
| 29 namespace keys = extension_preference_api_constants; |
| 30 namespace helpers = extension_preference_helpers; |
| 31 |
29 namespace { | 32 namespace { |
30 | 33 |
31 struct PrefMappingEntry { | 34 struct PrefMappingEntry { |
32 // Name of the preference referenced by the extension API JSON. | 35 // Name of the preference referenced by the extension API JSON. |
33 const char* extension_pref; | 36 const char* extension_pref; |
34 | 37 |
35 // Name of the preference in the PrefStores. | 38 // Name of the preference in the PrefStores. |
36 const char* browser_pref; | 39 const char* browser_pref; |
37 | 40 |
38 // Permission required to access this preference. | 41 // Permission required to access this preference. |
39 // Use ExtensionAPIPermission::kInvalid for |permission| to express that no | 42 // Use ExtensionAPIPermission::kInvalid for |permission| to express that no |
40 // permission is necessary. | 43 // permission is necessary. |
41 ExtensionAPIPermission::ID permission; | 44 ExtensionAPIPermission::ID permission; |
42 }; | 45 }; |
43 | 46 |
44 const char kNotControllable[] = "not_controllable"; | |
45 const char kControlledByOtherExtensions[] = "controlled_by_other_extensions"; | |
46 const char kControllableByThisExtension[] = "controllable_by_this_extension"; | |
47 const char kControlledByThisExtension[] = "controlled_by_this_extension"; | |
48 | |
49 const char kIncognitoSpecific[] = "incognitoSpecific"; | |
50 const char kLevelOfControl[] = "levelOfControl"; | |
51 const char kValue[] = "value"; | |
52 | |
53 const char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange"; | 47 const char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange"; |
54 | 48 |
55 PrefMappingEntry kPrefMapping[] = { | 49 PrefMappingEntry kPrefMapping[] = { |
56 { "alternateErrorPagesEnabled", | 50 { "alternateErrorPagesEnabled", |
57 prefs::kAlternateErrorPagesEnabled, | 51 prefs::kAlternateErrorPagesEnabled, |
58 ExtensionAPIPermission::kPrivacy | 52 ExtensionAPIPermission::kPrivacy |
59 }, | 53 }, |
60 { "autofillEnabled", | 54 { "autofillEnabled", |
61 prefs::kAutofillEnabled, | 55 prefs::kAutofillEnabled, |
62 ExtensionAPIPermission::kPrivacy | 56 ExtensionAPIPermission::kPrivacy |
63 }, | 57 }, |
64 { "hyperlinkAuditingEnabled", | 58 { "hyperlinkAuditingEnabled", |
65 prefs::kEnableHyperlinkAuditing, | 59 prefs::kEnableHyperlinkAuditing, |
66 ExtensionAPIPermission::kPrivacy | 60 ExtensionAPIPermission::kPrivacy |
67 }, | 61 }, |
68 { "instantEnabled", | 62 { "instantEnabled", |
69 prefs::kInstantEnabled, | 63 prefs::kInstantEnabled, |
70 ExtensionAPIPermission::kPrivacy | 64 ExtensionAPIPermission::kPrivacy |
71 }, | 65 }, |
| 66 { "managedModeEnabled", |
| 67 prefs::kInManagedMode, |
| 68 ExtensionAPIPermission::kManagedMode |
| 69 }, |
72 { "networkPredictionEnabled", | 70 { "networkPredictionEnabled", |
73 prefs::kNetworkPredictionEnabled, | 71 prefs::kNetworkPredictionEnabled, |
74 ExtensionAPIPermission::kPrivacy | 72 ExtensionAPIPermission::kPrivacy |
75 }, | 73 }, |
76 { "proxy", | 74 { "proxy", |
77 prefs::kProxy, | 75 prefs::kProxy, |
78 ExtensionAPIPermission::kProxy | 76 ExtensionAPIPermission::kProxy |
79 }, | 77 }, |
80 { "referrersEnabled", | 78 { "referrersEnabled", |
81 prefs::kEnableReferrers, | 79 prefs::kEnableReferrers, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 const std::string& browser_pref, | 139 const std::string& browser_pref, |
142 bool incognito) { | 140 bool incognito) { |
143 PrefService* prefs = incognito ? profile->GetOffTheRecordPrefs() | 141 PrefService* prefs = incognito ? profile->GetOffTheRecordPrefs() |
144 : profile->GetPrefs(); | 142 : profile->GetPrefs(); |
145 const PrefService::Preference* pref = | 143 const PrefService::Preference* pref = |
146 prefs->FindPreference(browser_pref.c_str()); | 144 prefs->FindPreference(browser_pref.c_str()); |
147 CHECK(pref); | 145 CHECK(pref); |
148 ExtensionPrefs* ep = profile->GetExtensionService()->extension_prefs(); | 146 ExtensionPrefs* ep = profile->GetExtensionService()->extension_prefs(); |
149 | 147 |
150 if (!pref->IsExtensionModifiable()) | 148 if (!pref->IsExtensionModifiable()) |
151 return kNotControllable; | 149 return keys::kNotControllable; |
152 | 150 |
153 if (ep->DoesExtensionControlPref(extension_id, browser_pref, incognito)) | 151 if (ep->DoesExtensionControlPref(extension_id, browser_pref, incognito)) |
154 return kControlledByThisExtension; | 152 return keys::kControlledByThisExtension; |
155 | 153 |
156 if (ep->CanExtensionControlPref(extension_id, browser_pref, incognito)) | 154 if (ep->CanExtensionControlPref(extension_id, browser_pref, incognito)) |
157 return kControllableByThisExtension; | 155 return keys::kControllableByThisExtension; |
158 | 156 |
159 return kControlledByOtherExtensions; | 157 return keys::kControlledByOtherExtensions; |
160 } | 158 } |
161 | 159 |
162 class PrefMapping { | 160 class PrefMapping { |
163 public: | 161 public: |
164 static PrefMapping* GetInstance() { | 162 static PrefMapping* GetInstance() { |
165 return Singleton<PrefMapping>::get(); | 163 return Singleton<PrefMapping>::get(); |
166 } | 164 } |
167 | 165 |
168 bool FindBrowserPrefForExtensionPref(const std::string& extension_pref, | 166 bool FindBrowserPrefForExtensionPref(const std::string& extension_pref, |
169 std::string* browser_pref, | 167 std::string* browser_pref, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 // Mapping from browser pref keys to transformers. | 244 // Mapping from browser pref keys to transformers. |
247 std::map<std::string, PrefTransformerInterface*> transformers_; | 245 std::map<std::string, PrefTransformerInterface*> transformers_; |
248 | 246 |
249 scoped_ptr<PrefTransformerInterface> identity_transformer_; | 247 scoped_ptr<PrefTransformerInterface> identity_transformer_; |
250 | 248 |
251 DISALLOW_COPY_AND_ASSIGN(PrefMapping); | 249 DISALLOW_COPY_AND_ASSIGN(PrefMapping); |
252 }; | 250 }; |
253 | 251 |
254 } // namespace | 252 } // namespace |
255 | 253 |
256 namespace keys = extension_preference_api_constants; | |
257 namespace helpers = extension_preference_helpers; | |
258 | |
259 ExtensionPreferenceEventRouter::ExtensionPreferenceEventRouter( | 254 ExtensionPreferenceEventRouter::ExtensionPreferenceEventRouter( |
260 Profile* profile) : profile_(profile) { | 255 Profile* profile) : profile_(profile) { |
261 registrar_.Init(profile_->GetPrefs()); | 256 registrar_.Init(profile_->GetPrefs()); |
262 incognito_registrar_.Init(profile_->GetOffTheRecordPrefs()); | 257 incognito_registrar_.Init(profile_->GetOffTheRecordPrefs()); |
263 for (size_t i = 0; i < arraysize(kPrefMapping); ++i) { | 258 for (size_t i = 0; i < arraysize(kPrefMapping); ++i) { |
264 registrar_.Add(kPrefMapping[i].browser_pref, this); | 259 registrar_.Add(kPrefMapping[i].browser_pref, this); |
265 incognito_registrar_.Add(kPrefMapping[i].browser_pref, this); | 260 incognito_registrar_.Add(kPrefMapping[i].browser_pref, this); |
266 } | 261 } |
267 } | 262 } |
268 | 263 |
(...skipping 25 matching lines...) Expand all Loading... |
294 | 289 |
295 ListValue args; | 290 ListValue args; |
296 DictionaryValue* dict = new DictionaryValue(); | 291 DictionaryValue* dict = new DictionaryValue(); |
297 args.Append(dict); | 292 args.Append(dict); |
298 const PrefService::Preference* pref = | 293 const PrefService::Preference* pref = |
299 pref_service->FindPreference(browser_pref.c_str()); | 294 pref_service->FindPreference(browser_pref.c_str()); |
300 CHECK(pref); | 295 CHECK(pref); |
301 ExtensionService* extension_service = profile_->GetExtensionService(); | 296 ExtensionService* extension_service = profile_->GetExtensionService(); |
302 PrefTransformerInterface* transformer = | 297 PrefTransformerInterface* transformer = |
303 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); | 298 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); |
304 dict->Set(kValue, transformer->BrowserToExtensionPref(pref->GetValue())); | 299 dict->Set(keys::kValue, |
| 300 transformer->BrowserToExtensionPref(pref->GetValue())); |
305 if (incognito) { | 301 if (incognito) { |
306 ExtensionPrefs* ep = extension_service->extension_prefs(); | 302 ExtensionPrefs* ep = extension_service->extension_prefs(); |
307 dict->SetBoolean(kIncognitoSpecific, | 303 dict->SetBoolean(keys::kIncognitoSpecific, |
308 ep->HasIncognitoPrefValue(browser_pref)); | 304 ep->HasIncognitoPrefValue(browser_pref)); |
309 } | 305 } |
310 | 306 |
311 ExtensionEventRouter* router = profile_->GetExtensionEventRouter(); | 307 ExtensionEventRouter* router = profile_->GetExtensionEventRouter(); |
312 if (!router || !router->HasEventListener(event_name)) | 308 if (!router || !router->HasEventListener(event_name)) |
313 return; | 309 return; |
314 const ExtensionSet* extensions = extension_service->extensions(); | 310 const ExtensionSet* extensions = extension_service->extensions(); |
315 for (ExtensionSet::const_iterator it = extensions->begin(); | 311 for (ExtensionSet::const_iterator it = extensions->begin(); |
316 it != extensions->end(); ++it) { | 312 it != extensions->end(); ++it) { |
317 std::string extension_id = (*it)->id(); | 313 std::string extension_id = (*it)->id(); |
318 // TODO(bauerb): Only iterate over registered event listeners. | 314 // TODO(bauerb): Only iterate over registered event listeners. |
319 if (router->ExtensionHasEventListener(extension_id, event_name) && | 315 if (router->ExtensionHasEventListener(extension_id, event_name) && |
320 (*it)->HasAPIPermission(permission) && | 316 (*it)->HasAPIPermission(permission) && |
321 (!incognito || extension_service->CanCrossIncognito(*it))) { | 317 (!incognito || extension_service->CanCrossIncognito(*it))) { |
322 std::string level_of_control = | 318 std::string level_of_control = |
323 GetLevelOfControl(profile_, extension_id, browser_pref, incognito); | 319 GetLevelOfControl(profile_, extension_id, browser_pref, incognito); |
324 dict->SetString(kLevelOfControl, level_of_control); | 320 dict->SetString(keys::kLevelOfControl, level_of_control); |
325 | 321 |
326 std::string json_args; | 322 std::string json_args; |
327 base::JSONWriter::Write(&args, false, &json_args); | 323 base::JSONWriter::Write(&args, false, &json_args); |
328 | 324 |
329 DispatchEvent(extension_id, event_name, json_args); | 325 DispatchEvent(extension_id, event_name, json_args); |
330 } | 326 } |
331 } | 327 } |
332 } | 328 } |
333 | 329 |
334 void ExtensionPreferenceEventRouter::DispatchEvent( | 330 void ExtensionPreferenceEventRouter::DispatchEvent( |
335 const std::string& extension_id, | 331 const std::string& extension_id, |
336 const std::string& event_name, | 332 const std::string& event_name, |
337 const std::string& json_args) { | 333 const std::string& json_args) { |
338 profile_->GetExtensionEventRouter()->DispatchEventToExtension( | 334 profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
339 extension_id, event_name, json_args, NULL, GURL()); | 335 extension_id, event_name, json_args, NULL, GURL()); |
340 } | 336 } |
341 | 337 |
342 // TODO(battre): Factor out common parts once this is stable. | 338 PreferenceFunction::~PreferenceFunction() { } |
| 339 |
| 340 bool PreferenceFunction::ValidateBrowserPref( |
| 341 const std::string& extension_pref_key, |
| 342 std::string* browser_pref_key) { |
| 343 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; |
| 344 EXTENSION_FUNCTION_VALIDATE( |
| 345 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( |
| 346 extension_pref_key, browser_pref_key, &permission)); |
| 347 if (!GetExtension()->HasAPIPermission(permission)) { |
| 348 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 349 keys::kPermissionErrorMessage, extension_pref_key); |
| 350 return false; |
| 351 } |
| 352 return true; |
| 353 } |
343 | 354 |
344 GetPreferenceFunction::~GetPreferenceFunction() { } | 355 GetPreferenceFunction::~GetPreferenceFunction() { } |
345 | 356 |
346 bool GetPreferenceFunction::RunImpl() { | 357 bool GetPreferenceFunction::RunImpl() { |
347 std::string pref_key; | 358 std::string pref_key; |
348 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); | 359 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); |
349 DictionaryValue* details = NULL; | 360 DictionaryValue* details = NULL; |
350 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | 361 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); |
351 | 362 |
352 bool incognito = false; | 363 bool incognito = false; |
353 if (details->HasKey(keys::kIncognitoKey)) | 364 if (details->HasKey(keys::kIncognitoKey)) |
354 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(keys::kIncognitoKey, | 365 EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(keys::kIncognitoKey, |
355 &incognito)); | 366 &incognito)); |
356 | 367 |
| 368 // Check incognito access. |
357 if (incognito && !include_incognito()) { | 369 if (incognito && !include_incognito()) { |
358 error_ = keys::kIncognitoErrorMessage; | 370 error_ = keys::kIncognitoErrorMessage; |
359 return false; | 371 return false; |
360 } | 372 } |
361 | 373 |
| 374 // Obtain pref. |
| 375 std::string browser_pref; |
| 376 if (!ValidateBrowserPref(pref_key, &browser_pref)) |
| 377 return false; |
362 PrefService* prefs = incognito ? profile_->GetOffTheRecordPrefs() | 378 PrefService* prefs = incognito ? profile_->GetOffTheRecordPrefs() |
363 : profile_->GetPrefs(); | 379 : profile_->GetPrefs(); |
364 std::string browser_pref; | |
365 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; | |
366 EXTENSION_FUNCTION_VALIDATE( | |
367 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( | |
368 pref_key, &browser_pref, &permission)); | |
369 if (!GetExtension()->HasAPIPermission(permission)) { | |
370 error_ = ExtensionErrorUtils::FormatErrorMessage( | |
371 keys::kPermissionErrorMessage, pref_key); | |
372 return false; | |
373 } | |
374 | |
375 const PrefService::Preference* pref = | 380 const PrefService::Preference* pref = |
376 prefs->FindPreference(browser_pref.c_str()); | 381 prefs->FindPreference(browser_pref.c_str()); |
377 CHECK(pref); | 382 CHECK(pref); |
| 383 |
| 384 scoped_ptr<DictionaryValue> result(new DictionaryValue); |
| 385 |
| 386 // Retrieve level of control. |
378 std::string level_of_control = | 387 std::string level_of_control = |
379 GetLevelOfControl(profile_, extension_id(), browser_pref, incognito); | 388 GetLevelOfControl(profile_, extension_id(), browser_pref, incognito); |
| 389 result->SetString(keys::kLevelOfControl, level_of_control); |
380 | 390 |
381 scoped_ptr<DictionaryValue> result(new DictionaryValue); | 391 // Retrieve pref value. |
382 PrefTransformerInterface* transformer = | 392 PrefTransformerInterface* transformer = |
383 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); | 393 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); |
384 result->Set(kValue, transformer->BrowserToExtensionPref(pref->GetValue())); | 394 result->Set(keys::kValue, |
385 result->SetString(kLevelOfControl, level_of_control); | 395 transformer->BrowserToExtensionPref(pref->GetValue())); |
| 396 |
| 397 // Retrieve incognito status. |
386 if (incognito) { | 398 if (incognito) { |
387 ExtensionPrefs* ep = profile_->GetExtensionService()->extension_prefs(); | 399 ExtensionPrefs* ep = profile_->GetExtensionService()->extension_prefs(); |
388 result->SetBoolean(kIncognitoSpecific, | 400 result->SetBoolean(keys::kIncognitoSpecific, |
389 ep->HasIncognitoPrefValue(browser_pref)); | 401 ep->HasIncognitoPrefValue(browser_pref)); |
390 } | 402 } |
| 403 |
391 result_.reset(result.release()); | 404 result_.reset(result.release()); |
392 return true; | 405 return true; |
393 } | 406 } |
394 | 407 |
395 SetPreferenceFunction::~SetPreferenceFunction() { } | 408 SetPreferenceFunction::~SetPreferenceFunction() { } |
396 | 409 |
397 bool SetPreferenceFunction::RunImpl() { | 410 bool SetPreferenceFunction::RunImpl() { |
398 std::string pref_key; | 411 std::string pref_key; |
399 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); | 412 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); |
400 DictionaryValue* details = NULL; | 413 DictionaryValue* details = NULL; |
401 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | 414 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); |
402 | 415 |
403 Value* value = NULL; | 416 Value* value = NULL; |
404 EXTENSION_FUNCTION_VALIDATE(details->Get(kValue, &value)); | 417 EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kValue, &value)); |
405 | 418 |
406 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; | 419 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; |
407 if (details->HasKey(keys::kScopeKey)) { | 420 if (details->HasKey(keys::kScopeKey)) { |
408 std::string scope_str; | 421 std::string scope_str; |
409 EXTENSION_FUNCTION_VALIDATE( | 422 EXTENSION_FUNCTION_VALIDATE( |
410 details->GetString(keys::kScopeKey, &scope_str)); | 423 details->GetString(keys::kScopeKey, &scope_str)); |
411 | 424 |
412 EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); | 425 EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); |
413 } | 426 } |
414 | 427 |
| 428 // Check incognito scope. |
415 bool incognito = (scope == kExtensionPrefsScopeIncognitoPersistent || | 429 bool incognito = (scope == kExtensionPrefsScopeIncognitoPersistent || |
416 scope == kExtensionPrefsScopeIncognitoSessionOnly); | 430 scope == kExtensionPrefsScopeIncognitoSessionOnly); |
417 if (incognito) { | 431 if (incognito) { |
418 // Regular profiles can't access incognito unless include_incognito is true. | 432 // Regular profiles can't access incognito unless include_incognito is true. |
419 if (!profile()->IsOffTheRecord() && !include_incognito()) { | 433 if (!profile()->IsOffTheRecord() && !include_incognito()) { |
420 error_ = keys::kIncognitoErrorMessage; | 434 error_ = keys::kIncognitoErrorMessage; |
421 return false; | 435 return false; |
422 } | 436 } |
423 } else { | 437 } else { |
424 // Incognito profiles can't access regular mode ever, they only exist in | 438 // Incognito profiles can't access regular mode ever, they only exist in |
425 // split mode. | 439 // split mode. |
426 if (profile()->IsOffTheRecord()) { | 440 if (profile()->IsOffTheRecord()) { |
427 error_ = "Can't modify regular settings from an incognito context."; | 441 error_ = "Can't modify regular settings from an incognito context."; |
428 return false; | 442 return false; |
429 } | 443 } |
430 } | 444 } |
431 | 445 |
432 if (scope == kExtensionPrefsScopeIncognitoSessionOnly && | 446 if (scope == kExtensionPrefsScopeIncognitoSessionOnly && |
433 !profile_->HasOffTheRecordProfile()) { | 447 !profile_->HasOffTheRecordProfile()) { |
434 error_ = keys::kIncognitoSessionOnlyErrorMessage; | 448 error_ = keys::kIncognitoSessionOnlyErrorMessage; |
435 return false; | 449 return false; |
436 } | 450 } |
437 | 451 |
| 452 // Obtain pref. |
438 std::string browser_pref; | 453 std::string browser_pref; |
439 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; | 454 if (!ValidateBrowserPref(pref_key, &browser_pref)) |
440 EXTENSION_FUNCTION_VALIDATE( | |
441 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( | |
442 pref_key, &browser_pref, &permission)); | |
443 if (!GetExtension()->HasAPIPermission(permission)) { | |
444 error_ = ExtensionErrorUtils::FormatErrorMessage( | |
445 keys::kPermissionErrorMessage, pref_key); | |
446 return false; | 455 return false; |
447 } | |
448 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); | 456 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); |
449 const PrefService::Preference* pref = | 457 const PrefService::Preference* pref = |
450 prefs->pref_service()->FindPreference(browser_pref.c_str()); | 458 prefs->pref_service()->FindPreference(browser_pref.c_str()); |
451 CHECK(pref); | 459 CHECK(pref); |
| 460 |
| 461 // Validate new value. |
452 EXTENSION_FUNCTION_VALIDATE(value->GetType() == pref->GetType()); | 462 EXTENSION_FUNCTION_VALIDATE(value->GetType() == pref->GetType()); |
453 PrefTransformerInterface* transformer = | 463 PrefTransformerInterface* transformer = |
454 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); | 464 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); |
455 std::string error; | 465 std::string error; |
456 bool bad_message = false; | 466 bool bad_message = false; |
457 Value* browserPrefValue = | 467 Value* browserPrefValue = |
458 transformer->ExtensionToBrowserPref(value, &error, &bad_message); | 468 transformer->ExtensionToBrowserPref(value, &error, &bad_message); |
459 if (!browserPrefValue) { | 469 if (!browserPrefValue) { |
460 error_ = error; | 470 error_ = error; |
461 bad_message_ = bad_message; | 471 bad_message_ = bad_message; |
462 return false; | 472 return false; |
463 } | 473 } |
| 474 |
464 prefs->SetExtensionControlledPref(extension_id(), | 475 prefs->SetExtensionControlledPref(extension_id(), |
465 browser_pref, | 476 browser_pref, |
466 scope, | 477 scope, |
467 browserPrefValue); | 478 browserPrefValue); |
468 return true; | 479 return true; |
469 } | 480 } |
470 | 481 |
471 ClearPreferenceFunction::~ClearPreferenceFunction() { } | 482 ClearPreferenceFunction::~ClearPreferenceFunction() { } |
472 | 483 |
473 bool ClearPreferenceFunction::RunImpl() { | 484 bool ClearPreferenceFunction::RunImpl() { |
474 std::string pref_key; | 485 std::string pref_key; |
475 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); | 486 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); |
476 DictionaryValue* details = NULL; | 487 DictionaryValue* details = NULL; |
477 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | 488 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); |
478 | 489 |
479 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; | 490 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; |
480 if (details->HasKey(keys::kScopeKey)) { | 491 if (details->HasKey(keys::kScopeKey)) { |
481 std::string scope_str; | 492 std::string scope_str; |
482 EXTENSION_FUNCTION_VALIDATE( | 493 EXTENSION_FUNCTION_VALIDATE( |
483 details->GetString(keys::kScopeKey, &scope_str)); | 494 details->GetString(keys::kScopeKey, &scope_str)); |
484 | 495 |
485 EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); | 496 EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); |
486 } | 497 } |
487 | 498 |
| 499 // Check incognito scope. |
488 bool incognito = (scope == kExtensionPrefsScopeIncognitoPersistent || | 500 bool incognito = (scope == kExtensionPrefsScopeIncognitoPersistent || |
489 scope == kExtensionPrefsScopeIncognitoSessionOnly); | 501 scope == kExtensionPrefsScopeIncognitoSessionOnly); |
490 if (incognito) { | 502 if (incognito) { |
491 // We don't check incognito permissions here, as an extension should be | 503 // We don't check incognito permissions here, as an extension should be |
492 // always allowed to clear its own settings. | 504 // always allowed to clear its own settings. |
493 } else { | 505 } else { |
494 // Incognito profiles can't access regular mode ever, they only exist in | 506 // Incognito profiles can't access regular mode ever, they only exist in |
495 // split mode. | 507 // split mode. |
496 if (profile()->IsOffTheRecord()) { | 508 if (profile()->IsOffTheRecord()) { |
497 error_ = "Can't modify regular settings from an incognito context."; | 509 error_ = "Can't modify regular settings from an incognito context."; |
498 return false; | 510 return false; |
499 } | 511 } |
500 } | 512 } |
501 | 513 |
502 std::string browser_pref; | 514 std::string browser_pref; |
503 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; | 515 if (!ValidateBrowserPref(pref_key, &browser_pref)) |
504 EXTENSION_FUNCTION_VALIDATE( | |
505 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( | |
506 pref_key, &browser_pref, &permission)); | |
507 if (!GetExtension()->HasAPIPermission(permission)) { | |
508 error_ = ExtensionErrorUtils::FormatErrorMessage( | |
509 keys::kPermissionErrorMessage, pref_key); | |
510 return false; | 516 return false; |
511 } | 517 |
512 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); | 518 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); |
513 prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); | 519 prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); |
514 return true; | 520 return true; |
515 } | 521 } |
OLD | NEW |