Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / extensions / browser / extension_prefs.cc
blobe9b4a765facb73e3a9b1ca20767a5690a221f6dd
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/extension_prefs.h"
7 #include <iterator>
9 #include "base/command_line.h"
10 #include "base/prefs/pref_notifier.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "base/value_conversions.h"
15 #include "components/user_prefs/pref_registry_syncable.h"
16 #include "extensions/browser/admin_policy.h"
17 #include "extensions/browser/app_sorting.h"
18 #include "extensions/browser/event_router.h"
19 #include "extensions/browser/extension_pref_store.h"
20 #include "extensions/browser/extension_prefs_factory.h"
21 #include "extensions/browser/extension_prefs_observer.h"
22 #include "extensions/browser/pref_names.h"
23 #include "extensions/common/feature_switch.h"
24 #include "extensions/common/manifest.h"
25 #include "extensions/common/permissions/permission_set.h"
26 #include "extensions/common/permissions/permissions_info.h"
27 #include "extensions/common/url_pattern.h"
28 #include "extensions/common/user_script.h"
29 #include "ui/base/l10n/l10n_util.h"
31 using base::Value;
32 using base::DictionaryValue;
33 using base::ListValue;
35 namespace extensions {
37 namespace {
39 // Additional preferences keys, which are not needed by external clients.
41 // True if this extension is running. Note this preference stops getting updated
42 // during Chrome shutdown (and won't be updated on a browser crash) and so can
43 // be used at startup to determine whether the extension was running when Chrome
44 // was last terminated.
45 const char kPrefRunning[] = "running";
47 // Whether this extension had windows when it was last running.
48 const char kIsActive[] = "is_active";
50 // Where an extension was installed from. (see Manifest::Location)
51 const char kPrefLocation[] = "location";
53 // Enabled, disabled, killed, etc. (see Extension::State)
54 const char kPrefState[] = "state";
56 // The path to the current version's manifest file.
57 const char kPrefPath[] = "path";
59 // The dictionary containing the extension's manifest.
60 const char kPrefManifest[] = "manifest";
62 // The version number.
63 const char kPrefVersion[] = "manifest.version";
65 // Indicates whether an extension is blacklisted.
66 const char kPrefBlacklist[] = "blacklist";
68 // If extension is greylisted.
69 const char kPrefBlacklistState[] = "blacklist_state";
71 // The count of how many times we prompted the user to acknowledge an
72 // extension.
73 const char kPrefAcknowledgePromptCount[] = "ack_prompt_count";
75 // Indicates whether the user has acknowledged various types of extensions.
76 const char kPrefExternalAcknowledged[] = "ack_external";
77 const char kPrefBlacklistAcknowledged[] = "ack_blacklist";
78 const char kPrefWipeoutAcknowledged[] = "ack_wiped";
79 const char kPrefSettingsBubbleAcknowledged[] = "ack_settings_bubble";
80 const char kPrefNtpBubbleAcknowledged[] = "ack_ntp_bubble";
82 // Indicates whether the external extension was installed during the first
83 // run of this profile.
84 const char kPrefExternalInstallFirstRun[] = "external_first_run";
86 // Indicates whether to show an install warning when the user enables.
87 const char kExtensionDidEscalatePermissions[] = "install_warning_on_enable";
89 // DO NOT USE, use kPrefDisableReasons instead.
90 // Indicates whether the extension was updated while it was disabled.
91 const char kDeprecatedPrefDisableReason[] = "disable_reason";
93 // A bitmask of all the reasons an extension is disabled.
94 const char kPrefDisableReasons[] = "disable_reasons";
96 // The key for a serialized Time value indicating the start of the day (from the
97 // server's perspective) an extension last included a "ping" parameter during
98 // its update check.
99 const char kLastPingDay[] = "lastpingday";
101 // Similar to kLastPingDay, but for "active" instead of "rollcall" pings.
102 const char kLastActivePingDay[] = "last_active_pingday";
104 // A bit we use to keep track of whether we need to do an "active" ping.
105 const char kActiveBit[] = "active_bit";
107 // Path for settings specific to blacklist update.
108 const char kExtensionsBlacklistUpdate[] = "extensions.blacklistupdate";
110 // Path for the delayed install info dictionary preference. The actual string
111 // value is a legacy artifact for when delayed installs only pertained to
112 // updates that were waiting for idle.
113 const char kDelayedInstallInfo[] = "idle_install_info";
115 // Reason why the extension's install was delayed.
116 const char kDelayedInstallReason[] = "delay_install_reason";
118 // Path for the suggested page ordinal of a delayed extension install.
119 const char kPrefSuggestedPageOrdinal[] = "suggested_page_ordinal";
121 // A preference that, if true, will allow this extension to run in incognito
122 // mode.
123 const char kPrefIncognitoEnabled[] = "incognito";
125 // A preference to control whether an extension is allowed to inject script in
126 // pages with file URLs.
127 const char kPrefAllowFileAccess[] = "newAllowFileAccess";
128 // TODO(jstritar): As part of fixing http://crbug.com/91577, we revoked all
129 // extension file access by renaming the pref. We should eventually clean up
130 // the old flag and possibly go back to that name.
131 // const char kPrefAllowFileAccessOld[] = "allowFileAccess";
133 // A preference specifying if the user dragged the app on the NTP.
134 const char kPrefUserDraggedApp[] = "user_dragged_app_ntp";
136 // Preferences that hold which permissions the user has granted the extension.
137 // We explicitly keep track of these so that extensions can contain unknown
138 // permissions, for backwards compatibility reasons, and we can still prompt
139 // the user to accept them once recognized. We store the active permission
140 // permissions because they may differ from those defined in the manifest.
141 const char kPrefActivePermissions[] = "active_permissions";
142 const char kPrefGrantedPermissions[] = "granted_permissions";
144 // The preference names for PermissionSet values.
145 const char kPrefAPIs[] = "api";
146 const char kPrefManifestPermissions[] = "manifest_permissions";
147 const char kPrefExplicitHosts[] = "explicit_host";
148 const char kPrefScriptableHosts[] = "scriptable_host";
150 // The preference names for the old granted permissions scheme.
151 const char kPrefOldGrantedFullAccess[] = "granted_permissions.full";
152 const char kPrefOldGrantedHosts[] = "granted_permissions.host";
153 const char kPrefOldGrantedAPIs[] = "granted_permissions.api";
155 // A preference that indicates when an extension was installed.
156 const char kPrefInstallTime[] = "install_time";
158 // A preference which saves the creation flags for extensions.
159 const char kPrefCreationFlags[] = "creation_flags";
161 // A preference that indicates whether the extension was installed from the
162 // Chrome Web Store.
163 const char kPrefFromWebStore[] = "from_webstore";
165 // A preference that indicates whether the extension was installed from a
166 // mock App created from a bookmark.
167 const char kPrefFromBookmark[] = "from_bookmark";
169 // A preference that indicates whether the extension was installed as a
170 // default app.
171 const char kPrefWasInstalledByDefault[] = "was_installed_by_default";
173 // A preference that indicates whether the extension was installed as an
174 // OEM app.
175 const char kPrefWasInstalledByOem[] = "was_installed_by_oem";
177 // Key for Geometry Cache preference.
178 const char kPrefGeometryCache[] = "geometry_cache";
180 // A preference that indicates when an extension is last launched.
181 const char kPrefLastLaunchTime[] = "last_launch_time";
183 // A preference that marks an ephemeral app that was evicted from the cache.
184 // Their data is retained and garbage collected when inactive for a long period
185 // of time.
186 const char kPrefEvictedEphemeralApp[] = "evicted_ephemeral_app";
188 // Am installation parameter bundled with an extension.
189 const char kPrefInstallParam[] = "install_parameter";
191 // A list of installed ids and a signature.
192 const char kInstallSignature[] = "extensions.install_signature";
194 // A preference that stores the next threshold for displaying a notification
195 // when an extension or app consumes excessive disk space. This will not be
196 // set until the extension/app reaches the initial threshold.
197 const char kPrefNextStorageThreshold[] = "next_storage_threshold";
199 // If this preference is set to true, notifications will be suppressed when an
200 // extension or app consumes excessive disk space.
201 const char kPrefDisableStorageNotifications[] = "disable_storage_notifications";
203 // Provider of write access to a dictionary storing extension prefs.
204 class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate {
205 public:
206 ScopedExtensionPrefUpdate(PrefService* service,
207 const std::string& extension_id) :
208 DictionaryPrefUpdate(service, pref_names::kExtensions),
209 extension_id_(extension_id) {}
211 virtual ~ScopedExtensionPrefUpdate() {
214 // DictionaryPrefUpdate overrides:
215 virtual base::DictionaryValue* Get() OVERRIDE {
216 base::DictionaryValue* dict = DictionaryPrefUpdate::Get();
217 base::DictionaryValue* extension = NULL;
218 if (!dict->GetDictionary(extension_id_, &extension)) {
219 // Extension pref does not exist, create it.
220 extension = new base::DictionaryValue();
221 dict->SetWithoutPathExpansion(extension_id_, extension);
223 return extension;
226 private:
227 const std::string extension_id_;
229 DISALLOW_COPY_AND_ASSIGN(ScopedExtensionPrefUpdate);
232 std::string JoinPrefs(const std::string& parent, const char* child) {
233 return parent + "." + child;
236 // Checks if kPrefBlacklist is set to true in the base::DictionaryValue.
237 // Return false if the value is false or kPrefBlacklist does not exist.
238 // This is used to decide if an extension is blacklisted.
239 bool IsBlacklistBitSet(const base::DictionaryValue* ext) {
240 bool bool_value;
241 return ext->GetBoolean(kPrefBlacklist, &bool_value) && bool_value;
244 bool IsEvictedEphemeralApp(const base::DictionaryValue* ext) {
245 bool bool_value;
246 return ext->GetBoolean(kPrefEvictedEphemeralApp, &bool_value) && bool_value;
249 void LoadExtensionControlledPrefs(ExtensionPrefs* prefs,
250 ExtensionPrefValueMap* value_map,
251 const std::string& extension_id,
252 ExtensionPrefsScope scope) {
253 std::string scope_string;
254 if (!pref_names::ScopeToPrefName(scope, &scope_string))
255 return;
256 std::string key = extension_id + "." + scope_string;
258 const base::DictionaryValue* source_dict =
259 prefs->pref_service()->GetDictionary(pref_names::kExtensions);
260 const base::DictionaryValue* preferences = NULL;
261 if (!source_dict->GetDictionary(key, &preferences))
262 return;
264 for (base::DictionaryValue::Iterator iter(*preferences); !iter.IsAtEnd();
265 iter.Advance()) {
266 value_map->SetExtensionPref(
267 extension_id, iter.key(), scope, iter.value().DeepCopy());
271 } // namespace
274 // TimeProvider
277 ExtensionPrefs::TimeProvider::TimeProvider() {
280 ExtensionPrefs::TimeProvider::~TimeProvider() {
283 base::Time ExtensionPrefs::TimeProvider::GetCurrentTime() const {
284 return base::Time::Now();
288 // ScopedUpdate
290 template <typename T, base::Value::Type type_enum_value>
291 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::ScopedUpdate(
292 ExtensionPrefs* prefs,
293 const std::string& extension_id,
294 const std::string& key)
295 : update_(prefs->pref_service(), pref_names::kExtensions),
296 extension_id_(extension_id),
297 key_(key) {
298 DCHECK(Extension::IdIsValid(extension_id_));
301 template <typename T, base::Value::Type type_enum_value>
302 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::~ScopedUpdate() {
305 template <typename T, base::Value::Type type_enum_value>
306 T* ExtensionPrefs::ScopedUpdate<T, type_enum_value>::Get() {
307 base::DictionaryValue* dict = update_.Get();
308 base::DictionaryValue* extension = NULL;
309 base::Value* key_value = NULL;
310 if (!dict->GetDictionary(extension_id_, &extension) ||
311 !extension->Get(key_, &key_value)) {
312 return NULL;
314 return key_value->GetType() == type_enum_value ?
315 static_cast<T*>(key_value) :
316 NULL;
319 template <typename T, base::Value::Type type_enum_value>
320 T* ExtensionPrefs::ScopedUpdate<T, type_enum_value>::Create() {
321 base::DictionaryValue* dict = update_.Get();
322 base::DictionaryValue* extension = NULL;
323 base::Value* key_value = NULL;
324 T* value_as_t = NULL;
325 if (!dict->GetDictionary(extension_id_, &extension)) {
326 extension = new base::DictionaryValue;
327 dict->SetWithoutPathExpansion(extension_id_, extension);
329 if (!extension->Get(key_, &key_value)) {
330 value_as_t = new T;
331 extension->SetWithoutPathExpansion(key_, value_as_t);
332 } else {
333 CHECK(key_value->GetType() == type_enum_value);
334 value_as_t = static_cast<T*>(key_value);
336 return value_as_t;
339 // Explicit instantiations for Dictionary and List value types.
340 template class ExtensionPrefs::ScopedUpdate<base::DictionaryValue,
341 base::Value::TYPE_DICTIONARY>;
342 template class ExtensionPrefs::ScopedUpdate<base::ListValue,
343 base::Value::TYPE_LIST>;
346 // ExtensionPrefs
349 // static
350 ExtensionPrefs* ExtensionPrefs::Create(
351 PrefService* prefs,
352 const base::FilePath& root_dir,
353 ExtensionPrefValueMap* extension_pref_value_map,
354 scoped_ptr<AppSorting> app_sorting,
355 bool extensions_disabled,
356 const std::vector<ExtensionPrefsObserver*>& early_observers) {
357 return ExtensionPrefs::Create(prefs,
358 root_dir,
359 extension_pref_value_map,
360 app_sorting.Pass(),
361 extensions_disabled,
362 early_observers,
363 make_scoped_ptr(new TimeProvider()));
366 // static
367 ExtensionPrefs* ExtensionPrefs::Create(
368 PrefService* pref_service,
369 const base::FilePath& root_dir,
370 ExtensionPrefValueMap* extension_pref_value_map,
371 scoped_ptr<AppSorting> app_sorting,
372 bool extensions_disabled,
373 const std::vector<ExtensionPrefsObserver*>& early_observers,
374 scoped_ptr<TimeProvider> time_provider) {
375 return new ExtensionPrefs(pref_service,
376 root_dir,
377 extension_pref_value_map,
378 app_sorting.Pass(),
379 time_provider.Pass(),
380 extensions_disabled,
381 early_observers);
384 ExtensionPrefs::~ExtensionPrefs() {
387 // static
388 ExtensionPrefs* ExtensionPrefs::Get(content::BrowserContext* context) {
389 return ExtensionPrefsFactory::GetInstance()->GetForBrowserContext(context);
392 static base::FilePath::StringType MakePathRelative(const base::FilePath& parent,
393 const base::FilePath& child) {
394 if (!parent.IsParent(child))
395 return child.value();
397 base::FilePath::StringType retval = child.value().substr(
398 parent.value().length());
399 if (base::FilePath::IsSeparator(retval[0]))
400 return retval.substr(1);
401 else
402 return retval;
405 void ExtensionPrefs::MakePathsRelative() {
406 const base::DictionaryValue* dict =
407 prefs_->GetDictionary(pref_names::kExtensions);
408 if (!dict || dict->empty())
409 return;
411 // Collect all extensions ids with absolute paths in |absolute_keys|.
412 std::set<std::string> absolute_keys;
413 for (base::DictionaryValue::Iterator i(*dict); !i.IsAtEnd(); i.Advance()) {
414 const base::DictionaryValue* extension_dict = NULL;
415 if (!i.value().GetAsDictionary(&extension_dict))
416 continue;
417 int location_value;
418 if (extension_dict->GetInteger(kPrefLocation, &location_value) &&
419 Manifest::IsUnpackedLocation(
420 static_cast<Manifest::Location>(location_value))) {
421 // Unpacked extensions can have absolute paths.
422 continue;
424 base::FilePath::StringType path_string;
425 if (!extension_dict->GetString(kPrefPath, &path_string))
426 continue;
427 base::FilePath path(path_string);
428 if (path.IsAbsolute())
429 absolute_keys.insert(i.key());
431 if (absolute_keys.empty())
432 return;
434 // Fix these paths.
435 DictionaryPrefUpdate update(prefs_, pref_names::kExtensions);
436 base::DictionaryValue* update_dict = update.Get();
437 for (std::set<std::string>::iterator i = absolute_keys.begin();
438 i != absolute_keys.end(); ++i) {
439 base::DictionaryValue* extension_dict = NULL;
440 if (!update_dict->GetDictionaryWithoutPathExpansion(*i, &extension_dict)) {
441 NOTREACHED() << "Control should never reach here for extension " << *i;
442 continue;
444 base::FilePath::StringType path_string;
445 extension_dict->GetString(kPrefPath, &path_string);
446 base::FilePath path(path_string);
447 extension_dict->SetString(kPrefPath,
448 MakePathRelative(install_directory_, path));
452 const base::DictionaryValue* ExtensionPrefs::GetExtensionPref(
453 const std::string& extension_id) const {
454 const base::DictionaryValue* extensions =
455 prefs_->GetDictionary(pref_names::kExtensions);
456 const base::DictionaryValue* extension_dict = NULL;
457 if (!extensions ||
458 !extensions->GetDictionary(extension_id, &extension_dict)) {
459 return NULL;
461 return extension_dict;
464 void ExtensionPrefs::UpdateExtensionPref(const std::string& extension_id,
465 const std::string& key,
466 base::Value* data_value) {
467 if (!Extension::IdIsValid(extension_id)) {
468 NOTREACHED() << "Invalid extension_id " << extension_id;
469 return;
471 ScopedExtensionPrefUpdate update(prefs_, extension_id);
472 if (data_value)
473 update->Set(key, data_value);
474 else
475 update->Remove(key, NULL);
478 void ExtensionPrefs::DeleteExtensionPrefs(const std::string& extension_id) {
479 extension_pref_value_map_->UnregisterExtension(extension_id);
480 FOR_EACH_OBSERVER(ExtensionPrefsObserver,
481 observer_list_,
482 OnExtensionPrefsDeleted(extension_id));
483 DictionaryPrefUpdate update(prefs_, pref_names::kExtensions);
484 base::DictionaryValue* dict = update.Get();
485 dict->Remove(extension_id, NULL);
488 bool ExtensionPrefs::ReadPrefAsBoolean(const std::string& extension_id,
489 const std::string& pref_key,
490 bool* out_value) const {
491 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
492 if (!ext || !ext->GetBoolean(pref_key, out_value))
493 return false;
495 return true;
498 bool ExtensionPrefs::ReadPrefAsInteger(const std::string& extension_id,
499 const std::string& pref_key,
500 int* out_value) const {
501 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
502 if (!ext || !ext->GetInteger(pref_key, out_value))
503 return false;
505 return true;
508 bool ExtensionPrefs::ReadPrefAsString(const std::string& extension_id,
509 const std::string& pref_key,
510 std::string* out_value) const {
511 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
512 if (!ext || !ext->GetString(pref_key, out_value))
513 return false;
515 return true;
518 bool ExtensionPrefs::ReadPrefAsList(const std::string& extension_id,
519 const std::string& pref_key,
520 const base::ListValue** out_value) const {
521 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
522 const base::ListValue* out = NULL;
523 if (!ext || !ext->GetList(pref_key, &out))
524 return false;
525 if (out_value)
526 *out_value = out;
528 return true;
531 bool ExtensionPrefs::ReadPrefAsDictionary(
532 const std::string& extension_id,
533 const std::string& pref_key,
534 const base::DictionaryValue** out_value) const {
535 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
536 const base::DictionaryValue* out = NULL;
537 if (!ext || !ext->GetDictionary(pref_key, &out))
538 return false;
539 if (out_value)
540 *out_value = out;
542 return true;
545 bool ExtensionPrefs::HasPrefForExtension(
546 const std::string& extension_id) const {
547 return GetExtensionPref(extension_id) != NULL;
550 bool ExtensionPrefs::ReadPrefAsURLPatternSet(const std::string& extension_id,
551 const std::string& pref_key,
552 URLPatternSet* result,
553 int valid_schemes) {
554 const base::ListValue* value = NULL;
555 if (!ReadPrefAsList(extension_id, pref_key, &value))
556 return false;
558 bool allow_file_access = AllowFileAccess(extension_id);
559 return result->Populate(*value, valid_schemes, allow_file_access, NULL);
562 void ExtensionPrefs::SetExtensionPrefURLPatternSet(
563 const std::string& extension_id,
564 const std::string& pref_key,
565 const URLPatternSet& new_value) {
566 UpdateExtensionPref(extension_id, pref_key, new_value.ToValue().release());
569 bool ExtensionPrefs::ReadPrefAsBooleanAndReturn(
570 const std::string& extension_id,
571 const std::string& pref_key) const {
572 bool out_value = false;
573 return ReadPrefAsBoolean(extension_id, pref_key, &out_value) && out_value;
576 PermissionSet* ExtensionPrefs::ReadPrefAsPermissionSet(
577 const std::string& extension_id,
578 const std::string& pref_key) {
579 if (!GetExtensionPref(extension_id))
580 return NULL;
582 // Retrieve the API permissions. Please refer SetExtensionPrefPermissionSet()
583 // for api_values format.
584 APIPermissionSet apis;
585 const base::ListValue* api_values = NULL;
586 std::string api_pref = JoinPrefs(pref_key, kPrefAPIs);
587 if (ReadPrefAsList(extension_id, api_pref, &api_values)) {
588 APIPermissionSet::ParseFromJSON(api_values,
589 APIPermissionSet::kAllowInternalPermissions,
590 &apis, NULL, NULL);
593 // Retrieve the Manifest Keys permissions. Please refer to
594 // |SetExtensionPrefPermissionSet| for manifest_permissions_values format.
595 ManifestPermissionSet manifest_permissions;
596 const base::ListValue* manifest_permissions_values = NULL;
597 std::string manifest_permission_pref =
598 JoinPrefs(pref_key, kPrefManifestPermissions);
599 if (ReadPrefAsList(extension_id, manifest_permission_pref,
600 &manifest_permissions_values)) {
601 ManifestPermissionSet::ParseFromJSON(
602 manifest_permissions_values, &manifest_permissions, NULL, NULL);
605 // Retrieve the explicit host permissions.
606 URLPatternSet explicit_hosts;
607 ReadPrefAsURLPatternSet(
608 extension_id, JoinPrefs(pref_key, kPrefExplicitHosts),
609 &explicit_hosts, Extension::kValidHostPermissionSchemes);
611 // Retrieve the scriptable host permissions.
612 URLPatternSet scriptable_hosts;
613 ReadPrefAsURLPatternSet(
614 extension_id, JoinPrefs(pref_key, kPrefScriptableHosts),
615 &scriptable_hosts, UserScript::ValidUserScriptSchemes());
617 return new PermissionSet(
618 apis, manifest_permissions, explicit_hosts, scriptable_hosts);
621 // Set the API or Manifest permissions.
622 // The format of api_values is:
623 // [ "permission_name1", // permissions do not support detail.
624 // "permission_name2",
625 // {"permission_name3": value },
626 // // permission supports detail, permission detail will be stored in value.
627 // ...
628 // ]
629 template<typename T>
630 static base::ListValue* CreatePermissionList(const T& permissions) {
631 base::ListValue* values = new base::ListValue();
632 for (typename T::const_iterator i = permissions.begin();
633 i != permissions.end(); ++i) {
634 scoped_ptr<base::Value> detail(i->ToValue());
635 if (detail) {
636 base::DictionaryValue* tmp = new base::DictionaryValue();
637 tmp->Set(i->name(), detail.release());
638 values->Append(tmp);
639 } else {
640 values->Append(new base::StringValue(i->name()));
643 return values;
646 void ExtensionPrefs::SetExtensionPrefPermissionSet(
647 const std::string& extension_id,
648 const std::string& pref_key,
649 const PermissionSet* new_value) {
650 std::string api_pref = JoinPrefs(pref_key, kPrefAPIs);
651 base::ListValue* api_values = CreatePermissionList(new_value->apis());
652 UpdateExtensionPref(extension_id, api_pref, api_values);
654 std::string manifest_permissions_pref =
655 JoinPrefs(pref_key, kPrefManifestPermissions);
656 base::ListValue* manifest_permissions_values = CreatePermissionList(
657 new_value->manifest_permissions());
658 UpdateExtensionPref(extension_id,
659 manifest_permissions_pref,
660 manifest_permissions_values);
662 // Set the explicit host permissions.
663 if (!new_value->explicit_hosts().is_empty()) {
664 SetExtensionPrefURLPatternSet(extension_id,
665 JoinPrefs(pref_key, kPrefExplicitHosts),
666 new_value->explicit_hosts());
669 // Set the scriptable host permissions.
670 if (!new_value->scriptable_hosts().is_empty()) {
671 SetExtensionPrefURLPatternSet(extension_id,
672 JoinPrefs(pref_key, kPrefScriptableHosts),
673 new_value->scriptable_hosts());
677 int ExtensionPrefs::IncrementAcknowledgePromptCount(
678 const std::string& extension_id) {
679 int count = 0;
680 ReadPrefAsInteger(extension_id, kPrefAcknowledgePromptCount, &count);
681 ++count;
682 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount,
683 new base::FundamentalValue(count));
684 return count;
687 bool ExtensionPrefs::IsExternalExtensionAcknowledged(
688 const std::string& extension_id) {
689 return ReadPrefAsBooleanAndReturn(extension_id, kPrefExternalAcknowledged);
692 void ExtensionPrefs::AcknowledgeExternalExtension(
693 const std::string& extension_id) {
694 DCHECK(Extension::IdIsValid(extension_id));
695 UpdateExtensionPref(extension_id, kPrefExternalAcknowledged,
696 new base::FundamentalValue(true));
697 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, NULL);
700 bool ExtensionPrefs::IsBlacklistedExtensionAcknowledged(
701 const std::string& extension_id) {
702 return ReadPrefAsBooleanAndReturn(extension_id, kPrefBlacklistAcknowledged);
705 void ExtensionPrefs::AcknowledgeBlacklistedExtension(
706 const std::string& extension_id) {
707 DCHECK(Extension::IdIsValid(extension_id));
708 UpdateExtensionPref(extension_id, kPrefBlacklistAcknowledged,
709 new base::FundamentalValue(true));
710 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, NULL);
713 bool ExtensionPrefs::IsExternalInstallFirstRun(
714 const std::string& extension_id) {
715 return ReadPrefAsBooleanAndReturn(extension_id, kPrefExternalInstallFirstRun);
718 void ExtensionPrefs::SetExternalInstallFirstRun(
719 const std::string& extension_id) {
720 DCHECK(Extension::IdIsValid(extension_id));
721 UpdateExtensionPref(extension_id, kPrefExternalInstallFirstRun,
722 new base::FundamentalValue(true));
725 bool ExtensionPrefs::HasWipeoutBeenAcknowledged(
726 const std::string& extension_id) {
727 return ReadPrefAsBooleanAndReturn(extension_id, kPrefWipeoutAcknowledged);
730 void ExtensionPrefs::SetWipeoutAcknowledged(
731 const std::string& extension_id,
732 bool value) {
733 UpdateExtensionPref(extension_id, kPrefWipeoutAcknowledged,
734 value ? base::Value::CreateBooleanValue(value) : NULL);
737 bool ExtensionPrefs::HasSettingsApiBubbleBeenAcknowledged(
738 const std::string& extension_id) {
739 return ReadPrefAsBooleanAndReturn(extension_id,
740 kPrefSettingsBubbleAcknowledged);
743 void ExtensionPrefs::SetSettingsApiBubbleBeenAcknowledged(
744 const std::string& extension_id,
745 bool value) {
746 UpdateExtensionPref(extension_id,
747 kPrefSettingsBubbleAcknowledged,
748 value ? base::Value::CreateBooleanValue(value) : NULL);
751 bool ExtensionPrefs::HasNtpOverriddenBubbleBeenAcknowledged(
752 const std::string& extension_id) {
753 return ReadPrefAsBooleanAndReturn(extension_id, kPrefNtpBubbleAcknowledged);
756 void ExtensionPrefs::SetNtpOverriddenBubbleBeenAcknowledged(
757 const std::string& extension_id,
758 bool value) {
759 UpdateExtensionPref(extension_id,
760 kPrefNtpBubbleAcknowledged,
761 value ? base::Value::CreateBooleanValue(value) : NULL);
764 bool ExtensionPrefs::SetAlertSystemFirstRun() {
765 if (prefs_->GetBoolean(pref_names::kAlertsInitialized)) {
766 return true;
768 prefs_->SetBoolean(pref_names::kAlertsInitialized, true);
769 return false;
772 bool ExtensionPrefs::ExtensionsBlacklistedByDefault() const {
773 return admin_policy::BlacklistedByDefault(
774 prefs_->GetList(pref_names::kInstallDenyList));
777 bool ExtensionPrefs::DidExtensionEscalatePermissions(
778 const std::string& extension_id) {
779 return ReadPrefAsBooleanAndReturn(extension_id,
780 kExtensionDidEscalatePermissions);
783 void ExtensionPrefs::SetDidExtensionEscalatePermissions(
784 const Extension* extension, bool did_escalate) {
785 UpdateExtensionPref(extension->id(), kExtensionDidEscalatePermissions,
786 new base::FundamentalValue(did_escalate));
789 int ExtensionPrefs::GetDisableReasons(const std::string& extension_id) const {
790 int value = -1;
791 if (ReadPrefAsInteger(extension_id, kPrefDisableReasons, &value) &&
792 value >= 0) {
793 return value;
795 return Extension::DISABLE_NONE;
798 void ExtensionPrefs::AddDisableReason(const std::string& extension_id,
799 Extension::DisableReason disable_reason) {
800 ModifyDisableReason(extension_id, disable_reason, DISABLE_REASON_ADD);
803 void ExtensionPrefs::RemoveDisableReason(
804 const std::string& extension_id,
805 Extension::DisableReason disable_reason) {
806 ModifyDisableReason(extension_id, disable_reason, DISABLE_REASON_REMOVE);
809 void ExtensionPrefs::ClearDisableReasons(const std::string& extension_id) {
810 ModifyDisableReason(
811 extension_id, Extension::DISABLE_NONE, DISABLE_REASON_CLEAR);
814 void ExtensionPrefs::ModifyDisableReason(const std::string& extension_id,
815 Extension::DisableReason reason,
816 DisableReasonChange change) {
817 int old_value = GetDisableReasons(extension_id);
818 int new_value = old_value;
819 switch (change) {
820 case DISABLE_REASON_ADD:
821 new_value |= static_cast<int>(reason);
822 break;
823 case DISABLE_REASON_REMOVE:
824 new_value &= ~static_cast<int>(reason);
825 break;
826 case DISABLE_REASON_CLEAR:
827 new_value = Extension::DISABLE_NONE;
828 break;
831 if (old_value == new_value) // no change, return.
832 return;
834 if (new_value == Extension::DISABLE_NONE) {
835 UpdateExtensionPref(extension_id, kPrefDisableReasons, NULL);
836 } else {
837 UpdateExtensionPref(extension_id,
838 kPrefDisableReasons,
839 new base::FundamentalValue(new_value));
842 FOR_EACH_OBSERVER(ExtensionPrefsObserver,
843 observer_list_,
844 OnExtensionDisableReasonsChanged(extension_id, new_value));
847 std::set<std::string> ExtensionPrefs::GetBlacklistedExtensions() {
848 std::set<std::string> ids;
850 const base::DictionaryValue* extensions =
851 prefs_->GetDictionary(pref_names::kExtensions);
852 if (!extensions)
853 return ids;
855 for (base::DictionaryValue::Iterator it(*extensions);
856 !it.IsAtEnd(); it.Advance()) {
857 if (!it.value().IsType(base::Value::TYPE_DICTIONARY)) {
858 NOTREACHED() << "Invalid pref for extension " << it.key();
859 continue;
861 if (IsBlacklistBitSet(
862 static_cast<const base::DictionaryValue*>(&it.value()))) {
863 ids.insert(it.key());
867 return ids;
870 void ExtensionPrefs::SetExtensionBlacklisted(const std::string& extension_id,
871 bool is_blacklisted) {
872 bool currently_blacklisted = IsExtensionBlacklisted(extension_id);
873 if (is_blacklisted == currently_blacklisted)
874 return;
876 // Always make sure the "acknowledged" bit is cleared since the blacklist bit
877 // is changing.
878 UpdateExtensionPref(extension_id, kPrefBlacklistAcknowledged, NULL);
880 if (is_blacklisted) {
881 UpdateExtensionPref(extension_id,
882 kPrefBlacklist,
883 new base::FundamentalValue(true));
884 } else {
885 UpdateExtensionPref(extension_id, kPrefBlacklist, NULL);
886 const base::DictionaryValue* dict = GetExtensionPref(extension_id);
887 if (dict && dict->empty())
888 DeleteExtensionPrefs(extension_id);
892 bool ExtensionPrefs::IsExtensionBlacklisted(const std::string& id) const {
893 const base::DictionaryValue* ext_prefs = GetExtensionPref(id);
894 return ext_prefs && IsBlacklistBitSet(ext_prefs);
897 namespace {
899 // Serializes a 64bit integer as a string value.
900 void SaveInt64(base::DictionaryValue* dictionary,
901 const char* key,
902 const int64 value) {
903 if (!dictionary)
904 return;
906 std::string string_value = base::Int64ToString(value);
907 dictionary->SetString(key, string_value);
910 // Deserializes a 64bit integer stored as a string value.
911 bool ReadInt64(const base::DictionaryValue* dictionary,
912 const char* key,
913 int64* value) {
914 if (!dictionary)
915 return false;
917 std::string string_value;
918 if (!dictionary->GetString(key, &string_value))
919 return false;
921 return base::StringToInt64(string_value, value);
924 // Serializes |time| as a string value mapped to |key| in |dictionary|.
925 void SaveTime(base::DictionaryValue* dictionary,
926 const char* key,
927 const base::Time& time) {
928 SaveInt64(dictionary, key, time.ToInternalValue());
931 // The opposite of SaveTime. If |key| is not found, this returns an empty Time
932 // (is_null() will return true).
933 base::Time ReadTime(const base::DictionaryValue* dictionary, const char* key) {
934 int64 value;
935 if (ReadInt64(dictionary, key, &value))
936 return base::Time::FromInternalValue(value);
938 return base::Time();
941 } // namespace
943 base::Time ExtensionPrefs::LastPingDay(const std::string& extension_id) const {
944 DCHECK(Extension::IdIsValid(extension_id));
945 return ReadTime(GetExtensionPref(extension_id), kLastPingDay);
948 void ExtensionPrefs::SetLastPingDay(const std::string& extension_id,
949 const base::Time& time) {
950 DCHECK(Extension::IdIsValid(extension_id));
951 ScopedExtensionPrefUpdate update(prefs_, extension_id);
952 SaveTime(update.Get(), kLastPingDay, time);
955 base::Time ExtensionPrefs::BlacklistLastPingDay() const {
956 return ReadTime(prefs_->GetDictionary(kExtensionsBlacklistUpdate),
957 kLastPingDay);
960 void ExtensionPrefs::SetBlacklistLastPingDay(const base::Time& time) {
961 DictionaryPrefUpdate update(prefs_, kExtensionsBlacklistUpdate);
962 SaveTime(update.Get(), kLastPingDay, time);
965 base::Time ExtensionPrefs::LastActivePingDay(const std::string& extension_id) {
966 DCHECK(Extension::IdIsValid(extension_id));
967 return ReadTime(GetExtensionPref(extension_id), kLastActivePingDay);
970 void ExtensionPrefs::SetLastActivePingDay(const std::string& extension_id,
971 const base::Time& time) {
972 DCHECK(Extension::IdIsValid(extension_id));
973 ScopedExtensionPrefUpdate update(prefs_, extension_id);
974 SaveTime(update.Get(), kLastActivePingDay, time);
977 bool ExtensionPrefs::GetActiveBit(const std::string& extension_id) {
978 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
979 bool result = false;
980 if (dictionary && dictionary->GetBoolean(kActiveBit, &result))
981 return result;
982 return false;
985 void ExtensionPrefs::SetActiveBit(const std::string& extension_id,
986 bool active) {
987 UpdateExtensionPref(extension_id, kActiveBit,
988 new base::FundamentalValue(active));
991 void ExtensionPrefs::MigratePermissions(const ExtensionIdList& extension_ids) {
992 PermissionsInfo* info = PermissionsInfo::GetInstance();
993 for (ExtensionIdList::const_iterator ext_id =
994 extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) {
995 // An extension's granted permissions need to be migrated if the
996 // full_access bit is present. This bit was always present in the previous
997 // scheme and is never present now.
998 bool full_access;
999 const base::DictionaryValue* ext = GetExtensionPref(*ext_id);
1000 if (!ext || !ext->GetBoolean(kPrefOldGrantedFullAccess, &full_access))
1001 continue;
1003 // Remove the full access bit (empty list will get trimmed).
1004 UpdateExtensionPref(
1005 *ext_id, kPrefOldGrantedFullAccess, new base::ListValue());
1007 // Add the plugin permission if the full access bit was set.
1008 if (full_access) {
1009 const base::ListValue* apis = NULL;
1010 base::ListValue* new_apis = NULL;
1012 std::string granted_apis = JoinPrefs(kPrefGrantedPermissions, kPrefAPIs);
1013 if (ext->GetList(kPrefOldGrantedAPIs, &apis))
1014 new_apis = apis->DeepCopy();
1015 else
1016 new_apis = new base::ListValue();
1018 std::string plugin_name = info->GetByID(APIPermission::kPlugin)->name();
1019 new_apis->Append(new base::StringValue(plugin_name));
1020 UpdateExtensionPref(*ext_id, granted_apis, new_apis);
1023 // The granted permissions originally only held the effective hosts,
1024 // which are a combination of host and user script host permissions.
1025 // We now maintain these lists separately. For migration purposes, it
1026 // does not matter how we treat the old effective hosts as long as the
1027 // new effective hosts will be the same, so we move them to explicit
1028 // host permissions.
1029 const base::ListValue* hosts = NULL;
1030 std::string explicit_hosts =
1031 JoinPrefs(kPrefGrantedPermissions, kPrefExplicitHosts);
1032 if (ext->GetList(kPrefOldGrantedHosts, &hosts)) {
1033 UpdateExtensionPref(
1034 *ext_id, explicit_hosts, hosts->DeepCopy());
1036 // We can get rid of the old one by setting it to an empty list.
1037 UpdateExtensionPref(*ext_id, kPrefOldGrantedHosts, new base::ListValue());
1042 void ExtensionPrefs::MigrateDisableReasons(
1043 const ExtensionIdList& extension_ids) {
1044 for (ExtensionIdList::const_iterator ext_id =
1045 extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) {
1046 int value = -1;
1047 if (ReadPrefAsInteger(*ext_id, kDeprecatedPrefDisableReason, &value)) {
1048 int new_value = Extension::DISABLE_NONE;
1049 switch (value) {
1050 case Extension::DEPRECATED_DISABLE_USER_ACTION:
1051 new_value = Extension::DISABLE_USER_ACTION;
1052 break;
1053 case Extension::DEPRECATED_DISABLE_PERMISSIONS_INCREASE:
1054 new_value = Extension::DISABLE_PERMISSIONS_INCREASE;
1055 break;
1056 case Extension::DEPRECATED_DISABLE_RELOAD:
1057 new_value = Extension::DISABLE_RELOAD;
1058 break;
1061 UpdateExtensionPref(*ext_id, kPrefDisableReasons,
1062 new base::FundamentalValue(new_value));
1063 // Remove the old disable reason.
1064 UpdateExtensionPref(*ext_id, kDeprecatedPrefDisableReason, NULL);
1069 PermissionSet* ExtensionPrefs::GetGrantedPermissions(
1070 const std::string& extension_id) {
1071 CHECK(Extension::IdIsValid(extension_id));
1072 return ReadPrefAsPermissionSet(extension_id, kPrefGrantedPermissions);
1075 void ExtensionPrefs::AddGrantedPermissions(
1076 const std::string& extension_id,
1077 const PermissionSet* permissions) {
1078 CHECK(Extension::IdIsValid(extension_id));
1080 scoped_refptr<PermissionSet> granted_permissions(
1081 GetGrantedPermissions(extension_id));
1083 // The new granted permissions are the union of the already granted
1084 // permissions and the newly granted permissions.
1085 scoped_refptr<PermissionSet> new_perms(
1086 PermissionSet::CreateUnion(
1087 permissions, granted_permissions.get()));
1089 SetExtensionPrefPermissionSet(
1090 extension_id, kPrefGrantedPermissions, new_perms.get());
1093 void ExtensionPrefs::RemoveGrantedPermissions(
1094 const std::string& extension_id,
1095 const PermissionSet* permissions) {
1096 CHECK(Extension::IdIsValid(extension_id));
1098 scoped_refptr<PermissionSet> granted_permissions(
1099 GetGrantedPermissions(extension_id));
1101 // The new granted permissions are the difference of the already granted
1102 // permissions and the newly ungranted permissions.
1103 scoped_refptr<PermissionSet> new_perms(
1104 PermissionSet::CreateDifference(
1105 granted_permissions.get(), permissions));
1107 SetExtensionPrefPermissionSet(
1108 extension_id, kPrefGrantedPermissions, new_perms.get());
1111 PermissionSet* ExtensionPrefs::GetActivePermissions(
1112 const std::string& extension_id) {
1113 CHECK(Extension::IdIsValid(extension_id));
1114 return ReadPrefAsPermissionSet(extension_id, kPrefActivePermissions);
1117 void ExtensionPrefs::SetActivePermissions(
1118 const std::string& extension_id,
1119 const PermissionSet* permissions) {
1120 SetExtensionPrefPermissionSet(
1121 extension_id, kPrefActivePermissions, permissions);
1124 void ExtensionPrefs::SetExtensionRunning(const std::string& extension_id,
1125 bool is_running) {
1126 base::Value* value = new base::FundamentalValue(is_running);
1127 UpdateExtensionPref(extension_id, kPrefRunning, value);
1130 bool ExtensionPrefs::IsExtensionRunning(const std::string& extension_id) {
1131 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1132 if (!extension)
1133 return false;
1134 bool running = false;
1135 extension->GetBoolean(kPrefRunning, &running);
1136 return running;
1139 void ExtensionPrefs::SetIsActive(const std::string& extension_id,
1140 bool is_active) {
1141 base::Value* value = new base::FundamentalValue(is_active);
1142 UpdateExtensionPref(extension_id, kIsActive, value);
1145 bool ExtensionPrefs::IsActive(const std::string& extension_id) {
1146 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1147 if (!extension)
1148 return false;
1149 bool is_active = false;
1150 extension->GetBoolean(kIsActive, &is_active);
1151 return is_active;
1154 bool ExtensionPrefs::IsIncognitoEnabled(const std::string& extension_id) const {
1155 return ReadPrefAsBooleanAndReturn(extension_id, kPrefIncognitoEnabled);
1158 void ExtensionPrefs::SetIsIncognitoEnabled(const std::string& extension_id,
1159 bool enabled) {
1160 UpdateExtensionPref(extension_id, kPrefIncognitoEnabled,
1161 new base::FundamentalValue(enabled));
1162 extension_pref_value_map_->SetExtensionIncognitoState(extension_id, enabled);
1165 bool ExtensionPrefs::AllowFileAccess(const std::string& extension_id) const {
1166 return ReadPrefAsBooleanAndReturn(extension_id, kPrefAllowFileAccess);
1169 void ExtensionPrefs::SetAllowFileAccess(const std::string& extension_id,
1170 bool allow) {
1171 UpdateExtensionPref(extension_id, kPrefAllowFileAccess,
1172 new base::FundamentalValue(allow));
1175 bool ExtensionPrefs::HasAllowFileAccessSetting(
1176 const std::string& extension_id) const {
1177 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
1178 return ext && ext->HasKey(kPrefAllowFileAccess);
1181 bool ExtensionPrefs::DoesExtensionHaveState(
1182 const std::string& id, Extension::State check_state) const {
1183 const base::DictionaryValue* extension = GetExtensionPref(id);
1184 int state = -1;
1185 if (!extension || !extension->GetInteger(kPrefState, &state))
1186 return false;
1188 if (state < 0 || state >= Extension::NUM_STATES) {
1189 LOG(ERROR) << "Bad pref 'state' for extension '" << id << "'";
1190 return false;
1193 return state == check_state;
1196 bool ExtensionPrefs::IsExternalExtensionUninstalled(
1197 const std::string& id) const {
1198 return DoesExtensionHaveState(id, Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1201 bool ExtensionPrefs::IsExtensionDisabled(
1202 const std::string& id) const {
1203 return DoesExtensionHaveState(id, Extension::DISABLED);
1206 ExtensionIdList ExtensionPrefs::GetToolbarOrder() {
1207 ExtensionIdList id_list_out;
1208 GetUserExtensionPrefIntoContainer(pref_names::kToolbar, &id_list_out);
1209 return id_list_out;
1212 void ExtensionPrefs::SetToolbarOrder(const ExtensionIdList& extension_ids) {
1213 SetExtensionPrefFromContainer(pref_names::kToolbar, extension_ids);
1216 bool ExtensionPrefs::GetKnownDisabled(ExtensionIdSet* id_set_out) {
1217 return GetUserExtensionPrefIntoContainer(pref_names::kKnownDisabled,
1218 id_set_out);
1221 void ExtensionPrefs::SetKnownDisabled(const ExtensionIdSet& extension_ids) {
1222 SetExtensionPrefFromContainer(pref_names::kKnownDisabled, extension_ids);
1225 void ExtensionPrefs::OnExtensionInstalled(
1226 const Extension* extension,
1227 Extension::State initial_state,
1228 bool blacklisted_for_malware,
1229 const syncer::StringOrdinal& page_ordinal,
1230 const std::string& install_parameter) {
1231 ScopedExtensionPrefUpdate update(prefs_, extension->id());
1232 base::DictionaryValue* extension_dict = update.Get();
1233 const base::Time install_time = time_provider_->GetCurrentTime();
1234 PopulateExtensionInfoPrefs(extension,
1235 install_time,
1236 initial_state,
1237 blacklisted_for_malware,
1238 install_parameter,
1239 extension_dict);
1240 FinishExtensionInfoPrefs(extension->id(), install_time,
1241 extension->RequiresSortOrdinal(),
1242 page_ordinal, extension_dict);
1245 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
1246 const Manifest::Location& location,
1247 bool external_uninstall) {
1248 app_sorting_->ClearOrdinals(extension_id);
1250 // For external extensions, we save a preference reminding ourself not to try
1251 // and install the extension anymore (except when |external_uninstall| is
1252 // true, which signifies that the registry key was deleted or the pref file
1253 // no longer lists the extension).
1254 if (!external_uninstall && Manifest::IsExternalLocation(location)) {
1255 UpdateExtensionPref(extension_id, kPrefState,
1256 new base::FundamentalValue(
1257 Extension::EXTERNAL_EXTENSION_UNINSTALLED));
1258 extension_pref_value_map_->SetExtensionState(extension_id, false);
1259 FOR_EACH_OBSERVER(ExtensionPrefsObserver,
1260 observer_list_,
1261 OnExtensionStateChanged(extension_id, false));
1262 } else {
1263 int creation_flags = GetCreationFlags(extension_id);
1264 if (creation_flags & Extension::IS_EPHEMERAL) {
1265 // Keep ephemeral apps around, but mark them as evicted.
1266 UpdateExtensionPref(extension_id, kPrefEvictedEphemeralApp,
1267 new base::FundamentalValue(true));
1268 } else {
1269 DeleteExtensionPrefs(extension_id);
1274 void ExtensionPrefs::SetExtensionState(const std::string& extension_id,
1275 Extension::State state) {
1276 UpdateExtensionPref(extension_id, kPrefState,
1277 new base::FundamentalValue(state));
1278 bool enabled = (state == Extension::ENABLED);
1279 extension_pref_value_map_->SetExtensionState(extension_id, enabled);
1280 FOR_EACH_OBSERVER(ExtensionPrefsObserver,
1281 observer_list_,
1282 OnExtensionStateChanged(extension_id, enabled));
1285 void ExtensionPrefs::SetExtensionBlacklistState(const std::string& extension_id,
1286 BlacklistState state) {
1287 SetExtensionBlacklisted(extension_id, state == BLACKLISTED_MALWARE);
1288 UpdateExtensionPref(extension_id, kPrefBlacklistState,
1289 new base::FundamentalValue(state));
1292 BlacklistState ExtensionPrefs::GetExtensionBlacklistState(
1293 const std::string& extension_id) {
1294 if (IsExtensionBlacklisted(extension_id))
1295 return BLACKLISTED_MALWARE;
1296 const base::DictionaryValue* ext_prefs = GetExtensionPref(extension_id);
1297 int int_value;
1298 if (ext_prefs && ext_prefs->GetInteger(kPrefBlacklistState, &int_value))
1299 return static_cast<BlacklistState>(int_value);
1301 return NOT_BLACKLISTED;
1304 std::string ExtensionPrefs::GetVersionString(const std::string& extension_id) {
1305 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1306 if (!extension)
1307 return std::string();
1309 std::string version;
1310 extension->GetString(kPrefVersion, &version);
1312 return version;
1315 void ExtensionPrefs::UpdateManifest(const Extension* extension) {
1316 if (!Manifest::IsUnpackedLocation(extension->location())) {
1317 const base::DictionaryValue* extension_dict =
1318 GetExtensionPref(extension->id());
1319 if (!extension_dict)
1320 return;
1321 const base::DictionaryValue* old_manifest = NULL;
1322 bool update_required =
1323 !extension_dict->GetDictionary(kPrefManifest, &old_manifest) ||
1324 !extension->manifest()->value()->Equals(old_manifest);
1325 if (update_required) {
1326 UpdateExtensionPref(extension->id(), kPrefManifest,
1327 extension->manifest()->value()->DeepCopy());
1332 base::FilePath ExtensionPrefs::GetExtensionPath(
1333 const std::string& extension_id) {
1334 const base::DictionaryValue* dict = GetExtensionPref(extension_id);
1335 if (!dict)
1336 return base::FilePath();
1338 std::string path;
1339 if (!dict->GetString(kPrefPath, &path))
1340 return base::FilePath();
1342 return install_directory_.Append(base::FilePath::FromUTF8Unsafe(path));
1345 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledInfoHelper(
1346 const std::string& extension_id,
1347 const base::DictionaryValue* extension) const {
1348 int location_value;
1349 if (!extension->GetInteger(kPrefLocation, &location_value))
1350 return scoped_ptr<ExtensionInfo>();
1352 base::FilePath::StringType path;
1353 if (!extension->GetString(kPrefPath, &path))
1354 return scoped_ptr<ExtensionInfo>();
1356 // Make path absolute. Unpacked extensions will already have absolute paths,
1357 // otherwise make it so.
1358 Manifest::Location location = static_cast<Manifest::Location>(location_value);
1359 if (!Manifest::IsUnpackedLocation(location)) {
1360 DCHECK(location == Manifest::COMPONENT ||
1361 !base::FilePath(path).IsAbsolute());
1362 path = install_directory_.Append(path).value();
1365 // Only the following extension types have data saved in the preferences.
1366 if (location != Manifest::INTERNAL &&
1367 !Manifest::IsUnpackedLocation(location) &&
1368 !Manifest::IsExternalLocation(location)) {
1369 NOTREACHED();
1370 return scoped_ptr<ExtensionInfo>();
1373 const base::DictionaryValue* manifest = NULL;
1374 if (!Manifest::IsUnpackedLocation(location) &&
1375 !extension->GetDictionary(kPrefManifest, &manifest)) {
1376 LOG(WARNING) << "Missing manifest for extension " << extension_id;
1377 // Just a warning for now.
1380 return scoped_ptr<ExtensionInfo>(new ExtensionInfo(
1381 manifest, extension_id, base::FilePath(path), location));
1384 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledExtensionInfo(
1385 const std::string& extension_id) const {
1386 const base::DictionaryValue* ext = NULL;
1387 const base::DictionaryValue* extensions =
1388 prefs_->GetDictionary(pref_names::kExtensions);
1389 if (!extensions ||
1390 !extensions->GetDictionaryWithoutPathExpansion(extension_id, &ext))
1391 return scoped_ptr<ExtensionInfo>();
1392 int state_value;
1393 if (!ext->GetInteger(kPrefState, &state_value) ||
1394 state_value == Extension::ENABLED_COMPONENT) {
1395 // Old preferences files may not have kPrefState for component extensions.
1396 return scoped_ptr<ExtensionInfo>();
1399 if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) {
1400 LOG(WARNING) << "External extension with id " << extension_id
1401 << " has been uninstalled by the user";
1402 return scoped_ptr<ExtensionInfo>();
1405 if (IsEvictedEphemeralApp(ext)) {
1406 // Hide evicted ephemeral apps.
1407 return scoped_ptr<ExtensionInfo>();
1410 return GetInstalledInfoHelper(extension_id, ext);
1413 scoped_ptr<ExtensionPrefs::ExtensionsInfo>
1414 ExtensionPrefs::GetInstalledExtensionsInfo() const {
1415 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1417 const base::DictionaryValue* extensions =
1418 prefs_->GetDictionary(pref_names::kExtensions);
1419 for (base::DictionaryValue::Iterator extension_id(*extensions);
1420 !extension_id.IsAtEnd(); extension_id.Advance()) {
1421 if (!Extension::IdIsValid(extension_id.key()))
1422 continue;
1424 scoped_ptr<ExtensionInfo> info =
1425 GetInstalledExtensionInfo(extension_id.key());
1426 if (info)
1427 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1430 return extensions_info.Pass();
1433 scoped_ptr<ExtensionPrefs::ExtensionsInfo>
1434 ExtensionPrefs::GetUninstalledExtensionsInfo() const {
1435 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1437 const base::DictionaryValue* extensions =
1438 prefs_->GetDictionary(pref_names::kExtensions);
1439 for (base::DictionaryValue::Iterator extension_id(*extensions);
1440 !extension_id.IsAtEnd(); extension_id.Advance()) {
1441 const base::DictionaryValue* ext = NULL;
1442 if (!Extension::IdIsValid(extension_id.key()) ||
1443 !IsExternalExtensionUninstalled(extension_id.key()) ||
1444 !extension_id.value().GetAsDictionary(&ext))
1445 continue;
1447 scoped_ptr<ExtensionInfo> info =
1448 GetInstalledInfoHelper(extension_id.key(), ext);
1449 if (info)
1450 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1453 return extensions_info.Pass();
1456 void ExtensionPrefs::SetDelayedInstallInfo(
1457 const Extension* extension,
1458 Extension::State initial_state,
1459 bool blacklisted_for_malware,
1460 DelayReason delay_reason,
1461 const syncer::StringOrdinal& page_ordinal,
1462 const std::string& install_parameter) {
1463 base::DictionaryValue* extension_dict = new base::DictionaryValue();
1464 PopulateExtensionInfoPrefs(extension,
1465 time_provider_->GetCurrentTime(),
1466 initial_state,
1467 blacklisted_for_malware,
1468 install_parameter,
1469 extension_dict);
1471 // Add transient data that is needed by FinishDelayedInstallInfo(), but
1472 // should not be in the final extension prefs. All entries here should have
1473 // a corresponding Remove() call in FinishDelayedInstallInfo().
1474 if (extension->RequiresSortOrdinal()) {
1475 extension_dict->SetString(
1476 kPrefSuggestedPageOrdinal,
1477 page_ordinal.IsValid() ? page_ordinal.ToInternalValue()
1478 : std::string());
1480 extension_dict->SetInteger(kDelayedInstallReason,
1481 static_cast<int>(delay_reason));
1483 UpdateExtensionPref(extension->id(), kDelayedInstallInfo, extension_dict);
1486 bool ExtensionPrefs::RemoveDelayedInstallInfo(
1487 const std::string& extension_id) {
1488 if (!GetExtensionPref(extension_id))
1489 return false;
1490 ScopedExtensionPrefUpdate update(prefs_, extension_id);
1491 bool result = update->Remove(kDelayedInstallInfo, NULL);
1492 return result;
1495 bool ExtensionPrefs::FinishDelayedInstallInfo(
1496 const std::string& extension_id) {
1497 CHECK(Extension::IdIsValid(extension_id));
1498 ScopedExtensionPrefUpdate update(prefs_, extension_id);
1499 base::DictionaryValue* extension_dict = update.Get();
1500 base::DictionaryValue* pending_install_dict = NULL;
1501 if (!extension_dict->GetDictionary(kDelayedInstallInfo,
1502 &pending_install_dict)) {
1503 return false;
1506 // Retrieve and clear transient values populated by SetDelayedInstallInfo().
1507 // Also do any other data cleanup that makes sense.
1508 std::string serialized_ordinal;
1509 syncer::StringOrdinal suggested_page_ordinal;
1510 bool needs_sort_ordinal = false;
1511 if (pending_install_dict->GetString(kPrefSuggestedPageOrdinal,
1512 &serialized_ordinal)) {
1513 suggested_page_ordinal = syncer::StringOrdinal(serialized_ordinal);
1514 needs_sort_ordinal = true;
1515 pending_install_dict->Remove(kPrefSuggestedPageOrdinal, NULL);
1517 pending_install_dict->Remove(kDelayedInstallReason, NULL);
1519 const base::Time install_time = time_provider_->GetCurrentTime();
1520 pending_install_dict->Set(
1521 kPrefInstallTime,
1522 new base::StringValue(
1523 base::Int64ToString(install_time.ToInternalValue())));
1525 // Commit the delayed install data.
1526 for (base::DictionaryValue::Iterator it(*pending_install_dict); !it.IsAtEnd();
1527 it.Advance()) {
1528 extension_dict->Set(it.key(), it.value().DeepCopy());
1530 FinishExtensionInfoPrefs(extension_id, install_time, needs_sort_ordinal,
1531 suggested_page_ordinal, extension_dict);
1532 return true;
1535 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetDelayedInstallInfo(
1536 const std::string& extension_id) const {
1537 const base::DictionaryValue* extension_prefs =
1538 GetExtensionPref(extension_id);
1539 if (!extension_prefs)
1540 return scoped_ptr<ExtensionInfo>();
1542 const base::DictionaryValue* ext = NULL;
1543 if (!extension_prefs->GetDictionary(kDelayedInstallInfo, &ext))
1544 return scoped_ptr<ExtensionInfo>();
1546 return GetInstalledInfoHelper(extension_id, ext);
1549 ExtensionPrefs::DelayReason ExtensionPrefs::GetDelayedInstallReason(
1550 const std::string& extension_id) const {
1551 const base::DictionaryValue* extension_prefs =
1552 GetExtensionPref(extension_id);
1553 if (!extension_prefs)
1554 return DELAY_REASON_NONE;
1556 const base::DictionaryValue* ext = NULL;
1557 if (!extension_prefs->GetDictionary(kDelayedInstallInfo, &ext))
1558 return DELAY_REASON_NONE;
1560 int delay_reason;
1561 if (!ext->GetInteger(kDelayedInstallReason, &delay_reason))
1562 return DELAY_REASON_NONE;
1564 return static_cast<DelayReason>(delay_reason);
1567 scoped_ptr<ExtensionPrefs::ExtensionsInfo> ExtensionPrefs::
1568 GetAllDelayedInstallInfo() const {
1569 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1571 const base::DictionaryValue* extensions =
1572 prefs_->GetDictionary(pref_names::kExtensions);
1573 for (base::DictionaryValue::Iterator extension_id(*extensions);
1574 !extension_id.IsAtEnd(); extension_id.Advance()) {
1575 if (!Extension::IdIsValid(extension_id.key()))
1576 continue;
1578 scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key());
1579 if (info)
1580 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1583 return extensions_info.Pass();
1586 scoped_ptr<ExtensionPrefs::ExtensionsInfo>
1587 ExtensionPrefs::GetEvictedEphemeralAppsInfo() const {
1588 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1590 const base::DictionaryValue* extensions =
1591 prefs_->GetDictionary(pref_names::kExtensions);
1592 for (base::DictionaryValue::Iterator extension_id(*extensions);
1593 !extension_id.IsAtEnd(); extension_id.Advance()) {
1594 const base::DictionaryValue* ext = NULL;
1595 if (!Extension::IdIsValid(extension_id.key()) ||
1596 !extension_id.value().GetAsDictionary(&ext)) {
1597 continue;
1600 if (!IsEvictedEphemeralApp(ext))
1601 continue;
1603 scoped_ptr<ExtensionInfo> info =
1604 GetInstalledInfoHelper(extension_id.key(), ext);
1605 if (info)
1606 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1609 return extensions_info.Pass();
1612 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetEvictedEphemeralAppInfo(
1613 const std::string& extension_id) const {
1614 const base::DictionaryValue* extension_prefs = GetExtensionPref(extension_id);
1615 if (!extension_prefs)
1616 return scoped_ptr<ExtensionInfo>();
1618 if (!IsEvictedEphemeralApp(extension_prefs))
1619 return scoped_ptr<ExtensionInfo>();
1621 return GetInstalledInfoHelper(extension_id, extension_prefs);
1624 void ExtensionPrefs::RemoveEvictedEphemeralApp(
1625 const std::string& extension_id) {
1626 bool evicted_ephemeral_app = false;
1627 if (ReadPrefAsBoolean(extension_id,
1628 kPrefEvictedEphemeralApp,
1629 &evicted_ephemeral_app) && evicted_ephemeral_app) {
1630 DeleteExtensionPrefs(extension_id);
1634 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) {
1635 return ReadPrefAsBooleanAndReturn(extension_id, kPrefUserDraggedApp);
1638 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) {
1639 UpdateExtensionPref(extension_id, kPrefUserDraggedApp,
1640 new base::FundamentalValue(true));
1643 bool ExtensionPrefs::IsFromWebStore(
1644 const std::string& extension_id) const {
1645 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1646 bool result = false;
1647 if (dictionary && dictionary->GetBoolean(kPrefFromWebStore, &result))
1648 return result;
1649 return false;
1652 bool ExtensionPrefs::IsFromBookmark(
1653 const std::string& extension_id) const {
1654 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1655 bool result = false;
1656 if (dictionary && dictionary->GetBoolean(kPrefFromBookmark, &result))
1657 return result;
1658 return false;
1661 int ExtensionPrefs::GetCreationFlags(const std::string& extension_id) const {
1662 int creation_flags = Extension::NO_FLAGS;
1663 if (!ReadPrefAsInteger(extension_id, kPrefCreationFlags, &creation_flags)) {
1664 // Since kPrefCreationFlags was added later, it will be missing for
1665 // previously installed extensions.
1666 if (IsFromBookmark(extension_id))
1667 creation_flags |= Extension::FROM_BOOKMARK;
1668 if (IsFromWebStore(extension_id))
1669 creation_flags |= Extension::FROM_WEBSTORE;
1670 if (WasInstalledByDefault(extension_id))
1671 creation_flags |= Extension::WAS_INSTALLED_BY_DEFAULT;
1672 if (WasInstalledByOem(extension_id))
1673 creation_flags |= Extension::WAS_INSTALLED_BY_OEM;
1675 return creation_flags;
1678 int ExtensionPrefs::GetDelayedInstallCreationFlags(
1679 const std::string& extension_id) const {
1680 int creation_flags = Extension::NO_FLAGS;
1681 const base::DictionaryValue* delayed_info = NULL;
1682 if (ReadPrefAsDictionary(extension_id, kDelayedInstallInfo, &delayed_info)) {
1683 delayed_info->GetInteger(kPrefCreationFlags, &creation_flags);
1685 return creation_flags;
1688 bool ExtensionPrefs::WasInstalledByDefault(
1689 const std::string& extension_id) const {
1690 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1691 bool result = false;
1692 if (dictionary &&
1693 dictionary->GetBoolean(kPrefWasInstalledByDefault, &result))
1694 return result;
1695 return false;
1698 bool ExtensionPrefs::WasInstalledByOem(const std::string& extension_id) const {
1699 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1700 bool result = false;
1701 if (dictionary && dictionary->GetBoolean(kPrefWasInstalledByOem, &result))
1702 return result;
1703 return false;
1706 base::Time ExtensionPrefs::GetInstallTime(
1707 const std::string& extension_id) const {
1708 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1709 if (!extension) {
1710 NOTREACHED();
1711 return base::Time();
1713 std::string install_time_str;
1714 if (!extension->GetString(kPrefInstallTime, &install_time_str))
1715 return base::Time();
1716 int64 install_time_i64 = 0;
1717 if (!base::StringToInt64(install_time_str, &install_time_i64))
1718 return base::Time();
1719 return base::Time::FromInternalValue(install_time_i64);
1722 base::Time ExtensionPrefs::GetLastLaunchTime(
1723 const std::string& extension_id) const {
1724 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1725 if (!extension)
1726 return base::Time();
1728 std::string launch_time_str;
1729 if (!extension->GetString(kPrefLastLaunchTime, &launch_time_str))
1730 return base::Time();
1731 int64 launch_time_i64 = 0;
1732 if (!base::StringToInt64(launch_time_str, &launch_time_i64))
1733 return base::Time();
1734 return base::Time::FromInternalValue(launch_time_i64);
1737 void ExtensionPrefs::SetLastLaunchTime(const std::string& extension_id,
1738 const base::Time& time) {
1739 DCHECK(Extension::IdIsValid(extension_id));
1740 ScopedExtensionPrefUpdate update(prefs_, extension_id);
1741 SaveTime(update.Get(), kPrefLastLaunchTime, time);
1744 void ExtensionPrefs::GetExtensions(ExtensionIdList* out) {
1745 CHECK(out);
1747 scoped_ptr<ExtensionsInfo> extensions_info(GetInstalledExtensionsInfo());
1749 for (size_t i = 0; i < extensions_info->size(); ++i) {
1750 ExtensionInfo* info = extensions_info->at(i).get();
1751 out->push_back(info->extension_id);
1755 // static
1756 ExtensionIdList ExtensionPrefs::GetExtensionsFrom(
1757 const PrefService* pref_service) {
1758 ExtensionIdList result;
1760 const base::DictionaryValue* extension_prefs = NULL;
1761 const base::Value* extension_prefs_value =
1762 pref_service->GetUserPrefValue(pref_names::kExtensions);
1763 if (!extension_prefs_value ||
1764 !extension_prefs_value->GetAsDictionary(&extension_prefs)) {
1765 return result; // Empty set
1768 for (base::DictionaryValue::Iterator it(*extension_prefs); !it.IsAtEnd();
1769 it.Advance()) {
1770 const base::DictionaryValue* ext = NULL;
1771 if (!it.value().GetAsDictionary(&ext)) {
1772 NOTREACHED() << "Invalid pref for extension " << it.key();
1773 continue;
1775 if (!IsBlacklistBitSet(ext))
1776 result.push_back(it.key());
1778 return result;
1781 void ExtensionPrefs::AddObserver(ExtensionPrefsObserver* observer) {
1782 observer_list_.AddObserver(observer);
1785 void ExtensionPrefs::RemoveObserver(ExtensionPrefsObserver* observer) {
1786 observer_list_.RemoveObserver(observer);
1789 void ExtensionPrefs::FixMissingPrefs(const ExtensionIdList& extension_ids) {
1790 // Fix old entries that did not get an installation time entry when they
1791 // were installed or don't have a preferences field.
1792 for (ExtensionIdList::const_iterator ext_id = extension_ids.begin();
1793 ext_id != extension_ids.end(); ++ext_id) {
1794 if (GetInstallTime(*ext_id) == base::Time()) {
1795 VLOG(1) << "Could not parse installation time of extension "
1796 << *ext_id << ". It was probably installed before setting "
1797 << kPrefInstallTime << " was introduced. Updating "
1798 << kPrefInstallTime << " to the current time.";
1799 const base::Time install_time = time_provider_->GetCurrentTime();
1800 UpdateExtensionPref(*ext_id,
1801 kPrefInstallTime,
1802 new base::StringValue(base::Int64ToString(
1803 install_time.ToInternalValue())));
1808 void ExtensionPrefs::InitPrefStore() {
1809 if (extensions_disabled_) {
1810 extension_pref_value_map_->NotifyInitializationCompleted();
1811 return;
1814 // When this is called, the PrefService is initialized and provides access
1815 // to the user preferences stored in a JSON file.
1816 ExtensionIdList extension_ids;
1817 GetExtensions(&extension_ids);
1818 // Create empty preferences dictionary for each extension (these dictionaries
1819 // are pruned when persisting the preferences to disk).
1820 for (ExtensionIdList::iterator ext_id = extension_ids.begin();
1821 ext_id != extension_ids.end(); ++ext_id) {
1822 ScopedExtensionPrefUpdate update(prefs_, *ext_id);
1823 // This creates an empty dictionary if none is stored.
1824 update.Get();
1827 FixMissingPrefs(extension_ids);
1828 MigratePermissions(extension_ids);
1829 MigrateDisableReasons(extension_ids);
1830 app_sorting_->Initialize(extension_ids);
1832 InitExtensionControlledPrefs(extension_pref_value_map_);
1834 extension_pref_value_map_->NotifyInitializationCompleted();
1837 bool ExtensionPrefs::HasIncognitoPrefValue(const std::string& pref_key) {
1838 bool has_incognito_pref_value = false;
1839 extension_pref_value_map_->GetEffectivePrefValue(pref_key,
1840 true,
1841 &has_incognito_pref_value);
1842 return has_incognito_pref_value;
1845 URLPatternSet ExtensionPrefs::GetAllowedInstallSites() {
1846 URLPatternSet result;
1847 const base::ListValue* list =
1848 prefs_->GetList(pref_names::kAllowedInstallSites);
1849 CHECK(list);
1851 for (size_t i = 0; i < list->GetSize(); ++i) {
1852 std::string entry_string;
1853 URLPattern entry(URLPattern::SCHEME_ALL);
1854 if (!list->GetString(i, &entry_string) ||
1855 entry.Parse(entry_string) != URLPattern::PARSE_SUCCESS) {
1856 LOG(ERROR) << "Invalid value for preference: "
1857 << pref_names::kAllowedInstallSites << "." << i;
1858 continue;
1860 result.AddPattern(entry);
1863 return result;
1866 const base::DictionaryValue* ExtensionPrefs::GetGeometryCache(
1867 const std::string& extension_id) const {
1868 const base::DictionaryValue* extension_prefs = GetExtensionPref(extension_id);
1869 if (!extension_prefs)
1870 return NULL;
1872 const base::DictionaryValue* ext = NULL;
1873 if (!extension_prefs->GetDictionary(kPrefGeometryCache, &ext))
1874 return NULL;
1876 return ext;
1879 void ExtensionPrefs::SetGeometryCache(
1880 const std::string& extension_id,
1881 scoped_ptr<base::DictionaryValue> cache) {
1882 UpdateExtensionPref(extension_id, kPrefGeometryCache, cache.release());
1885 const base::DictionaryValue* ExtensionPrefs::GetInstallSignature() {
1886 return prefs_->GetDictionary(kInstallSignature);
1889 void ExtensionPrefs::SetInstallSignature(
1890 const base::DictionaryValue* signature) {
1891 if (signature) {
1892 prefs_->Set(kInstallSignature, *signature);
1893 DVLOG(1) << "SetInstallSignature - saving";
1894 } else {
1895 DVLOG(1) << "SetInstallSignature - clearing";
1896 prefs_->ClearPref(kInstallSignature);
1900 std::string ExtensionPrefs::GetInstallParam(
1901 const std::string& extension_id) const {
1902 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1903 if (!extension) // Expected during unit testing.
1904 return std::string();
1905 std::string install_parameter;
1906 if (!extension->GetString(kPrefInstallParam, &install_parameter))
1907 return std::string();
1908 return install_parameter;
1911 void ExtensionPrefs::SetInstallParam(const std::string& extension_id,
1912 const std::string& install_parameter) {
1913 UpdateExtensionPref(extension_id,
1914 kPrefInstallParam,
1915 new base::StringValue(install_parameter));
1918 int64 ExtensionPrefs::GetNextStorageThreshold(
1919 const std::string& extension_id) const {
1920 int64 next_threshold;
1921 if (ReadInt64(GetExtensionPref(extension_id),
1922 kPrefNextStorageThreshold,
1923 &next_threshold)) {
1924 return next_threshold;
1927 return 0;
1930 void ExtensionPrefs::SetNextStorageThreshold(const std::string& extension_id,
1931 int64 next_threshold) {
1932 ScopedExtensionPrefUpdate update(prefs_, extension_id);
1933 SaveInt64(update.Get(), kPrefNextStorageThreshold, next_threshold);
1936 bool ExtensionPrefs::IsStorageNotificationEnabled(
1937 const std::string& extension_id) const {
1938 bool disable_notifications;
1939 if (ReadPrefAsBoolean(extension_id,
1940 kPrefDisableStorageNotifications,
1941 &disable_notifications)) {
1942 return !disable_notifications;
1945 return true;
1948 void ExtensionPrefs::SetStorageNotificationEnabled(
1949 const std::string& extension_id, bool enable_notifications) {
1950 UpdateExtensionPref(
1951 extension_id,
1952 kPrefDisableStorageNotifications,
1953 enable_notifications ? NULL : new base::FundamentalValue(true));
1956 ExtensionPrefs::ExtensionPrefs(
1957 PrefService* prefs,
1958 const base::FilePath& root_dir,
1959 ExtensionPrefValueMap* extension_pref_value_map,
1960 scoped_ptr<AppSorting> app_sorting,
1961 scoped_ptr<TimeProvider> time_provider,
1962 bool extensions_disabled,
1963 const std::vector<ExtensionPrefsObserver*>& early_observers)
1964 : prefs_(prefs),
1965 install_directory_(root_dir),
1966 extension_pref_value_map_(extension_pref_value_map),
1967 app_sorting_(app_sorting.Pass()),
1968 time_provider_(time_provider.Pass()),
1969 extensions_disabled_(extensions_disabled) {
1970 app_sorting_->SetExtensionScopedPrefs(this);
1971 MakePathsRelative();
1973 // Ensure that any early observers are watching before prefs are initialized.
1974 for (std::vector<ExtensionPrefsObserver*>::const_iterator iter =
1975 early_observers.begin();
1976 iter != early_observers.end();
1977 ++iter) {
1978 AddObserver(*iter);
1981 InitPrefStore();
1984 void ExtensionPrefs::SetNeedsStorageGarbageCollection(bool value) {
1985 prefs_->SetBoolean(pref_names::kStorageGarbageCollect, value);
1988 bool ExtensionPrefs::NeedsStorageGarbageCollection() {
1989 return prefs_->GetBoolean(pref_names::kStorageGarbageCollect);
1992 // static
1993 void ExtensionPrefs::RegisterProfilePrefs(
1994 user_prefs::PrefRegistrySyncable* registry) {
1995 registry->RegisterDictionaryPref(
1996 pref_names::kExtensions,
1997 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1998 registry->RegisterListPref(pref_names::kToolbar,
1999 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
2000 registry->RegisterIntegerPref(
2001 pref_names::kToolbarSize,
2002 -1, // default value
2003 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2004 registry->RegisterDictionaryPref(
2005 kExtensionsBlacklistUpdate,
2006 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2007 registry->RegisterListPref(pref_names::kInstallAllowList,
2008 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2009 registry->RegisterListPref(pref_names::kInstallDenyList,
2010 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2011 registry->RegisterDictionaryPref(
2012 pref_names::kInstallForceList,
2013 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2014 registry->RegisterListPref(pref_names::kAllowedTypes,
2015 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2016 registry->RegisterBooleanPref(
2017 pref_names::kStorageGarbageCollect,
2018 false, // default value
2019 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2020 registry->RegisterInt64Pref(
2021 pref_names::kLastUpdateCheck,
2022 0, // default value
2023 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2024 registry->RegisterInt64Pref(
2025 pref_names::kNextUpdateCheck,
2026 0, // default value
2027 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2028 registry->RegisterListPref(pref_names::kAllowedInstallSites,
2029 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2030 registry->RegisterStringPref(
2031 pref_names::kLastChromeVersion,
2032 std::string(), // default value
2033 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2034 registry->RegisterListPref(pref_names::kKnownDisabled,
2035 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2036 #if defined(TOOLKIT_VIEWS)
2037 registry->RegisterIntegerPref(
2038 pref_names::kBrowserActionContainerWidth,
2040 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2041 #endif
2042 registry->RegisterDictionaryPref(
2043 kInstallSignature,
2044 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2046 registry->RegisterListPref(pref_names::kNativeMessagingBlacklist,
2047 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2048 registry->RegisterListPref(pref_names::kNativeMessagingWhitelist,
2049 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2050 registry->RegisterBooleanPref(
2051 pref_names::kNativeMessagingUserLevelHosts,
2052 true, // default value
2053 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2056 template <class ExtensionIdContainer>
2057 bool ExtensionPrefs::GetUserExtensionPrefIntoContainer(
2058 const char* pref,
2059 ExtensionIdContainer* id_container_out) {
2060 DCHECK(id_container_out->empty());
2062 const base::Value* user_pref_value = prefs_->GetUserPrefValue(pref);
2063 const base::ListValue* user_pref_as_list;
2064 if (!user_pref_value || !user_pref_value->GetAsList(&user_pref_as_list))
2065 return false;
2067 std::insert_iterator<ExtensionIdContainer> insert_iterator(
2068 *id_container_out, id_container_out->end());
2069 std::string extension_id;
2070 for (base::ListValue::const_iterator value_it = user_pref_as_list->begin();
2071 value_it != user_pref_as_list->end(); ++value_it) {
2072 if (!(*value_it)->GetAsString(&extension_id)) {
2073 NOTREACHED();
2074 continue;
2076 insert_iterator = extension_id;
2078 return true;
2081 template <class ExtensionIdContainer>
2082 void ExtensionPrefs::SetExtensionPrefFromContainer(
2083 const char* pref,
2084 const ExtensionIdContainer& strings) {
2085 ListPrefUpdate update(prefs_, pref);
2086 base::ListValue* list_of_values = update.Get();
2087 list_of_values->Clear();
2088 for (typename ExtensionIdContainer::const_iterator iter = strings.begin();
2089 iter != strings.end(); ++iter) {
2090 list_of_values->Append(new base::StringValue(*iter));
2094 void ExtensionPrefs::PopulateExtensionInfoPrefs(
2095 const Extension* extension,
2096 const base::Time install_time,
2097 Extension::State initial_state,
2098 bool blacklisted_for_malware,
2099 const std::string& install_parameter,
2100 base::DictionaryValue* extension_dict) {
2101 // Leave the state blank for component extensions so that old chrome versions
2102 // loading new profiles do not fail in GetInstalledExtensionInfo. Older
2103 // Chrome versions would only check for an omitted state.
2104 if (initial_state != Extension::ENABLED_COMPONENT)
2105 extension_dict->Set(kPrefState, new base::FundamentalValue(initial_state));
2107 extension_dict->Set(kPrefLocation,
2108 new base::FundamentalValue(extension->location()));
2109 extension_dict->Set(kPrefCreationFlags,
2110 new base::FundamentalValue(extension->creation_flags()));
2111 extension_dict->Set(kPrefFromWebStore,
2112 new base::FundamentalValue(extension->from_webstore()));
2113 extension_dict->Set(kPrefFromBookmark,
2114 new base::FundamentalValue(extension->from_bookmark()));
2115 extension_dict->Set(
2116 kPrefWasInstalledByDefault,
2117 new base::FundamentalValue(extension->was_installed_by_default()));
2118 extension_dict->Set(
2119 kPrefWasInstalledByOem,
2120 new base::FundamentalValue(extension->was_installed_by_oem()));
2121 extension_dict->Set(kPrefInstallTime,
2122 new base::StringValue(
2123 base::Int64ToString(install_time.ToInternalValue())));
2124 if (blacklisted_for_malware)
2125 extension_dict->Set(kPrefBlacklist, new base::FundamentalValue(true));
2127 base::FilePath::StringType path = MakePathRelative(install_directory_,
2128 extension->path());
2129 extension_dict->Set(kPrefPath, new base::StringValue(path));
2130 if (!install_parameter.empty()) {
2131 extension_dict->Set(kPrefInstallParam,
2132 new base::StringValue(install_parameter));
2134 // We store prefs about LOAD extensions, but don't cache their manifest
2135 // since it may change on disk.
2136 if (!Manifest::IsUnpackedLocation(extension->location())) {
2137 extension_dict->Set(kPrefManifest,
2138 extension->manifest()->value()->DeepCopy());
2142 void ExtensionPrefs::InitExtensionControlledPrefs(
2143 ExtensionPrefValueMap* value_map) {
2144 ExtensionIdList extension_ids;
2145 GetExtensions(&extension_ids);
2147 for (ExtensionIdList::iterator extension_id = extension_ids.begin();
2148 extension_id != extension_ids.end();
2149 ++extension_id) {
2150 base::Time install_time = GetInstallTime(*extension_id);
2151 bool is_enabled = !IsExtensionDisabled(*extension_id);
2152 bool is_incognito_enabled = IsIncognitoEnabled(*extension_id);
2153 value_map->RegisterExtension(
2154 *extension_id, install_time, is_enabled, is_incognito_enabled);
2156 FOR_EACH_OBSERVER(
2157 ExtensionPrefsObserver,
2158 observer_list_,
2159 OnExtensionRegistered(*extension_id, install_time, is_enabled));
2161 // Set regular extension controlled prefs.
2162 LoadExtensionControlledPrefs(
2163 this, value_map, *extension_id, kExtensionPrefsScopeRegular);
2164 // Set incognito extension controlled prefs.
2165 LoadExtensionControlledPrefs(this,
2166 value_map,
2167 *extension_id,
2168 kExtensionPrefsScopeIncognitoPersistent);
2169 // Set regular-only extension controlled prefs.
2170 LoadExtensionControlledPrefs(
2171 this, value_map, *extension_id, kExtensionPrefsScopeRegularOnly);
2173 FOR_EACH_OBSERVER(ExtensionPrefsObserver,
2174 observer_list_,
2175 OnExtensionPrefsLoaded(*extension_id, this));
2179 void ExtensionPrefs::FinishExtensionInfoPrefs(
2180 const std::string& extension_id,
2181 const base::Time install_time,
2182 bool needs_sort_ordinal,
2183 const syncer::StringOrdinal& suggested_page_ordinal,
2184 base::DictionaryValue* extension_dict) {
2185 // Reinitializes various preferences with empty dictionaries.
2186 if (!extension_dict->HasKey(pref_names::kPrefPreferences)) {
2187 extension_dict->Set(pref_names::kPrefPreferences,
2188 new base::DictionaryValue);
2191 if (!extension_dict->HasKey(pref_names::kPrefIncognitoPreferences)) {
2192 extension_dict->Set(pref_names::kPrefIncognitoPreferences,
2193 new base::DictionaryValue);
2196 if (!extension_dict->HasKey(pref_names::kPrefRegularOnlyPreferences)) {
2197 extension_dict->Set(pref_names::kPrefRegularOnlyPreferences,
2198 new base::DictionaryValue);
2201 if (!extension_dict->HasKey(pref_names::kPrefContentSettings))
2202 extension_dict->Set(pref_names::kPrefContentSettings, new base::ListValue);
2204 if (!extension_dict->HasKey(pref_names::kPrefIncognitoContentSettings)) {
2205 extension_dict->Set(pref_names::kPrefIncognitoContentSettings,
2206 new base::ListValue);
2209 // If this point has been reached, any pending installs should be considered
2210 // out of date.
2211 extension_dict->Remove(kDelayedInstallInfo, NULL);
2213 // Clear state that may be registered from a previous install.
2214 extension_dict->Remove(EventRouter::kRegisteredEvents, NULL);
2216 // When evicted ephemeral apps are re-installed, this flag must be reset.
2217 extension_dict->Remove(kPrefEvictedEphemeralApp, NULL);
2219 // FYI, all code below here races on sudden shutdown because |extension_dict|,
2220 // |app_sorting_|, |extension_pref_value_map_|, and (potentially) observers
2221 // are updated non-transactionally. This is probably not fixable without
2222 // nested transactional updates to pref dictionaries.
2223 if (needs_sort_ordinal)
2224 app_sorting_->EnsureValidOrdinals(extension_id, suggested_page_ordinal);
2226 bool is_enabled = false;
2227 int initial_state;
2228 if (extension_dict->GetInteger(kPrefState, &initial_state)) {
2229 is_enabled = initial_state == Extension::ENABLED;
2231 bool is_incognito_enabled = IsIncognitoEnabled(extension_id);
2233 extension_pref_value_map_->RegisterExtension(
2234 extension_id, install_time, is_enabled, is_incognito_enabled);
2236 FOR_EACH_OBSERVER(
2237 ExtensionPrefsObserver,
2238 observer_list_,
2239 OnExtensionRegistered(extension_id, install_time, is_enabled));
2242 } // namespace extensions