Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Side by Side Diff: chrome/browser/extensions/extension_preference_api.cc

Issue 8662008: Implement chrome.systemPrivate.getIncognitoModeAvailability extension API function (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Made destructor virtual Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
Aaron Boodman 2011/11/28 19:32:44 Can you file one or more bugs for yourself to fix
battre 2011/11/28 20:23:16 I will do that, though I am pretty sad seeing that
Bernhard Bauer 2011/11/29 10:00:01 If we want to move this outside of chrome/browser/
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/extensions/extension_system_api.h"
21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/common/chrome_notification_types.h" 23 #include "chrome/common/chrome_notification_types.h"
23 #include "chrome/common/extensions/extension_error_utils.h" 24 #include "chrome/common/extensions/extension_error_utils.h"
24 #include "chrome/common/extensions/extension_permission_set.h" 25 #include "chrome/common/extensions/extension_permission_set.h"
25 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
26 #include "content/public/browser/notification_details.h" 27 #include "content/public/browser/notification_details.h"
27 #include "content/public/browser/notification_source.h" 28 #include "content/public/browser/notification_source.h"
28 29
29 namespace { 30 namespace {
30 31
31 struct PrefMappingEntry { 32 struct PrefMappingEntry {
33 // Name of the preference referenced by extension_api.json.
32 const char* extension_pref; 34 const char* extension_pref;
35
36 // Name of the preference in the PrefStores.
33 const char* browser_pref; 37 const char* browser_pref;
38
39 // Permission required to access this preference.
40 // Use ExtensionAPIPermission::kInvalid for |permission| to express that no
41 // permission is necessary.
34 ExtensionAPIPermission::ID permission; 42 ExtensionAPIPermission::ID permission;
35 }; 43 };
36 44
37 const char kNotControllable[] = "not_controllable"; 45 const char kNotControllable[] = "not_controllable";
38 const char kControlledByOtherExtensions[] = "controlled_by_other_extensions"; 46 const char kControlledByOtherExtensions[] = "controlled_by_other_extensions";
39 const char kControllableByThisExtension[] = "controllable_by_this_extension"; 47 const char kControllableByThisExtension[] = "controllable_by_this_extension";
40 const char kControlledByThisExtension[] = "controlled_by_this_extension"; 48 const char kControlledByThisExtension[] = "controlled_by_this_extension";
41 49
42 const char kIncognitoSpecific[] = "incognitoSpecific"; 50 const char kIncognitoSpecific[] = "incognitoSpecific";
43 const char kLevelOfControl[] = "levelOfControl"; 51 const char kLevelOfControl[] = "levelOfControl";
44 const char kValue[] = "value"; 52 const char kValue[] = "value";
45 53
46 const char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange"; 54 const char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange";
47 55
56 const char* kReadOnlyPrefs[] = {
Aaron Boodman 2011/11/28 19:32:44 Does it really make sense to overload the content
battre 2011/11/28 20:23:16 We lose two things: - subscription to changes (the
57 prefs::kIncognitoModeAvailability
58 };
59
48 PrefMappingEntry kPrefMapping[] = { 60 PrefMappingEntry kPrefMapping[] = {
49 { "alternateErrorPagesEnabled", 61 { "alternateErrorPagesEnabled",
50 prefs::kAlternateErrorPagesEnabled, 62 prefs::kAlternateErrorPagesEnabled,
51 ExtensionAPIPermission::kExperimental 63 ExtensionAPIPermission::kExperimental
52 }, 64 },
53 { "autofillEnabled", 65 { "autofillEnabled",
54 prefs::kAutofillEnabled, 66 prefs::kAutofillEnabled,
55 ExtensionAPIPermission::kExperimental 67 ExtensionAPIPermission::kExperimental
56 }, 68 },
57 { "hyperlinkAuditingEnabled", 69 { "hyperlinkAuditingEnabled",
(...skipping 29 matching lines...) Expand all
87 prefs::kSafeBrowsingEnabled, 99 prefs::kSafeBrowsingEnabled,
88 ExtensionAPIPermission::kExperimental 100 ExtensionAPIPermission::kExperimental
89 }, 101 },
90 { "thirdPartyCookiesAllowed", 102 { "thirdPartyCookiesAllowed",
91 prefs::kBlockThirdPartyCookies, 103 prefs::kBlockThirdPartyCookies,
92 ExtensionAPIPermission::kExperimental 104 ExtensionAPIPermission::kExperimental
93 }, 105 },
94 { "translationServiceEnabled", 106 { "translationServiceEnabled",
95 prefs::kEnableTranslate, 107 prefs::kEnableTranslate,
96 ExtensionAPIPermission::kExperimental 108 ExtensionAPIPermission::kExperimental
109 },
110 { "incognitoModeAvailability",
111 prefs::kIncognitoModeAvailability,
112 ExtensionAPIPermission::kInvalid // kInvalid = none required.
97 } 113 }
98 }; 114 };
99 115
100 class IdentityPrefTransformer : public PrefTransformerInterface { 116 class IdentityPrefTransformer : public PrefTransformerInterface {
101 public: 117 public:
102 virtual Value* ExtensionToBrowserPref(const Value* extension_pref, 118 virtual Value* ExtensionToBrowserPref(const Value* extension_pref,
103 std::string* error, 119 std::string* error,
104 bool* bad_message) { 120 bool* bad_message) {
105 return extension_pref->DeepCopy(); 121 return extension_pref->DeepCopy();
106 } 122 }
(...skipping 17 matching lines...) Expand all
124 140
125 private: 141 private:
126 static Value* InvertBooleanValue(const Value* value) { 142 static Value* InvertBooleanValue(const Value* value) {
127 bool bool_value = false; 143 bool bool_value = false;
128 bool result = value->GetAsBoolean(&bool_value); 144 bool result = value->GetAsBoolean(&bool_value);
129 DCHECK(result); 145 DCHECK(result);
130 return Value::CreateBooleanValue(!bool_value); 146 return Value::CreateBooleanValue(!bool_value);
131 } 147 }
132 }; 148 };
133 149
150 // Checks whether an extension has a specific permission but considers
151 // ExtensionAPIPermission::kInvalid a wildcard that is possessed by every
152 // extension.
153 bool HasAPIPermission(const Extension* extension,
154 ExtensionAPIPermission::ID permission) {
155 return permission == ExtensionAPIPermission::kInvalid ||
156 extension->HasAPIPermission(permission);
157 }
158
159 bool IsReadOnlyPreference(const std::string& browser_pref) {
160 for (size_t i = 0; i < arraysize(kReadOnlyPrefs); ++i) {
161 if (kReadOnlyPrefs[i] == browser_pref)
162 return true;
163 }
164 return false;
165 }
166
134 // Returns a string constant (defined in the API) indicating the level of 167 // Returns a string constant (defined in the API) indicating the level of
135 // control this extension has over the specified preference. 168 // control this extension has over the specified preference.
136 const char* GetLevelOfControl( 169 const char* GetLevelOfControl(
137 Profile* profile, 170 Profile* profile,
138 const std::string& extension_id, 171 const std::string& extension_id,
139 const std::string& browser_pref, 172 const std::string& browser_pref,
140 bool incognito) { 173 bool incognito) {
141 PrefService* prefs = incognito ? profile->GetOffTheRecordPrefs() 174 PrefService* prefs = incognito ? profile->GetOffTheRecordPrefs()
142 : profile->GetPrefs(); 175 : profile->GetPrefs();
143 const PrefService::Preference* pref = 176 const PrefService::Preference* pref =
144 prefs->FindPreference(browser_pref.c_str()); 177 prefs->FindPreference(browser_pref.c_str());
145 CHECK(pref); 178 CHECK(pref);
146 ExtensionPrefs* ep = profile->GetExtensionService()->extension_prefs(); 179 ExtensionPrefs* ep = profile->GetExtensionService()->extension_prefs();
147 180
181 if (IsReadOnlyPreference(browser_pref))
182 return kNotControllable;
183
148 if (!pref->IsExtensionModifiable()) 184 if (!pref->IsExtensionModifiable())
149 return kNotControllable; 185 return kNotControllable;
150 186
151 if (ep->DoesExtensionControlPref(extension_id, browser_pref, incognito)) 187 if (ep->DoesExtensionControlPref(extension_id, browser_pref, incognito))
152 return kControlledByThisExtension; 188 return kControlledByThisExtension;
153 189
154 if (ep->CanExtensionControlPref(extension_id, browser_pref, incognito)) 190 if (ep->CanExtensionControlPref(extension_id, browser_pref, incognito))
155 return kControllableByThisExtension; 191 return kControllableByThisExtension;
156 192
157 return kControlledByOtherExtensions; 193 return kControlledByOtherExtensions;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 std::string event_name = 245 std::string event_name =
210 base::StringPrintf(kOnPrefChangeFormat, 246 base::StringPrintf(kOnPrefChangeFormat,
211 kPrefMapping[i].extension_pref); 247 kPrefMapping[i].extension_pref);
212 event_mapping_[kPrefMapping[i].browser_pref] = 248 event_mapping_[kPrefMapping[i].browser_pref] =
213 std::make_pair(event_name, kPrefMapping[i].permission); 249 std::make_pair(event_name, kPrefMapping[i].permission);
214 } 250 }
215 DCHECK_EQ(arraysize(kPrefMapping), mapping_.size()); 251 DCHECK_EQ(arraysize(kPrefMapping), mapping_.size());
216 DCHECK_EQ(arraysize(kPrefMapping), event_mapping_.size()); 252 DCHECK_EQ(arraysize(kPrefMapping), event_mapping_.size());
217 RegisterPrefTransformer(prefs::kProxy, new ProxyPrefTransformer()); 253 RegisterPrefTransformer(prefs::kProxy, new ProxyPrefTransformer());
218 RegisterPrefTransformer(prefs::kBlockThirdPartyCookies, 254 RegisterPrefTransformer(prefs::kBlockThirdPartyCookies,
219 new InvertBooleanTransformer()); 255 new InvertBooleanTransformer());
256 RegisterPrefTransformer(prefs::kIncognitoModeAvailability,
257 new IncognitoModeAvailabilityTransformer());
220 } 258 }
221 259
222 ~PrefMapping() { 260 ~PrefMapping() {
223 STLDeleteContainerPairSecondPointers(transformers_.begin(), 261 STLDeleteContainerPairSecondPointers(transformers_.begin(),
224 transformers_.end()); 262 transformers_.end());
225 } 263 }
226 264
227 void RegisterPrefTransformer(const std::string& browser_pref, 265 void RegisterPrefTransformer(const std::string& browser_pref,
228 PrefTransformerInterface* transformer) { 266 PrefTransformerInterface* transformer) {
229 DCHECK_EQ(0u, transformers_.count(browser_pref)) << 267 DCHECK_EQ(0u, transformers_.count(browser_pref)) <<
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 346
309 ExtensionEventRouter* router = profile_->GetExtensionEventRouter(); 347 ExtensionEventRouter* router = profile_->GetExtensionEventRouter();
310 if (!router || !router->HasEventListener(event_name)) 348 if (!router || !router->HasEventListener(event_name))
311 return; 349 return;
312 const ExtensionList* extensions = extension_service->extensions(); 350 const ExtensionList* extensions = extension_service->extensions();
313 for (ExtensionList::const_iterator it = extensions->begin(); 351 for (ExtensionList::const_iterator it = extensions->begin();
314 it != extensions->end(); ++it) { 352 it != extensions->end(); ++it) {
315 std::string extension_id = (*it)->id(); 353 std::string extension_id = (*it)->id();
316 // TODO(bauerb): Only iterate over registered event listeners. 354 // TODO(bauerb): Only iterate over registered event listeners.
317 if (router->ExtensionHasEventListener(extension_id, event_name) && 355 if (router->ExtensionHasEventListener(extension_id, event_name) &&
318 (*it)->HasAPIPermission(permission) && 356 HasAPIPermission(it->get(), permission) &&
319 (!incognito || extension_service->CanCrossIncognito(*it))) { 357 (!incognito || extension_service->CanCrossIncognito(*it))) {
320 std::string level_of_control = 358 std::string level_of_control =
321 GetLevelOfControl(profile_, extension_id, browser_pref, incognito); 359 GetLevelOfControl(profile_, extension_id, browser_pref, incognito);
322 dict->SetString(kLevelOfControl, level_of_control); 360 dict->SetString(kLevelOfControl, level_of_control);
323 361
324 std::string json_args; 362 std::string json_args;
325 base::JSONWriter::Write(&args, false, &json_args); 363 base::JSONWriter::Write(&args, false, &json_args);
326 364
327 DispatchEvent(extension_id, event_name, json_args); 365 DispatchEvent(extension_id, event_name, json_args);
328 } 366 }
(...skipping 28 matching lines...) Expand all
357 return false; 395 return false;
358 } 396 }
359 397
360 PrefService* prefs = incognito ? profile_->GetOffTheRecordPrefs() 398 PrefService* prefs = incognito ? profile_->GetOffTheRecordPrefs()
361 : profile_->GetPrefs(); 399 : profile_->GetPrefs();
362 std::string browser_pref; 400 std::string browser_pref;
363 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; 401 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid;
364 EXTENSION_FUNCTION_VALIDATE( 402 EXTENSION_FUNCTION_VALIDATE(
365 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( 403 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref(
366 pref_key, &browser_pref, &permission)); 404 pref_key, &browser_pref, &permission));
367 if (!GetExtension()->HasAPIPermission(permission)) { 405 if (!HasAPIPermission(GetExtension(), permission)) {
368 error_ = ExtensionErrorUtils::FormatErrorMessage( 406 error_ = ExtensionErrorUtils::FormatErrorMessage(
369 keys::kPermissionErrorMessage, pref_key); 407 keys::kPermissionErrorMessage, pref_key);
370 return false; 408 return false;
371 } 409 }
372 410
373 const PrefService::Preference* pref = 411 const PrefService::Preference* pref =
374 prefs->FindPreference(browser_pref.c_str()); 412 prefs->FindPreference(browser_pref.c_str());
375 CHECK(pref); 413 CHECK(pref);
376 std::string level_of_control = 414 std::string level_of_control =
377 GetLevelOfControl(profile_, extension_id(), browser_pref, incognito); 415 GetLevelOfControl(profile_, extension_id(), browser_pref, incognito);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 !profile_->HasOffTheRecordProfile()) { 469 !profile_->HasOffTheRecordProfile()) {
432 error_ = keys::kIncognitoSessionOnlyErrorMessage; 470 error_ = keys::kIncognitoSessionOnlyErrorMessage;
433 return false; 471 return false;
434 } 472 }
435 473
436 std::string browser_pref; 474 std::string browser_pref;
437 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; 475 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid;
438 EXTENSION_FUNCTION_VALIDATE( 476 EXTENSION_FUNCTION_VALIDATE(
439 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( 477 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref(
440 pref_key, &browser_pref, &permission)); 478 pref_key, &browser_pref, &permission));
441 if (!GetExtension()->HasAPIPermission(permission)) { 479 if (!HasAPIPermission(GetExtension(), permission)) {
442 error_ = ExtensionErrorUtils::FormatErrorMessage( 480 error_ = ExtensionErrorUtils::FormatErrorMessage(
443 keys::kPermissionErrorMessage, pref_key); 481 keys::kPermissionErrorMessage, pref_key);
444 return false; 482 return false;
445 } 483 }
484
485 if (IsReadOnlyPreference(browser_pref)) {
486 error_ = ExtensionErrorUtils::FormatErrorMessage(
487 keys::kCannotModifyReadOnlyMessage, pref_key);
488 return false;
489 }
490
446 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); 491 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs();
447 const PrefService::Preference* pref = 492 const PrefService::Preference* pref =
448 prefs->pref_service()->FindPreference(browser_pref.c_str()); 493 prefs->pref_service()->FindPreference(browser_pref.c_str());
449 CHECK(pref); 494 CHECK(pref);
450 EXTENSION_FUNCTION_VALIDATE(value->GetType() == pref->GetType()); 495 EXTENSION_FUNCTION_VALIDATE(value->GetType() == pref->GetType());
451 PrefTransformerInterface* transformer = 496 PrefTransformerInterface* transformer =
452 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); 497 PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref);
453 std::string error; 498 std::string error;
454 bool bad_message = false; 499 bool bad_message = false;
455 Value* browserPrefValue = 500 Value* browserPrefValue =
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 error_ = "Can't modify regular settings from an incognito context."; 540 error_ = "Can't modify regular settings from an incognito context.";
496 return false; 541 return false;
497 } 542 }
498 } 543 }
499 544
500 std::string browser_pref; 545 std::string browser_pref;
501 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid; 546 ExtensionAPIPermission::ID permission = ExtensionAPIPermission::kInvalid;
502 EXTENSION_FUNCTION_VALIDATE( 547 EXTENSION_FUNCTION_VALIDATE(
503 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( 548 PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref(
504 pref_key, &browser_pref, &permission)); 549 pref_key, &browser_pref, &permission));
505 if (!GetExtension()->HasAPIPermission(permission)) { 550 if (!HasAPIPermission(GetExtension(), permission)) {
506 error_ = ExtensionErrorUtils::FormatErrorMessage( 551 error_ = ExtensionErrorUtils::FormatErrorMessage(
507 keys::kPermissionErrorMessage, pref_key); 552 keys::kPermissionErrorMessage, pref_key);
508 return false; 553 return false;
509 } 554 }
555
556 if (IsReadOnlyPreference(browser_pref)) {
557 error_ = ExtensionErrorUtils::FormatErrorMessage(
558 keys::kCannotModifyReadOnlyMessage, pref_key);
559 return false;
560 }
561
510 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); 562 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs();
511 prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); 563 prefs->RemoveExtensionControlledPref(extension_id(), browser_pref, scope);
512 return true; 564 return true;
513 } 565 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698