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"
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 "chrome/browser/extensions/api/content_settings/content_settings_store.h"
16 #include "components/user_prefs/pref_registry_syncable.h"
17 #include "extensions/browser/admin_policy.h"
18 #include "extensions/browser/app_sorting.h"
19 #include "extensions/browser/event_router.h"
20 #include "extensions/browser/extension_pref_store.h"
21 #include "extensions/browser/extension_prefs_factory.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"
32 using base::DictionaryValue;
33 using base::ListValue;
35 namespace extensions {
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
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";
81 // Indicates whether the external extension was installed during the first
82 // run of this profile.
83 const char kPrefExternalInstallFirstRun[] = "external_first_run";
85 // Indicates whether to show an install warning when the user enables.
86 const char kExtensionDidEscalatePermissions[] = "install_warning_on_enable";
88 // DO NOT USE, use kPrefDisableReasons instead.
89 // Indicates whether the extension was updated while it was disabled.
90 const char kDeprecatedPrefDisableReason[] = "disable_reason";
92 // A bitmask of all the reasons an extension is disabled.
93 const char kPrefDisableReasons[] = "disable_reasons";
95 // The key for a serialized Time value indicating the start of the day (from the
96 // server's perspective) an extension last included a "ping" parameter during
98 const char kLastPingDay[] = "lastpingday";
100 // Similar to kLastPingDay, but for "active" instead of "rollcall" pings.
101 const char kLastActivePingDay[] = "last_active_pingday";
103 // A bit we use to keep track of whether we need to do an "active" ping.
104 const char kActiveBit[] = "active_bit";
106 // Path for settings specific to blacklist update.
107 const char kExtensionsBlacklistUpdate[] = "extensions.blacklistupdate";
109 // Path for the delayed install info dictionary preference. The actual string
110 // value is a legacy artifact for when delayed installs only pertained to
111 // updates that were waiting for idle.
112 const char kDelayedInstallInfo[] = "idle_install_info";
114 // Reason why the extension's install was delayed.
115 const char kDelayedInstallReason[] = "delay_install_reason";
117 // Path for the suggested page ordinal of a delayed extension install.
118 const char kPrefSuggestedPageOrdinal[] = "suggested_page_ordinal";
120 // A preference that, if true, will allow this extension to run in incognito
122 const char kPrefIncognitoEnabled[] = "incognito";
124 // A preference to control whether an extension is allowed to inject script in
125 // pages with file URLs.
126 const char kPrefAllowFileAccess[] = "newAllowFileAccess";
127 // TODO(jstritar): As part of fixing http://crbug.com/91577, we revoked all
128 // extension file access by renaming the pref. We should eventually clean up
129 // the old flag and possibly go back to that name.
130 // const char kPrefAllowFileAccessOld[] = "allowFileAccess";
132 // A preference specifying if the user dragged the app on the NTP.
133 const char kPrefUserDraggedApp[] = "user_dragged_app_ntp";
135 // Preferences that hold which permissions the user has granted the extension.
136 // We explicitly keep track of these so that extensions can contain unknown
137 // permissions, for backwards compatibility reasons, and we can still prompt
138 // the user to accept them once recognized. We store the active permission
139 // permissions because they may differ from those defined in the manifest.
140 const char kPrefActivePermissions[] = "active_permissions";
141 const char kPrefGrantedPermissions[] = "granted_permissions";
143 // The preference names for PermissionSet values.
144 const char kPrefAPIs[] = "api";
145 const char kPrefManifestPermissions[] = "manifest_permissions";
146 const char kPrefExplicitHosts[] = "explicit_host";
147 const char kPrefScriptableHosts[] = "scriptable_host";
149 // The preference names for the old granted permissions scheme.
150 const char kPrefOldGrantedFullAccess[] = "granted_permissions.full";
151 const char kPrefOldGrantedHosts[] = "granted_permissions.host";
152 const char kPrefOldGrantedAPIs[] = "granted_permissions.api";
154 // A preference that indicates when an extension was installed.
155 const char kPrefInstallTime[] = "install_time";
157 // A preference which saves the creation flags for extensions.
158 const char kPrefCreationFlags[] = "creation_flags";
160 // A preference that indicates whether the extension was installed from the
162 const char kPrefFromWebStore[] = "from_webstore";
164 // A preference that indicates whether the extension was installed from a
165 // mock App created from a bookmark.
166 const char kPrefFromBookmark[] = "from_bookmark";
168 // A preference that indicates whether the extension was installed as a
170 const char kPrefWasInstalledByDefault[] = "was_installed_by_default";
172 // A preference that indicates whether the extension was installed as an
174 const char kPrefWasInstalledByOem[] = "was_installed_by_oem";
176 // Key for Geometry Cache preference.
177 const char kPrefGeometryCache[] = "geometry_cache";
179 // A preference that indicates when an extension is last launched.
180 const char kPrefLastLaunchTime[] = "last_launch_time";
182 // A preference that marks an ephemeral app that was evicted from the cache.
183 // Their data is retained and garbage collected when inactive for a long period
185 const char kPrefEvictedEphemeralApp[] = "evicted_ephemeral_app";
187 // Am installation parameter bundled with an extension.
188 const char kPrefInstallParam[] = "install_parameter";
190 // A list of installed ids and a signature.
191 const char kInstallSignature[] = "extensions.install_signature";
193 // Provider of write access to a dictionary storing extension prefs.
194 class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate {
196 ScopedExtensionPrefUpdate(PrefService* service,
197 const std::string& extension_id) :
198 DictionaryPrefUpdate(service, pref_names::kExtensions),
199 extension_id_(extension_id) {}
201 virtual ~ScopedExtensionPrefUpdate() {
204 // DictionaryPrefUpdate overrides:
205 virtual base::DictionaryValue* Get() OVERRIDE {
206 base::DictionaryValue* dict = DictionaryPrefUpdate::Get();
207 base::DictionaryValue* extension = NULL;
208 if (!dict->GetDictionary(extension_id_, &extension)) {
209 // Extension pref does not exist, create it.
210 extension = new base::DictionaryValue();
211 dict->SetWithoutPathExpansion(extension_id_, extension);
217 const std::string extension_id_;
219 DISALLOW_COPY_AND_ASSIGN(ScopedExtensionPrefUpdate);
222 std::string JoinPrefs(const std::string& parent, const char* child) {
223 return parent + "." + child;
226 // Checks if kPrefBlacklist is set to true in the base::DictionaryValue.
227 // Return false if the value is false or kPrefBlacklist does not exist.
228 // This is used to decide if an extension is blacklisted.
229 bool IsBlacklistBitSet(const base::DictionaryValue* ext) {
231 return ext->GetBoolean(kPrefBlacklist, &bool_value) && bool_value;
234 bool IsEvictedEphemeralApp(const base::DictionaryValue* ext) {
236 return ext->GetBoolean(kPrefEvictedEphemeralApp, &bool_value) && bool_value;
239 void LoadExtensionControlledPrefs(ExtensionPrefs* prefs,
240 ExtensionPrefValueMap* value_map,
241 const std::string& extension_id,
242 ExtensionPrefsScope scope) {
243 std::string scope_string;
244 if (!pref_names::ScopeToPrefName(scope, &scope_string))
246 std::string key = extension_id + "." + scope_string;
248 const base::DictionaryValue* source_dict =
249 prefs->pref_service()->GetDictionary(pref_names::kExtensions);
250 const base::DictionaryValue* preferences = NULL;
251 if (!source_dict->GetDictionary(key, &preferences))
254 for (base::DictionaryValue::Iterator iter(*preferences); !iter.IsAtEnd();
256 value_map->SetExtensionPref(
257 extension_id, iter.key(), scope, iter.value().DeepCopy());
261 void InitExtensionControlledPrefs(ExtensionPrefs* prefs,
262 ExtensionPrefValueMap* value_map) {
263 ExtensionIdList extension_ids;
264 prefs->GetExtensions(&extension_ids);
266 for (ExtensionIdList::iterator extension_id = extension_ids.begin();
267 extension_id != extension_ids.end();
269 base::Time install_time = prefs->GetInstallTime(*extension_id);
270 bool is_enabled = !prefs->IsExtensionDisabled(*extension_id);
271 bool is_incognito_enabled = prefs->IsIncognitoEnabled(*extension_id);
272 value_map->RegisterExtension(
273 *extension_id, install_time, is_enabled, is_incognito_enabled);
274 prefs->content_settings_store()->RegisterExtension(
275 *extension_id, install_time, is_enabled);
277 // Set regular extension controlled prefs.
278 LoadExtensionControlledPrefs(
279 prefs, value_map, *extension_id, kExtensionPrefsScopeRegular);
280 // Set incognito extension controlled prefs.
281 LoadExtensionControlledPrefs(prefs,
284 kExtensionPrefsScopeIncognitoPersistent);
285 // Set regular-only extension controlled prefs.
286 LoadExtensionControlledPrefs(
287 prefs, value_map, *extension_id, kExtensionPrefsScopeRegularOnly);
289 // Set content settings.
290 const base::ListValue* content_settings = NULL;
291 if (prefs->ReadPrefAsList(*extension_id,
292 pref_names::kPrefContentSettings,
293 &content_settings)) {
294 prefs->content_settings_store()->SetExtensionContentSettingFromList(
295 *extension_id, content_settings, kExtensionPrefsScopeRegular);
297 if (prefs->ReadPrefAsList(*extension_id,
298 pref_names::kPrefIncognitoContentSettings,
299 &content_settings)) {
300 prefs->content_settings_store()->SetExtensionContentSettingFromList(
303 kExtensionPrefsScopeIncognitoPersistent);
314 ExtensionPrefs::TimeProvider::TimeProvider() {
317 ExtensionPrefs::TimeProvider::~TimeProvider() {
320 base::Time ExtensionPrefs::TimeProvider::GetCurrentTime() const {
321 return base::Time::Now();
327 template <typename T, base::Value::Type type_enum_value>
328 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::ScopedUpdate(
329 ExtensionPrefs* prefs,
330 const std::string& extension_id,
331 const std::string& key)
332 : update_(prefs->pref_service(), pref_names::kExtensions),
333 extension_id_(extension_id),
335 DCHECK(Extension::IdIsValid(extension_id_));
338 template <typename T, base::Value::Type type_enum_value>
339 ExtensionPrefs::ScopedUpdate<T, type_enum_value>::~ScopedUpdate() {
342 template <typename T, base::Value::Type type_enum_value>
343 T* ExtensionPrefs::ScopedUpdate<T, type_enum_value>::Get() {
344 base::DictionaryValue* dict = update_.Get();
345 base::DictionaryValue* extension = NULL;
346 base::Value* key_value = NULL;
347 if (!dict->GetDictionary(extension_id_, &extension) ||
348 !extension->Get(key_, &key_value)) {
351 return key_value->GetType() == type_enum_value ?
352 static_cast<T*>(key_value) :
356 template <typename T, base::Value::Type type_enum_value>
357 T* ExtensionPrefs::ScopedUpdate<T, type_enum_value>::Create() {
358 base::DictionaryValue* dict = update_.Get();
359 base::DictionaryValue* extension = NULL;
360 base::Value* key_value = NULL;
361 T* value_as_t = NULL;
362 if (!dict->GetDictionary(extension_id_, &extension)) {
363 extension = new base::DictionaryValue;
364 dict->SetWithoutPathExpansion(extension_id_, extension);
366 if (!extension->Get(key_, &key_value)) {
368 extension->SetWithoutPathExpansion(key_, value_as_t);
370 CHECK(key_value->GetType() == type_enum_value);
371 value_as_t = static_cast<T*>(key_value);
376 // Explicit instantiations for Dictionary and List value types.
377 template class ExtensionPrefs::ScopedUpdate<base::DictionaryValue,
378 base::Value::TYPE_DICTIONARY>;
379 template class ExtensionPrefs::ScopedUpdate<base::ListValue,
380 base::Value::TYPE_LIST>;
387 ExtensionPrefs* ExtensionPrefs::Create(
389 const base::FilePath& root_dir,
390 ExtensionPrefValueMap* extension_pref_value_map,
391 scoped_ptr<AppSorting> app_sorting,
392 bool extensions_disabled) {
393 return ExtensionPrefs::Create(prefs,
395 extension_pref_value_map,
398 make_scoped_ptr(new TimeProvider()));
402 ExtensionPrefs* ExtensionPrefs::Create(
403 PrefService* pref_service,
404 const base::FilePath& root_dir,
405 ExtensionPrefValueMap* extension_pref_value_map,
406 scoped_ptr<AppSorting> app_sorting,
407 bool extensions_disabled,
408 scoped_ptr<TimeProvider> time_provider) {
409 return new ExtensionPrefs(pref_service,
411 extension_pref_value_map,
413 time_provider.Pass(),
414 extensions_disabled);
417 ExtensionPrefs::~ExtensionPrefs() {
421 ExtensionPrefs* ExtensionPrefs::Get(content::BrowserContext* context) {
422 return ExtensionPrefsFactory::GetInstance()->GetForBrowserContext(context);
425 static base::FilePath::StringType MakePathRelative(const base::FilePath& parent,
426 const base::FilePath& child) {
427 if (!parent.IsParent(child))
428 return child.value();
430 base::FilePath::StringType retval = child.value().substr(
431 parent.value().length());
432 if (base::FilePath::IsSeparator(retval[0]))
433 return retval.substr(1);
438 void ExtensionPrefs::MakePathsRelative() {
439 const base::DictionaryValue* dict =
440 prefs_->GetDictionary(pref_names::kExtensions);
441 if (!dict || dict->empty())
444 // Collect all extensions ids with absolute paths in |absolute_keys|.
445 std::set<std::string> absolute_keys;
446 for (base::DictionaryValue::Iterator i(*dict); !i.IsAtEnd(); i.Advance()) {
447 const base::DictionaryValue* extension_dict = NULL;
448 if (!i.value().GetAsDictionary(&extension_dict))
451 if (extension_dict->GetInteger(kPrefLocation, &location_value) &&
452 Manifest::IsUnpackedLocation(
453 static_cast<Manifest::Location>(location_value))) {
454 // Unpacked extensions can have absolute paths.
457 base::FilePath::StringType path_string;
458 if (!extension_dict->GetString(kPrefPath, &path_string))
460 base::FilePath path(path_string);
461 if (path.IsAbsolute())
462 absolute_keys.insert(i.key());
464 if (absolute_keys.empty())
468 DictionaryPrefUpdate update(prefs_, pref_names::kExtensions);
469 base::DictionaryValue* update_dict = update.Get();
470 for (std::set<std::string>::iterator i = absolute_keys.begin();
471 i != absolute_keys.end(); ++i) {
472 base::DictionaryValue* extension_dict = NULL;
473 if (!update_dict->GetDictionaryWithoutPathExpansion(*i, &extension_dict)) {
474 NOTREACHED() << "Control should never reach here for extension " << *i;
477 base::FilePath::StringType path_string;
478 extension_dict->GetString(kPrefPath, &path_string);
479 base::FilePath path(path_string);
480 extension_dict->SetString(kPrefPath,
481 MakePathRelative(install_directory_, path));
485 const base::DictionaryValue* ExtensionPrefs::GetExtensionPref(
486 const std::string& extension_id) const {
487 const base::DictionaryValue* extensions =
488 prefs_->GetDictionary(pref_names::kExtensions);
489 const base::DictionaryValue* extension_dict = NULL;
491 !extensions->GetDictionary(extension_id, &extension_dict)) {
494 return extension_dict;
497 void ExtensionPrefs::UpdateExtensionPref(const std::string& extension_id,
498 const std::string& key,
499 base::Value* data_value) {
500 if (!Extension::IdIsValid(extension_id)) {
501 NOTREACHED() << "Invalid extension_id " << extension_id;
504 ScopedExtensionPrefUpdate update(prefs_, extension_id);
506 update->Set(key, data_value);
508 update->Remove(key, NULL);
511 void ExtensionPrefs::DeleteExtensionPrefs(const std::string& extension_id) {
512 extension_pref_value_map_->UnregisterExtension(extension_id);
513 content_settings_store_->UnregisterExtension(extension_id);
514 DictionaryPrefUpdate update(prefs_, pref_names::kExtensions);
515 base::DictionaryValue* dict = update.Get();
516 dict->Remove(extension_id, NULL);
519 bool ExtensionPrefs::ReadPrefAsBoolean(const std::string& extension_id,
520 const std::string& pref_key,
521 bool* out_value) const {
522 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
523 if (!ext || !ext->GetBoolean(pref_key, out_value))
529 bool ExtensionPrefs::ReadPrefAsInteger(const std::string& extension_id,
530 const std::string& pref_key,
531 int* out_value) const {
532 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
533 if (!ext || !ext->GetInteger(pref_key, out_value))
539 bool ExtensionPrefs::ReadPrefAsString(const std::string& extension_id,
540 const std::string& pref_key,
541 std::string* out_value) const {
542 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
543 if (!ext || !ext->GetString(pref_key, out_value))
549 bool ExtensionPrefs::ReadPrefAsList(const std::string& extension_id,
550 const std::string& pref_key,
551 const base::ListValue** out_value) const {
552 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
553 const base::ListValue* out = NULL;
554 if (!ext || !ext->GetList(pref_key, &out))
562 bool ExtensionPrefs::ReadPrefAsDictionary(
563 const std::string& extension_id,
564 const std::string& pref_key,
565 const base::DictionaryValue** out_value) const {
566 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
567 const base::DictionaryValue* out = NULL;
568 if (!ext || !ext->GetDictionary(pref_key, &out))
576 bool ExtensionPrefs::HasPrefForExtension(
577 const std::string& extension_id) const {
578 return GetExtensionPref(extension_id) != NULL;
581 bool ExtensionPrefs::ReadPrefAsURLPatternSet(const std::string& extension_id,
582 const std::string& pref_key,
583 URLPatternSet* result,
585 const base::ListValue* value = NULL;
586 if (!ReadPrefAsList(extension_id, pref_key, &value))
589 bool allow_file_access = AllowFileAccess(extension_id);
590 return result->Populate(*value, valid_schemes, allow_file_access, NULL);
593 void ExtensionPrefs::SetExtensionPrefURLPatternSet(
594 const std::string& extension_id,
595 const std::string& pref_key,
596 const URLPatternSet& new_value) {
597 UpdateExtensionPref(extension_id, pref_key, new_value.ToValue().release());
600 bool ExtensionPrefs::ReadPrefAsBooleanAndReturn(
601 const std::string& extension_id,
602 const std::string& pref_key) const {
603 bool out_value = false;
604 return ReadPrefAsBoolean(extension_id, pref_key, &out_value) && out_value;
607 PermissionSet* ExtensionPrefs::ReadPrefAsPermissionSet(
608 const std::string& extension_id,
609 const std::string& pref_key) {
610 if (!GetExtensionPref(extension_id))
613 // Retrieve the API permissions. Please refer SetExtensionPrefPermissionSet()
614 // for api_values format.
615 APIPermissionSet apis;
616 const base::ListValue* api_values = NULL;
617 std::string api_pref = JoinPrefs(pref_key, kPrefAPIs);
618 if (ReadPrefAsList(extension_id, api_pref, &api_values)) {
619 APIPermissionSet::ParseFromJSON(api_values,
620 APIPermissionSet::kAllowInternalPermissions,
624 // Retrieve the Manifest Keys permissions. Please refer to
625 // |SetExtensionPrefPermissionSet| for manifest_permissions_values format.
626 ManifestPermissionSet manifest_permissions;
627 const base::ListValue* manifest_permissions_values = NULL;
628 std::string manifest_permission_pref =
629 JoinPrefs(pref_key, kPrefManifestPermissions);
630 if (ReadPrefAsList(extension_id, manifest_permission_pref,
631 &manifest_permissions_values)) {
632 ManifestPermissionSet::ParseFromJSON(
633 manifest_permissions_values, &manifest_permissions, NULL, NULL);
636 // Retrieve the explicit host permissions.
637 URLPatternSet explicit_hosts;
638 ReadPrefAsURLPatternSet(
639 extension_id, JoinPrefs(pref_key, kPrefExplicitHosts),
640 &explicit_hosts, Extension::kValidHostPermissionSchemes);
642 // Retrieve the scriptable host permissions.
643 URLPatternSet scriptable_hosts;
644 ReadPrefAsURLPatternSet(
645 extension_id, JoinPrefs(pref_key, kPrefScriptableHosts),
646 &scriptable_hosts, UserScript::ValidUserScriptSchemes());
648 return new PermissionSet(
649 apis, manifest_permissions, explicit_hosts, scriptable_hosts);
652 // Set the API or Manifest permissions.
653 // The format of api_values is:
654 // [ "permission_name1", // permissions do not support detail.
655 // "permission_name2",
656 // {"permission_name3": value },
657 // // permission supports detail, permission detail will be stored in value.
661 static base::ListValue* CreatePermissionList(const T& permissions) {
662 base::ListValue* values = new base::ListValue();
663 for (typename T::const_iterator i = permissions.begin();
664 i != permissions.end(); ++i) {
665 scoped_ptr<base::Value> detail(i->ToValue());
667 base::DictionaryValue* tmp = new base::DictionaryValue();
668 tmp->Set(i->name(), detail.release());
671 values->Append(new base::StringValue(i->name()));
677 void ExtensionPrefs::SetExtensionPrefPermissionSet(
678 const std::string& extension_id,
679 const std::string& pref_key,
680 const PermissionSet* new_value) {
681 std::string api_pref = JoinPrefs(pref_key, kPrefAPIs);
682 base::ListValue* api_values = CreatePermissionList(new_value->apis());
683 UpdateExtensionPref(extension_id, api_pref, api_values);
685 std::string manifest_permissions_pref =
686 JoinPrefs(pref_key, kPrefManifestPermissions);
687 base::ListValue* manifest_permissions_values = CreatePermissionList(
688 new_value->manifest_permissions());
689 UpdateExtensionPref(extension_id,
690 manifest_permissions_pref,
691 manifest_permissions_values);
693 // Set the explicit host permissions.
694 if (!new_value->explicit_hosts().is_empty()) {
695 SetExtensionPrefURLPatternSet(extension_id,
696 JoinPrefs(pref_key, kPrefExplicitHosts),
697 new_value->explicit_hosts());
700 // Set the scriptable host permissions.
701 if (!new_value->scriptable_hosts().is_empty()) {
702 SetExtensionPrefURLPatternSet(extension_id,
703 JoinPrefs(pref_key, kPrefScriptableHosts),
704 new_value->scriptable_hosts());
708 int ExtensionPrefs::IncrementAcknowledgePromptCount(
709 const std::string& extension_id) {
711 ReadPrefAsInteger(extension_id, kPrefAcknowledgePromptCount, &count);
713 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount,
714 new base::FundamentalValue(count));
718 bool ExtensionPrefs::IsExternalExtensionAcknowledged(
719 const std::string& extension_id) {
720 return ReadPrefAsBooleanAndReturn(extension_id, kPrefExternalAcknowledged);
723 void ExtensionPrefs::AcknowledgeExternalExtension(
724 const std::string& extension_id) {
725 DCHECK(Extension::IdIsValid(extension_id));
726 UpdateExtensionPref(extension_id, kPrefExternalAcknowledged,
727 new base::FundamentalValue(true));
728 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, NULL);
731 bool ExtensionPrefs::IsBlacklistedExtensionAcknowledged(
732 const std::string& extension_id) {
733 return ReadPrefAsBooleanAndReturn(extension_id, kPrefBlacklistAcknowledged);
736 void ExtensionPrefs::AcknowledgeBlacklistedExtension(
737 const std::string& extension_id) {
738 DCHECK(Extension::IdIsValid(extension_id));
739 UpdateExtensionPref(extension_id, kPrefBlacklistAcknowledged,
740 new base::FundamentalValue(true));
741 UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, NULL);
744 bool ExtensionPrefs::IsExternalInstallFirstRun(
745 const std::string& extension_id) {
746 return ReadPrefAsBooleanAndReturn(extension_id, kPrefExternalInstallFirstRun);
749 void ExtensionPrefs::SetExternalInstallFirstRun(
750 const std::string& extension_id) {
751 DCHECK(Extension::IdIsValid(extension_id));
752 UpdateExtensionPref(extension_id, kPrefExternalInstallFirstRun,
753 new base::FundamentalValue(true));
756 bool ExtensionPrefs::HasWipeoutBeenAcknowledged(
757 const std::string& extension_id) {
758 return ReadPrefAsBooleanAndReturn(extension_id, kPrefWipeoutAcknowledged);
761 void ExtensionPrefs::SetWipeoutAcknowledged(
762 const std::string& extension_id,
764 UpdateExtensionPref(extension_id, kPrefWipeoutAcknowledged,
765 value ? base::Value::CreateBooleanValue(value) : NULL);
768 bool ExtensionPrefs::HasSettingsApiBubbleBeenAcknowledged(
769 const std::string& extension_id) {
770 return ReadPrefAsBooleanAndReturn(extension_id,
771 kPrefSettingsBubbleAcknowledged);
774 void ExtensionPrefs::SetSettingsApiBubbleBeenAcknowledged(
775 const std::string& extension_id,
777 UpdateExtensionPref(extension_id,
778 kPrefSettingsBubbleAcknowledged,
779 value ? base::Value::CreateBooleanValue(value) : NULL);
782 bool ExtensionPrefs::SetAlertSystemFirstRun() {
783 if (prefs_->GetBoolean(pref_names::kAlertsInitialized)) {
786 prefs_->SetBoolean(pref_names::kAlertsInitialized, true);
790 bool ExtensionPrefs::ExtensionsBlacklistedByDefault() const {
791 return admin_policy::BlacklistedByDefault(
792 prefs_->GetList(pref_names::kInstallDenyList));
795 bool ExtensionPrefs::DidExtensionEscalatePermissions(
796 const std::string& extension_id) {
797 return ReadPrefAsBooleanAndReturn(extension_id,
798 kExtensionDidEscalatePermissions);
801 void ExtensionPrefs::SetDidExtensionEscalatePermissions(
802 const Extension* extension, bool did_escalate) {
803 UpdateExtensionPref(extension->id(), kExtensionDidEscalatePermissions,
804 new base::FundamentalValue(did_escalate));
807 int ExtensionPrefs::GetDisableReasons(const std::string& extension_id) const {
809 if (ReadPrefAsInteger(extension_id, kPrefDisableReasons, &value) &&
813 return Extension::DISABLE_NONE;
816 void ExtensionPrefs::AddDisableReason(const std::string& extension_id,
817 Extension::DisableReason disable_reason) {
818 ModifyDisableReason(extension_id, disable_reason, DISABLE_REASON_ADD);
821 void ExtensionPrefs::RemoveDisableReason(
822 const std::string& extension_id,
823 Extension::DisableReason disable_reason) {
824 ModifyDisableReason(extension_id, disable_reason, DISABLE_REASON_REMOVE);
827 void ExtensionPrefs::ClearDisableReasons(const std::string& extension_id) {
829 extension_id, Extension::DISABLE_NONE, DISABLE_REASON_CLEAR);
832 void ExtensionPrefs::ModifyDisableReason(const std::string& extension_id,
833 Extension::DisableReason reason,
834 DisableReasonChange change) {
835 int old_value = GetDisableReasons(extension_id);
836 int new_value = old_value;
838 case DISABLE_REASON_ADD:
839 new_value |= static_cast<int>(reason);
841 case DISABLE_REASON_REMOVE:
842 new_value &= ~static_cast<int>(reason);
844 case DISABLE_REASON_CLEAR:
845 new_value = Extension::DISABLE_NONE;
849 if (old_value == new_value) // no change, return.
852 if (new_value == Extension::DISABLE_NONE) {
853 UpdateExtensionPref(extension_id, kPrefDisableReasons, NULL);
855 UpdateExtensionPref(extension_id,
857 new base::FundamentalValue(new_value));
860 FOR_EACH_OBSERVER(Observer,
862 OnExtensionDisableReasonsChanged(extension_id, new_value));
865 std::set<std::string> ExtensionPrefs::GetBlacklistedExtensions() {
866 std::set<std::string> ids;
868 const base::DictionaryValue* extensions =
869 prefs_->GetDictionary(pref_names::kExtensions);
873 for (base::DictionaryValue::Iterator it(*extensions);
874 !it.IsAtEnd(); it.Advance()) {
875 if (!it.value().IsType(base::Value::TYPE_DICTIONARY)) {
876 NOTREACHED() << "Invalid pref for extension " << it.key();
879 if (IsBlacklistBitSet(
880 static_cast<const base::DictionaryValue*>(&it.value()))) {
881 ids.insert(it.key());
888 void ExtensionPrefs::SetExtensionBlacklisted(const std::string& extension_id,
889 bool is_blacklisted) {
890 bool currently_blacklisted = IsExtensionBlacklisted(extension_id);
891 if (is_blacklisted == currently_blacklisted)
894 // Always make sure the "acknowledged" bit is cleared since the blacklist bit
896 UpdateExtensionPref(extension_id, kPrefBlacklistAcknowledged, NULL);
898 if (is_blacklisted) {
899 UpdateExtensionPref(extension_id,
901 new base::FundamentalValue(true));
903 UpdateExtensionPref(extension_id, kPrefBlacklist, NULL);
904 const base::DictionaryValue* dict = GetExtensionPref(extension_id);
905 if (dict && dict->empty())
906 DeleteExtensionPrefs(extension_id);
910 bool ExtensionPrefs::IsExtensionBlacklisted(const std::string& id) const {
911 const base::DictionaryValue* ext_prefs = GetExtensionPref(id);
912 return ext_prefs && IsBlacklistBitSet(ext_prefs);
917 // Serializes |time| as a string value mapped to |key| in |dictionary|.
918 void SaveTime(base::DictionaryValue* dictionary,
920 const base::Time& time) {
923 std::string string_value = base::Int64ToString(time.ToInternalValue());
924 dictionary->SetString(key, string_value);
927 // The opposite of SaveTime. If |key| is not found, this returns an empty Time
928 // (is_null() will return true).
929 base::Time ReadTime(const base::DictionaryValue* dictionary, const char* key) {
932 std::string string_value;
934 if (dictionary->GetString(key, &string_value)) {
935 if (base::StringToInt64(string_value, &value)) {
936 return base::Time::FromInternalValue(value);
944 base::Time ExtensionPrefs::LastPingDay(const std::string& extension_id) const {
945 DCHECK(Extension::IdIsValid(extension_id));
946 return ReadTime(GetExtensionPref(extension_id), kLastPingDay);
949 void ExtensionPrefs::SetLastPingDay(const std::string& extension_id,
950 const base::Time& time) {
951 DCHECK(Extension::IdIsValid(extension_id));
952 ScopedExtensionPrefUpdate update(prefs_, extension_id);
953 SaveTime(update.Get(), kLastPingDay, time);
956 base::Time ExtensionPrefs::BlacklistLastPingDay() const {
957 return ReadTime(prefs_->GetDictionary(kExtensionsBlacklistUpdate),
961 void ExtensionPrefs::SetBlacklistLastPingDay(const base::Time& time) {
962 DictionaryPrefUpdate update(prefs_, kExtensionsBlacklistUpdate);
963 SaveTime(update.Get(), kLastPingDay, time);
966 base::Time ExtensionPrefs::LastActivePingDay(const std::string& extension_id) {
967 DCHECK(Extension::IdIsValid(extension_id));
968 return ReadTime(GetExtensionPref(extension_id), kLastActivePingDay);
971 void ExtensionPrefs::SetLastActivePingDay(const std::string& extension_id,
972 const base::Time& time) {
973 DCHECK(Extension::IdIsValid(extension_id));
974 ScopedExtensionPrefUpdate update(prefs_, extension_id);
975 SaveTime(update.Get(), kLastActivePingDay, time);
978 bool ExtensionPrefs::GetActiveBit(const std::string& extension_id) {
979 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
981 if (dictionary && dictionary->GetBoolean(kActiveBit, &result))
986 void ExtensionPrefs::SetActiveBit(const std::string& extension_id,
988 UpdateExtensionPref(extension_id, kActiveBit,
989 new base::FundamentalValue(active));
992 void ExtensionPrefs::MigratePermissions(const ExtensionIdList& extension_ids) {
993 PermissionsInfo* info = PermissionsInfo::GetInstance();
994 for (ExtensionIdList::const_iterator ext_id =
995 extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) {
996 // An extension's granted permissions need to be migrated if the
997 // full_access bit is present. This bit was always present in the previous
998 // scheme and is never present now.
1000 const base::DictionaryValue* ext = GetExtensionPref(*ext_id);
1001 if (!ext || !ext->GetBoolean(kPrefOldGrantedFullAccess, &full_access))
1004 // Remove the full access bit (empty list will get trimmed).
1005 UpdateExtensionPref(
1006 *ext_id, kPrefOldGrantedFullAccess, new base::ListValue());
1008 // Add the plugin permission if the full access bit was set.
1010 const base::ListValue* apis = NULL;
1011 base::ListValue* new_apis = NULL;
1013 std::string granted_apis = JoinPrefs(kPrefGrantedPermissions, kPrefAPIs);
1014 if (ext->GetList(kPrefOldGrantedAPIs, &apis))
1015 new_apis = apis->DeepCopy();
1017 new_apis = new base::ListValue();
1019 std::string plugin_name = info->GetByID(APIPermission::kPlugin)->name();
1020 new_apis->Append(new base::StringValue(plugin_name));
1021 UpdateExtensionPref(*ext_id, granted_apis, new_apis);
1024 // The granted permissions originally only held the effective hosts,
1025 // which are a combination of host and user script host permissions.
1026 // We now maintain these lists separately. For migration purposes, it
1027 // does not matter how we treat the old effective hosts as long as the
1028 // new effective hosts will be the same, so we move them to explicit
1029 // host permissions.
1030 const base::ListValue* hosts = NULL;
1031 std::string explicit_hosts =
1032 JoinPrefs(kPrefGrantedPermissions, kPrefExplicitHosts);
1033 if (ext->GetList(kPrefOldGrantedHosts, &hosts)) {
1034 UpdateExtensionPref(
1035 *ext_id, explicit_hosts, hosts->DeepCopy());
1037 // We can get rid of the old one by setting it to an empty list.
1038 UpdateExtensionPref(*ext_id, kPrefOldGrantedHosts, new base::ListValue());
1043 void ExtensionPrefs::MigrateDisableReasons(
1044 const ExtensionIdList& extension_ids) {
1045 for (ExtensionIdList::const_iterator ext_id =
1046 extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) {
1048 if (ReadPrefAsInteger(*ext_id, kDeprecatedPrefDisableReason, &value)) {
1049 int new_value = Extension::DISABLE_NONE;
1051 case Extension::DEPRECATED_DISABLE_USER_ACTION:
1052 new_value = Extension::DISABLE_USER_ACTION;
1054 case Extension::DEPRECATED_DISABLE_PERMISSIONS_INCREASE:
1055 new_value = Extension::DISABLE_PERMISSIONS_INCREASE;
1057 case Extension::DEPRECATED_DISABLE_RELOAD:
1058 new_value = Extension::DISABLE_RELOAD;
1062 UpdateExtensionPref(*ext_id, kPrefDisableReasons,
1063 new base::FundamentalValue(new_value));
1064 // Remove the old disable reason.
1065 UpdateExtensionPref(*ext_id, kDeprecatedPrefDisableReason, NULL);
1070 PermissionSet* ExtensionPrefs::GetGrantedPermissions(
1071 const std::string& extension_id) {
1072 CHECK(Extension::IdIsValid(extension_id));
1073 return ReadPrefAsPermissionSet(extension_id, kPrefGrantedPermissions);
1076 void ExtensionPrefs::AddGrantedPermissions(
1077 const std::string& extension_id,
1078 const PermissionSet* permissions) {
1079 CHECK(Extension::IdIsValid(extension_id));
1081 scoped_refptr<PermissionSet> granted_permissions(
1082 GetGrantedPermissions(extension_id));
1084 // The new granted permissions are the union of the already granted
1085 // permissions and the newly granted permissions.
1086 scoped_refptr<PermissionSet> new_perms(
1087 PermissionSet::CreateUnion(
1088 permissions, granted_permissions.get()));
1090 SetExtensionPrefPermissionSet(
1091 extension_id, kPrefGrantedPermissions, new_perms.get());
1094 void ExtensionPrefs::RemoveGrantedPermissions(
1095 const std::string& extension_id,
1096 const PermissionSet* permissions) {
1097 CHECK(Extension::IdIsValid(extension_id));
1099 scoped_refptr<PermissionSet> granted_permissions(
1100 GetGrantedPermissions(extension_id));
1102 // The new granted permissions are the difference of the already granted
1103 // permissions and the newly ungranted permissions.
1104 scoped_refptr<PermissionSet> new_perms(
1105 PermissionSet::CreateDifference(
1106 granted_permissions.get(), permissions));
1108 SetExtensionPrefPermissionSet(
1109 extension_id, kPrefGrantedPermissions, new_perms.get());
1112 PermissionSet* ExtensionPrefs::GetActivePermissions(
1113 const std::string& extension_id) {
1114 CHECK(Extension::IdIsValid(extension_id));
1115 return ReadPrefAsPermissionSet(extension_id, kPrefActivePermissions);
1118 void ExtensionPrefs::SetActivePermissions(
1119 const std::string& extension_id,
1120 const PermissionSet* permissions) {
1121 SetExtensionPrefPermissionSet(
1122 extension_id, kPrefActivePermissions, permissions);
1125 void ExtensionPrefs::SetExtensionRunning(const std::string& extension_id,
1127 base::Value* value = new base::FundamentalValue(is_running);
1128 UpdateExtensionPref(extension_id, kPrefRunning, value);
1131 bool ExtensionPrefs::IsExtensionRunning(const std::string& extension_id) {
1132 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1135 bool running = false;
1136 extension->GetBoolean(kPrefRunning, &running);
1140 void ExtensionPrefs::SetIsActive(const std::string& extension_id,
1142 base::Value* value = new base::FundamentalValue(is_active);
1143 UpdateExtensionPref(extension_id, kIsActive, value);
1146 bool ExtensionPrefs::IsActive(const std::string& extension_id) {
1147 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1150 bool is_active = false;
1151 extension->GetBoolean(kIsActive, &is_active);
1155 bool ExtensionPrefs::IsIncognitoEnabled(const std::string& extension_id) const {
1156 return ReadPrefAsBooleanAndReturn(extension_id, kPrefIncognitoEnabled);
1159 void ExtensionPrefs::SetIsIncognitoEnabled(const std::string& extension_id,
1161 UpdateExtensionPref(extension_id, kPrefIncognitoEnabled,
1162 new base::FundamentalValue(enabled));
1163 extension_pref_value_map_->SetExtensionIncognitoState(extension_id, enabled);
1166 bool ExtensionPrefs::AllowFileAccess(const std::string& extension_id) const {
1167 return ReadPrefAsBooleanAndReturn(extension_id, kPrefAllowFileAccess);
1170 void ExtensionPrefs::SetAllowFileAccess(const std::string& extension_id,
1172 UpdateExtensionPref(extension_id, kPrefAllowFileAccess,
1173 new base::FundamentalValue(allow));
1176 bool ExtensionPrefs::HasAllowFileAccessSetting(
1177 const std::string& extension_id) const {
1178 const base::DictionaryValue* ext = GetExtensionPref(extension_id);
1179 return ext && ext->HasKey(kPrefAllowFileAccess);
1182 bool ExtensionPrefs::DoesExtensionHaveState(
1183 const std::string& id, Extension::State check_state) const {
1184 const base::DictionaryValue* extension = GetExtensionPref(id);
1186 if (!extension || !extension->GetInteger(kPrefState, &state))
1189 if (state < 0 || state >= Extension::NUM_STATES) {
1190 LOG(ERROR) << "Bad pref 'state' for extension '" << id << "'";
1194 return state == check_state;
1197 bool ExtensionPrefs::IsExternalExtensionUninstalled(
1198 const std::string& id) const {
1199 return DoesExtensionHaveState(id, Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1202 bool ExtensionPrefs::IsExtensionDisabled(
1203 const std::string& id) const {
1204 return DoesExtensionHaveState(id, Extension::DISABLED);
1207 ExtensionIdList ExtensionPrefs::GetToolbarOrder() {
1208 ExtensionIdList id_list_out;
1209 GetUserExtensionPrefIntoContainer(pref_names::kToolbar, &id_list_out);
1213 void ExtensionPrefs::SetToolbarOrder(const ExtensionIdList& extension_ids) {
1214 SetExtensionPrefFromContainer(pref_names::kToolbar, extension_ids);
1217 bool ExtensionPrefs::GetKnownDisabled(ExtensionIdSet* id_set_out) {
1218 return GetUserExtensionPrefIntoContainer(pref_names::kKnownDisabled,
1222 void ExtensionPrefs::SetKnownDisabled(const ExtensionIdSet& extension_ids) {
1223 SetExtensionPrefFromContainer(pref_names::kKnownDisabled, extension_ids);
1226 void ExtensionPrefs::OnExtensionInstalled(
1227 const Extension* extension,
1228 Extension::State initial_state,
1229 bool blacklisted_for_malware,
1230 const syncer::StringOrdinal& page_ordinal,
1231 const std::string& install_parameter) {
1232 ScopedExtensionPrefUpdate update(prefs_, extension->id());
1233 base::DictionaryValue* extension_dict = update.Get();
1234 const base::Time install_time = time_provider_->GetCurrentTime();
1235 PopulateExtensionInfoPrefs(extension,
1238 blacklisted_for_malware,
1241 FinishExtensionInfoPrefs(extension->id(), install_time,
1242 extension->RequiresSortOrdinal(),
1243 page_ordinal, extension_dict);
1246 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
1247 const Manifest::Location& location,
1248 bool external_uninstall) {
1249 app_sorting_->ClearOrdinals(extension_id);
1251 // For external extensions, we save a preference reminding ourself not to try
1252 // and install the extension anymore (except when |external_uninstall| is
1253 // true, which signifies that the registry key was deleted or the pref file
1254 // no longer lists the extension).
1255 if (!external_uninstall && Manifest::IsExternalLocation(location)) {
1256 UpdateExtensionPref(extension_id, kPrefState,
1257 new base::FundamentalValue(
1258 Extension::EXTERNAL_EXTENSION_UNINSTALLED));
1259 extension_pref_value_map_->SetExtensionState(extension_id, false);
1260 content_settings_store_->SetExtensionState(extension_id, false);
1262 int creation_flags = GetCreationFlags(extension_id);
1263 if (creation_flags & Extension::IS_EPHEMERAL) {
1264 // Keep ephemeral apps around, but mark them as evicted.
1265 UpdateExtensionPref(extension_id, kPrefEvictedEphemeralApp,
1266 new base::FundamentalValue(true));
1268 DeleteExtensionPrefs(extension_id);
1273 void ExtensionPrefs::SetExtensionState(const std::string& extension_id,
1274 Extension::State state) {
1275 UpdateExtensionPref(extension_id, kPrefState,
1276 new base::FundamentalValue(state));
1277 bool enabled = (state == Extension::ENABLED);
1278 extension_pref_value_map_->SetExtensionState(extension_id, enabled);
1279 content_settings_store_->SetExtensionState(extension_id, enabled);
1282 void ExtensionPrefs::SetExtensionBlacklistState(const std::string& extension_id,
1283 BlacklistState state) {
1284 SetExtensionBlacklisted(extension_id, state == BLACKLISTED_MALWARE);
1285 UpdateExtensionPref(extension_id, kPrefBlacklistState,
1286 new base::FundamentalValue(state));
1289 BlacklistState ExtensionPrefs::GetExtensionBlacklistState(
1290 const std::string& extension_id) {
1291 if (IsExtensionBlacklisted(extension_id))
1292 return BLACKLISTED_MALWARE;
1293 const base::DictionaryValue* ext_prefs = GetExtensionPref(extension_id);
1295 if (ext_prefs && ext_prefs->GetInteger(kPrefBlacklistState, &int_value))
1296 return static_cast<BlacklistState>(int_value);
1298 return NOT_BLACKLISTED;
1301 std::string ExtensionPrefs::GetVersionString(const std::string& extension_id) {
1302 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1304 return std::string();
1306 std::string version;
1307 extension->GetString(kPrefVersion, &version);
1312 void ExtensionPrefs::UpdateManifest(const Extension* extension) {
1313 if (!Manifest::IsUnpackedLocation(extension->location())) {
1314 const base::DictionaryValue* extension_dict =
1315 GetExtensionPref(extension->id());
1316 if (!extension_dict)
1318 const base::DictionaryValue* old_manifest = NULL;
1319 bool update_required =
1320 !extension_dict->GetDictionary(kPrefManifest, &old_manifest) ||
1321 !extension->manifest()->value()->Equals(old_manifest);
1322 if (update_required) {
1323 UpdateExtensionPref(extension->id(), kPrefManifest,
1324 extension->manifest()->value()->DeepCopy());
1329 base::FilePath ExtensionPrefs::GetExtensionPath(
1330 const std::string& extension_id) {
1331 const base::DictionaryValue* dict = GetExtensionPref(extension_id);
1333 return base::FilePath();
1336 if (!dict->GetString(kPrefPath, &path))
1337 return base::FilePath();
1339 return install_directory_.Append(base::FilePath::FromUTF8Unsafe(path));
1342 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledInfoHelper(
1343 const std::string& extension_id,
1344 const base::DictionaryValue* extension) const {
1346 if (!extension->GetInteger(kPrefLocation, &location_value))
1347 return scoped_ptr<ExtensionInfo>();
1349 base::FilePath::StringType path;
1350 if (!extension->GetString(kPrefPath, &path))
1351 return scoped_ptr<ExtensionInfo>();
1353 // Make path absolute. Unpacked extensions will already have absolute paths,
1354 // otherwise make it so.
1355 Manifest::Location location = static_cast<Manifest::Location>(location_value);
1356 if (!Manifest::IsUnpackedLocation(location)) {
1357 DCHECK(location == Manifest::COMPONENT ||
1358 !base::FilePath(path).IsAbsolute());
1359 path = install_directory_.Append(path).value();
1362 // Only the following extension types have data saved in the preferences.
1363 if (location != Manifest::INTERNAL &&
1364 !Manifest::IsUnpackedLocation(location) &&
1365 !Manifest::IsExternalLocation(location)) {
1367 return scoped_ptr<ExtensionInfo>();
1370 const base::DictionaryValue* manifest = NULL;
1371 if (!Manifest::IsUnpackedLocation(location) &&
1372 !extension->GetDictionary(kPrefManifest, &manifest)) {
1373 LOG(WARNING) << "Missing manifest for extension " << extension_id;
1374 // Just a warning for now.
1377 return scoped_ptr<ExtensionInfo>(new ExtensionInfo(
1378 manifest, extension_id, base::FilePath(path), location));
1381 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledExtensionInfo(
1382 const std::string& extension_id) const {
1383 const base::DictionaryValue* ext = NULL;
1384 const base::DictionaryValue* extensions =
1385 prefs_->GetDictionary(pref_names::kExtensions);
1387 !extensions->GetDictionaryWithoutPathExpansion(extension_id, &ext))
1388 return scoped_ptr<ExtensionInfo>();
1390 if (!ext->GetInteger(kPrefState, &state_value) ||
1391 state_value == Extension::ENABLED_COMPONENT) {
1392 // Old preferences files may not have kPrefState for component extensions.
1393 return scoped_ptr<ExtensionInfo>();
1396 if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) {
1397 LOG(WARNING) << "External extension with id " << extension_id
1398 << " has been uninstalled by the user";
1399 return scoped_ptr<ExtensionInfo>();
1402 if (IsEvictedEphemeralApp(ext)) {
1403 // Hide evicted ephemeral apps.
1404 return scoped_ptr<ExtensionInfo>();
1407 return GetInstalledInfoHelper(extension_id, ext);
1410 scoped_ptr<ExtensionPrefs::ExtensionsInfo>
1411 ExtensionPrefs::GetInstalledExtensionsInfo() const {
1412 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1414 const base::DictionaryValue* extensions =
1415 prefs_->GetDictionary(pref_names::kExtensions);
1416 for (base::DictionaryValue::Iterator extension_id(*extensions);
1417 !extension_id.IsAtEnd(); extension_id.Advance()) {
1418 if (!Extension::IdIsValid(extension_id.key()))
1421 scoped_ptr<ExtensionInfo> info =
1422 GetInstalledExtensionInfo(extension_id.key());
1424 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1427 return extensions_info.Pass();
1430 scoped_ptr<ExtensionPrefs::ExtensionsInfo>
1431 ExtensionPrefs::GetUninstalledExtensionsInfo() const {
1432 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1434 const base::DictionaryValue* extensions =
1435 prefs_->GetDictionary(pref_names::kExtensions);
1436 for (base::DictionaryValue::Iterator extension_id(*extensions);
1437 !extension_id.IsAtEnd(); extension_id.Advance()) {
1438 const base::DictionaryValue* ext = NULL;
1439 if (!Extension::IdIsValid(extension_id.key()) ||
1440 !IsExternalExtensionUninstalled(extension_id.key()) ||
1441 !extension_id.value().GetAsDictionary(&ext))
1444 scoped_ptr<ExtensionInfo> info =
1445 GetInstalledInfoHelper(extension_id.key(), ext);
1447 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1450 return extensions_info.Pass();
1453 void ExtensionPrefs::SetDelayedInstallInfo(
1454 const Extension* extension,
1455 Extension::State initial_state,
1456 bool blacklisted_for_malware,
1457 DelayReason delay_reason,
1458 const syncer::StringOrdinal& page_ordinal,
1459 const std::string& install_parameter) {
1460 base::DictionaryValue* extension_dict = new base::DictionaryValue();
1461 PopulateExtensionInfoPrefs(extension,
1462 time_provider_->GetCurrentTime(),
1464 blacklisted_for_malware,
1468 // Add transient data that is needed by FinishDelayedInstallInfo(), but
1469 // should not be in the final extension prefs. All entries here should have
1470 // a corresponding Remove() call in FinishDelayedInstallInfo().
1471 if (extension->RequiresSortOrdinal()) {
1472 extension_dict->SetString(
1473 kPrefSuggestedPageOrdinal,
1474 page_ordinal.IsValid() ? page_ordinal.ToInternalValue()
1477 extension_dict->SetInteger(kDelayedInstallReason,
1478 static_cast<int>(delay_reason));
1480 UpdateExtensionPref(extension->id(), kDelayedInstallInfo, extension_dict);
1483 bool ExtensionPrefs::RemoveDelayedInstallInfo(
1484 const std::string& extension_id) {
1485 if (!GetExtensionPref(extension_id))
1487 ScopedExtensionPrefUpdate update(prefs_, extension_id);
1488 bool result = update->Remove(kDelayedInstallInfo, NULL);
1492 bool ExtensionPrefs::FinishDelayedInstallInfo(
1493 const std::string& extension_id) {
1494 CHECK(Extension::IdIsValid(extension_id));
1495 ScopedExtensionPrefUpdate update(prefs_, extension_id);
1496 base::DictionaryValue* extension_dict = update.Get();
1497 base::DictionaryValue* pending_install_dict = NULL;
1498 if (!extension_dict->GetDictionary(kDelayedInstallInfo,
1499 &pending_install_dict)) {
1503 // Retrieve and clear transient values populated by SetDelayedInstallInfo().
1504 // Also do any other data cleanup that makes sense.
1505 std::string serialized_ordinal;
1506 syncer::StringOrdinal suggested_page_ordinal;
1507 bool needs_sort_ordinal = false;
1508 if (pending_install_dict->GetString(kPrefSuggestedPageOrdinal,
1509 &serialized_ordinal)) {
1510 suggested_page_ordinal = syncer::StringOrdinal(serialized_ordinal);
1511 needs_sort_ordinal = true;
1512 pending_install_dict->Remove(kPrefSuggestedPageOrdinal, NULL);
1514 pending_install_dict->Remove(kDelayedInstallReason, NULL);
1516 const base::Time install_time = time_provider_->GetCurrentTime();
1517 pending_install_dict->Set(
1519 new base::StringValue(
1520 base::Int64ToString(install_time.ToInternalValue())));
1522 // Commit the delayed install data.
1523 for (base::DictionaryValue::Iterator it(*pending_install_dict); !it.IsAtEnd();
1525 extension_dict->Set(it.key(), it.value().DeepCopy());
1527 FinishExtensionInfoPrefs(extension_id, install_time, needs_sort_ordinal,
1528 suggested_page_ordinal, extension_dict);
1532 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetDelayedInstallInfo(
1533 const std::string& extension_id) const {
1534 const base::DictionaryValue* extension_prefs =
1535 GetExtensionPref(extension_id);
1536 if (!extension_prefs)
1537 return scoped_ptr<ExtensionInfo>();
1539 const base::DictionaryValue* ext = NULL;
1540 if (!extension_prefs->GetDictionary(kDelayedInstallInfo, &ext))
1541 return scoped_ptr<ExtensionInfo>();
1543 return GetInstalledInfoHelper(extension_id, ext);
1546 ExtensionPrefs::DelayReason ExtensionPrefs::GetDelayedInstallReason(
1547 const std::string& extension_id) const {
1548 const base::DictionaryValue* extension_prefs =
1549 GetExtensionPref(extension_id);
1550 if (!extension_prefs)
1551 return DELAY_REASON_NONE;
1553 const base::DictionaryValue* ext = NULL;
1554 if (!extension_prefs->GetDictionary(kDelayedInstallInfo, &ext))
1555 return DELAY_REASON_NONE;
1558 if (!ext->GetInteger(kDelayedInstallReason, &delay_reason))
1559 return DELAY_REASON_NONE;
1561 return static_cast<DelayReason>(delay_reason);
1564 scoped_ptr<ExtensionPrefs::ExtensionsInfo> ExtensionPrefs::
1565 GetAllDelayedInstallInfo() const {
1566 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1568 const base::DictionaryValue* extensions =
1569 prefs_->GetDictionary(pref_names::kExtensions);
1570 for (base::DictionaryValue::Iterator extension_id(*extensions);
1571 !extension_id.IsAtEnd(); extension_id.Advance()) {
1572 if (!Extension::IdIsValid(extension_id.key()))
1575 scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key());
1577 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1580 return extensions_info.Pass();
1583 scoped_ptr<ExtensionPrefs::ExtensionsInfo>
1584 ExtensionPrefs::GetEvictedEphemeralAppsInfo() const {
1585 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1587 const base::DictionaryValue* extensions =
1588 prefs_->GetDictionary(pref_names::kExtensions);
1589 for (base::DictionaryValue::Iterator extension_id(*extensions);
1590 !extension_id.IsAtEnd(); extension_id.Advance()) {
1591 const base::DictionaryValue* ext = NULL;
1592 if (!Extension::IdIsValid(extension_id.key()) ||
1593 !extension_id.value().GetAsDictionary(&ext)) {
1597 if (!IsEvictedEphemeralApp(ext))
1600 scoped_ptr<ExtensionInfo> info =
1601 GetInstalledInfoHelper(extension_id.key(), ext);
1603 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1606 return extensions_info.Pass();
1609 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetEvictedEphemeralAppInfo(
1610 const std::string& extension_id) const {
1611 const base::DictionaryValue* extension_prefs = GetExtensionPref(extension_id);
1612 if (!extension_prefs)
1613 return scoped_ptr<ExtensionInfo>();
1615 if (!IsEvictedEphemeralApp(extension_prefs))
1616 return scoped_ptr<ExtensionInfo>();
1618 return GetInstalledInfoHelper(extension_id, extension_prefs);
1621 void ExtensionPrefs::RemoveEvictedEphemeralApp(
1622 const std::string& extension_id) {
1623 bool evicted_ephemeral_app = false;
1624 if (ReadPrefAsBoolean(extension_id,
1625 kPrefEvictedEphemeralApp,
1626 &evicted_ephemeral_app) && evicted_ephemeral_app) {
1627 DeleteExtensionPrefs(extension_id);
1631 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) {
1632 return ReadPrefAsBooleanAndReturn(extension_id, kPrefUserDraggedApp);
1635 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) {
1636 UpdateExtensionPref(extension_id, kPrefUserDraggedApp,
1637 new base::FundamentalValue(true));
1640 bool ExtensionPrefs::IsFromWebStore(
1641 const std::string& extension_id) const {
1642 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1643 bool result = false;
1644 if (dictionary && dictionary->GetBoolean(kPrefFromWebStore, &result))
1649 bool ExtensionPrefs::IsFromBookmark(
1650 const std::string& extension_id) const {
1651 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1652 bool result = false;
1653 if (dictionary && dictionary->GetBoolean(kPrefFromBookmark, &result))
1658 int ExtensionPrefs::GetCreationFlags(const std::string& extension_id) const {
1659 int creation_flags = Extension::NO_FLAGS;
1660 if (!ReadPrefAsInteger(extension_id, kPrefCreationFlags, &creation_flags)) {
1661 // Since kPrefCreationFlags was added later, it will be missing for
1662 // previously installed extensions.
1663 if (IsFromBookmark(extension_id))
1664 creation_flags |= Extension::FROM_BOOKMARK;
1665 if (IsFromWebStore(extension_id))
1666 creation_flags |= Extension::FROM_WEBSTORE;
1667 if (WasInstalledByDefault(extension_id))
1668 creation_flags |= Extension::WAS_INSTALLED_BY_DEFAULT;
1669 if (WasInstalledByOem(extension_id))
1670 creation_flags |= Extension::WAS_INSTALLED_BY_OEM;
1672 return creation_flags;
1675 int ExtensionPrefs::GetDelayedInstallCreationFlags(
1676 const std::string& extension_id) const {
1677 int creation_flags = Extension::NO_FLAGS;
1678 const base::DictionaryValue* delayed_info = NULL;
1679 if (ReadPrefAsDictionary(extension_id, kDelayedInstallInfo, &delayed_info)) {
1680 delayed_info->GetInteger(kPrefCreationFlags, &creation_flags);
1682 return creation_flags;
1685 bool ExtensionPrefs::WasInstalledByDefault(
1686 const std::string& extension_id) const {
1687 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1688 bool result = false;
1690 dictionary->GetBoolean(kPrefWasInstalledByDefault, &result))
1695 bool ExtensionPrefs::WasInstalledByOem(const std::string& extension_id) const {
1696 const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1697 bool result = false;
1698 if (dictionary && dictionary->GetBoolean(kPrefWasInstalledByOem, &result))
1703 base::Time ExtensionPrefs::GetInstallTime(
1704 const std::string& extension_id) const {
1705 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1708 return base::Time();
1710 std::string install_time_str;
1711 if (!extension->GetString(kPrefInstallTime, &install_time_str))
1712 return base::Time();
1713 int64 install_time_i64 = 0;
1714 if (!base::StringToInt64(install_time_str, &install_time_i64))
1715 return base::Time();
1716 return base::Time::FromInternalValue(install_time_i64);
1719 base::Time ExtensionPrefs::GetLastLaunchTime(
1720 const std::string& extension_id) const {
1721 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1723 return base::Time();
1725 std::string launch_time_str;
1726 if (!extension->GetString(kPrefLastLaunchTime, &launch_time_str))
1727 return base::Time();
1728 int64 launch_time_i64 = 0;
1729 if (!base::StringToInt64(launch_time_str, &launch_time_i64))
1730 return base::Time();
1731 return base::Time::FromInternalValue(launch_time_i64);
1734 void ExtensionPrefs::SetLastLaunchTime(const std::string& extension_id,
1735 const base::Time& time) {
1736 DCHECK(Extension::IdIsValid(extension_id));
1737 ScopedExtensionPrefUpdate update(prefs_, extension_id);
1738 SaveTime(update.Get(), kPrefLastLaunchTime, time);
1741 void ExtensionPrefs::GetExtensions(ExtensionIdList* out) {
1744 scoped_ptr<ExtensionsInfo> extensions_info(GetInstalledExtensionsInfo());
1746 for (size_t i = 0; i < extensions_info->size(); ++i) {
1747 ExtensionInfo* info = extensions_info->at(i).get();
1748 out->push_back(info->extension_id);
1753 ExtensionIdList ExtensionPrefs::GetExtensionsFrom(
1754 const PrefService* pref_service) {
1755 ExtensionIdList result;
1757 const base::DictionaryValue* extension_prefs = NULL;
1758 const base::Value* extension_prefs_value =
1759 pref_service->GetUserPrefValue(pref_names::kExtensions);
1760 if (!extension_prefs_value ||
1761 !extension_prefs_value->GetAsDictionary(&extension_prefs)) {
1762 return result; // Empty set
1765 for (base::DictionaryValue::Iterator it(*extension_prefs); !it.IsAtEnd();
1767 const base::DictionaryValue* ext = NULL;
1768 if (!it.value().GetAsDictionary(&ext)) {
1769 NOTREACHED() << "Invalid pref for extension " << it.key();
1772 if (!IsBlacklistBitSet(ext))
1773 result.push_back(it.key());
1778 void ExtensionPrefs::AddObserver(Observer* observer) {
1779 observer_list_.AddObserver(observer);
1782 void ExtensionPrefs::RemoveObserver(Observer* observer) {
1783 observer_list_.RemoveObserver(observer);
1786 void ExtensionPrefs::FixMissingPrefs(const ExtensionIdList& extension_ids) {
1787 // Fix old entries that did not get an installation time entry when they
1788 // were installed or don't have a preferences field.
1789 for (ExtensionIdList::const_iterator ext_id = extension_ids.begin();
1790 ext_id != extension_ids.end(); ++ext_id) {
1791 if (GetInstallTime(*ext_id) == base::Time()) {
1792 VLOG(1) << "Could not parse installation time of extension "
1793 << *ext_id << ". It was probably installed before setting "
1794 << kPrefInstallTime << " was introduced. Updating "
1795 << kPrefInstallTime << " to the current time.";
1796 const base::Time install_time = time_provider_->GetCurrentTime();
1797 UpdateExtensionPref(*ext_id,
1799 new base::StringValue(base::Int64ToString(
1800 install_time.ToInternalValue())));
1805 void ExtensionPrefs::InitPrefStore() {
1806 if (extensions_disabled_) {
1807 extension_pref_value_map_->NotifyInitializationCompleted();
1811 // When this is called, the PrefService is initialized and provides access
1812 // to the user preferences stored in a JSON file.
1813 ExtensionIdList extension_ids;
1814 GetExtensions(&extension_ids);
1815 // Create empty preferences dictionary for each extension (these dictionaries
1816 // are pruned when persisting the preferences to disk).
1817 for (ExtensionIdList::iterator ext_id = extension_ids.begin();
1818 ext_id != extension_ids.end(); ++ext_id) {
1819 ScopedExtensionPrefUpdate update(prefs_, *ext_id);
1820 // This creates an empty dictionary if none is stored.
1824 FixMissingPrefs(extension_ids);
1825 MigratePermissions(extension_ids);
1826 MigrateDisableReasons(extension_ids);
1827 app_sorting_->Initialize(extension_ids);
1829 InitExtensionControlledPrefs(this, extension_pref_value_map_);
1831 extension_pref_value_map_->NotifyInitializationCompleted();
1834 bool ExtensionPrefs::HasIncognitoPrefValue(const std::string& pref_key) {
1835 bool has_incognito_pref_value = false;
1836 extension_pref_value_map_->GetEffectivePrefValue(pref_key,
1838 &has_incognito_pref_value);
1839 return has_incognito_pref_value;
1842 URLPatternSet ExtensionPrefs::GetAllowedInstallSites() {
1843 URLPatternSet result;
1844 const base::ListValue* list =
1845 prefs_->GetList(pref_names::kAllowedInstallSites);
1848 for (size_t i = 0; i < list->GetSize(); ++i) {
1849 std::string entry_string;
1850 URLPattern entry(URLPattern::SCHEME_ALL);
1851 if (!list->GetString(i, &entry_string) ||
1852 entry.Parse(entry_string) != URLPattern::PARSE_SUCCESS) {
1853 LOG(ERROR) << "Invalid value for preference: "
1854 << pref_names::kAllowedInstallSites << "." << i;
1857 result.AddPattern(entry);
1863 const base::DictionaryValue* ExtensionPrefs::GetGeometryCache(
1864 const std::string& extension_id) const {
1865 const base::DictionaryValue* extension_prefs = GetExtensionPref(extension_id);
1866 if (!extension_prefs)
1869 const base::DictionaryValue* ext = NULL;
1870 if (!extension_prefs->GetDictionary(kPrefGeometryCache, &ext))
1876 void ExtensionPrefs::SetGeometryCache(
1877 const std::string& extension_id,
1878 scoped_ptr<base::DictionaryValue> cache) {
1879 UpdateExtensionPref(extension_id, kPrefGeometryCache, cache.release());
1882 const base::DictionaryValue* ExtensionPrefs::GetInstallSignature() {
1883 return prefs_->GetDictionary(kInstallSignature);
1886 void ExtensionPrefs::SetInstallSignature(
1887 const base::DictionaryValue* signature) {
1889 prefs_->Set(kInstallSignature, *signature);
1890 DVLOG(1) << "SetInstallSignature - saving";
1892 DVLOG(1) << "SetInstallSignature - clearing";
1893 prefs_->ClearPref(kInstallSignature);
1897 std::string ExtensionPrefs::GetInstallParam(
1898 const std::string& extension_id) const {
1899 const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1902 return std::string();
1904 std::string install_parameter;
1905 if (!extension->GetString(kPrefInstallParam, &install_parameter))
1906 return std::string();
1907 return install_parameter;
1910 void ExtensionPrefs::SetInstallParam(const std::string& extension_id,
1911 const std::string& install_parameter) {
1912 UpdateExtensionPref(extension_id,
1914 new base::StringValue(install_parameter));
1917 ExtensionPrefs::ExtensionPrefs(
1919 const base::FilePath& root_dir,
1920 ExtensionPrefValueMap* extension_pref_value_map,
1921 scoped_ptr<AppSorting> app_sorting,
1922 scoped_ptr<TimeProvider> time_provider,
1923 bool extensions_disabled)
1925 install_directory_(root_dir),
1926 extension_pref_value_map_(extension_pref_value_map),
1927 app_sorting_(app_sorting.Pass()),
1928 content_settings_store_(new ContentSettingsStore()),
1929 time_provider_(time_provider.Pass()),
1930 extensions_disabled_(extensions_disabled) {
1931 app_sorting_->SetExtensionScopedPrefs(this);
1932 MakePathsRelative();
1936 void ExtensionPrefs::SetNeedsStorageGarbageCollection(bool value) {
1937 prefs_->SetBoolean(pref_names::kStorageGarbageCollect, value);
1940 bool ExtensionPrefs::NeedsStorageGarbageCollection() {
1941 return prefs_->GetBoolean(pref_names::kStorageGarbageCollect);
1945 void ExtensionPrefs::RegisterProfilePrefs(
1946 user_prefs::PrefRegistrySyncable* registry) {
1947 registry->RegisterDictionaryPref(
1948 pref_names::kExtensions,
1949 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1950 registry->RegisterListPref(pref_names::kToolbar,
1951 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
1952 registry->RegisterIntegerPref(
1953 pref_names::kToolbarSize,
1954 -1, // default value
1955 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1956 registry->RegisterDictionaryPref(
1957 kExtensionsBlacklistUpdate,
1958 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1959 registry->RegisterListPref(pref_names::kInstallAllowList,
1960 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1961 registry->RegisterListPref(pref_names::kInstallDenyList,
1962 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1963 registry->RegisterDictionaryPref(
1964 pref_names::kInstallForceList,
1965 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1966 registry->RegisterListPref(pref_names::kAllowedTypes,
1967 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1968 registry->RegisterBooleanPref(
1969 pref_names::kStorageGarbageCollect,
1970 false, // default value
1971 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1972 registry->RegisterInt64Pref(
1973 pref_names::kLastUpdateCheck,
1975 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1976 registry->RegisterInt64Pref(
1977 pref_names::kNextUpdateCheck,
1979 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1980 registry->RegisterListPref(pref_names::kAllowedInstallSites,
1981 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1982 registry->RegisterStringPref(
1983 pref_names::kLastChromeVersion,
1984 std::string(), // default value
1985 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1986 registry->RegisterListPref(pref_names::kKnownDisabled,
1987 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1988 #if defined(TOOLKIT_VIEWS)
1989 registry->RegisterIntegerPref(
1990 pref_names::kBrowserActionContainerWidth,
1992 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1994 registry->RegisterDictionaryPref(
1996 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1998 registry->RegisterListPref(pref_names::kNativeMessagingBlacklist,
1999 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2000 registry->RegisterListPref(pref_names::kNativeMessagingWhitelist,
2001 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2002 registry->RegisterBooleanPref(
2003 pref_names::kNativeMessagingUserLevelHosts,
2004 true, // default value
2005 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2008 template <class ExtensionIdContainer>
2009 bool ExtensionPrefs::GetUserExtensionPrefIntoContainer(
2011 ExtensionIdContainer* id_container_out) {
2012 DCHECK(id_container_out->empty());
2014 const base::Value* user_pref_value = prefs_->GetUserPrefValue(pref);
2015 const base::ListValue* user_pref_as_list;
2016 if (!user_pref_value || !user_pref_value->GetAsList(&user_pref_as_list))
2019 std::insert_iterator<ExtensionIdContainer> insert_iterator(
2020 *id_container_out, id_container_out->end());
2021 std::string extension_id;
2022 for (base::ListValue::const_iterator value_it = user_pref_as_list->begin();
2023 value_it != user_pref_as_list->end(); ++value_it) {
2024 if (!(*value_it)->GetAsString(&extension_id)) {
2028 insert_iterator = extension_id;
2033 template <class ExtensionIdContainer>
2034 void ExtensionPrefs::SetExtensionPrefFromContainer(
2036 const ExtensionIdContainer& strings) {
2037 ListPrefUpdate update(prefs_, pref);
2038 base::ListValue* list_of_values = update.Get();
2039 list_of_values->Clear();
2040 for (typename ExtensionIdContainer::const_iterator iter = strings.begin();
2041 iter != strings.end(); ++iter) {
2042 list_of_values->Append(new base::StringValue(*iter));
2046 void ExtensionPrefs::PopulateExtensionInfoPrefs(
2047 const Extension* extension,
2048 const base::Time install_time,
2049 Extension::State initial_state,
2050 bool blacklisted_for_malware,
2051 const std::string& install_parameter,
2052 base::DictionaryValue* extension_dict) {
2053 // Leave the state blank for component extensions so that old chrome versions
2054 // loading new profiles do not fail in GetInstalledExtensionInfo. Older
2055 // Chrome versions would only check for an omitted state.
2056 if (initial_state != Extension::ENABLED_COMPONENT)
2057 extension_dict->Set(kPrefState, new base::FundamentalValue(initial_state));
2059 extension_dict->Set(kPrefLocation,
2060 new base::FundamentalValue(extension->location()));
2061 extension_dict->Set(kPrefCreationFlags,
2062 new base::FundamentalValue(extension->creation_flags()));
2063 extension_dict->Set(kPrefFromWebStore,
2064 new base::FundamentalValue(extension->from_webstore()));
2065 extension_dict->Set(kPrefFromBookmark,
2066 new base::FundamentalValue(extension->from_bookmark()));
2067 extension_dict->Set(
2068 kPrefWasInstalledByDefault,
2069 new base::FundamentalValue(extension->was_installed_by_default()));
2070 extension_dict->Set(
2071 kPrefWasInstalledByOem,
2072 new base::FundamentalValue(extension->was_installed_by_oem()));
2073 extension_dict->Set(kPrefInstallTime,
2074 new base::StringValue(
2075 base::Int64ToString(install_time.ToInternalValue())));
2076 if (blacklisted_for_malware)
2077 extension_dict->Set(kPrefBlacklist, new base::FundamentalValue(true));
2079 base::FilePath::StringType path = MakePathRelative(install_directory_,
2081 extension_dict->Set(kPrefPath, new base::StringValue(path));
2082 if (!install_parameter.empty()) {
2083 extension_dict->Set(kPrefInstallParam,
2084 new base::StringValue(install_parameter));
2086 // We store prefs about LOAD extensions, but don't cache their manifest
2087 // since it may change on disk.
2088 if (!Manifest::IsUnpackedLocation(extension->location())) {
2089 extension_dict->Set(kPrefManifest,
2090 extension->manifest()->value()->DeepCopy());
2094 void ExtensionPrefs::FinishExtensionInfoPrefs(
2095 const std::string& extension_id,
2096 const base::Time install_time,
2097 bool needs_sort_ordinal,
2098 const syncer::StringOrdinal& suggested_page_ordinal,
2099 base::DictionaryValue* extension_dict) {
2100 // Reinitializes various preferences with empty dictionaries.
2101 if (!extension_dict->HasKey(pref_names::kPrefPreferences)) {
2102 extension_dict->Set(pref_names::kPrefPreferences,
2103 new base::DictionaryValue);
2106 if (!extension_dict->HasKey(pref_names::kPrefIncognitoPreferences)) {
2107 extension_dict->Set(pref_names::kPrefIncognitoPreferences,
2108 new base::DictionaryValue);
2111 if (!extension_dict->HasKey(pref_names::kPrefRegularOnlyPreferences)) {
2112 extension_dict->Set(pref_names::kPrefRegularOnlyPreferences,
2113 new base::DictionaryValue);
2116 if (!extension_dict->HasKey(pref_names::kPrefContentSettings))
2117 extension_dict->Set(pref_names::kPrefContentSettings, new base::ListValue);
2119 if (!extension_dict->HasKey(pref_names::kPrefIncognitoContentSettings)) {
2120 extension_dict->Set(pref_names::kPrefIncognitoContentSettings,
2121 new base::ListValue);
2124 // If this point has been reached, any pending installs should be considered
2126 extension_dict->Remove(kDelayedInstallInfo, NULL);
2128 // Clear state that may be registered from a previous install.
2129 extension_dict->Remove(EventRouter::kRegisteredEvents, NULL);
2131 // When evicted ephemeral apps are re-installed, this flag must be reset.
2132 extension_dict->Remove(kPrefEvictedEphemeralApp, NULL);
2134 // FYI, all code below here races on sudden shutdown because |extension_dict|,
2135 // |app_sorting_|, |extension_pref_value_map_|, and |content_settings_store_|
2136 // are updated non-transactionally. This is probably not fixable without
2137 // nested transactional updates to pref dictionaries.
2138 if (needs_sort_ordinal)
2139 app_sorting_->EnsureValidOrdinals(extension_id, suggested_page_ordinal);
2141 bool is_enabled = false;
2143 if (extension_dict->GetInteger(kPrefState, &initial_state)) {
2144 is_enabled = initial_state == Extension::ENABLED;
2146 bool is_incognito_enabled = IsIncognitoEnabled(extension_id);
2148 extension_pref_value_map_->RegisterExtension(
2149 extension_id, install_time, is_enabled, is_incognito_enabled);
2150 content_settings_store_->RegisterExtension(extension_id, install_time,
2154 } // namespace extensions