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 "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"
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());
267 ExtensionPrefs::TimeProvider::TimeProvider() {
270 ExtensionPrefs::TimeProvider::~TimeProvider() {
273 base::Time
ExtensionPrefs::TimeProvider::GetCurrentTime() const {
274 return base::Time::Now();
280 template <typename T
, base::Value::Type type_enum_value
>
281 ExtensionPrefs::ScopedUpdate
<T
, type_enum_value
>::ScopedUpdate(
282 ExtensionPrefs
* prefs
,
283 const std::string
& extension_id
,
284 const std::string
& key
)
285 : update_(prefs
->pref_service(), pref_names::kExtensions
),
286 extension_id_(extension_id
),
288 DCHECK(Extension::IdIsValid(extension_id_
));
291 template <typename T
, base::Value::Type type_enum_value
>
292 ExtensionPrefs::ScopedUpdate
<T
, type_enum_value
>::~ScopedUpdate() {
295 template <typename T
, base::Value::Type type_enum_value
>
296 T
* ExtensionPrefs::ScopedUpdate
<T
, type_enum_value
>::Get() {
297 base::DictionaryValue
* dict
= update_
.Get();
298 base::DictionaryValue
* extension
= NULL
;
299 base::Value
* key_value
= NULL
;
300 if (!dict
->GetDictionary(extension_id_
, &extension
) ||
301 !extension
->Get(key_
, &key_value
)) {
304 return key_value
->GetType() == type_enum_value
?
305 static_cast<T
*>(key_value
) :
309 template <typename T
, base::Value::Type type_enum_value
>
310 T
* ExtensionPrefs::ScopedUpdate
<T
, type_enum_value
>::Create() {
311 base::DictionaryValue
* dict
= update_
.Get();
312 base::DictionaryValue
* extension
= NULL
;
313 base::Value
* key_value
= NULL
;
314 T
* value_as_t
= NULL
;
315 if (!dict
->GetDictionary(extension_id_
, &extension
)) {
316 extension
= new base::DictionaryValue
;
317 dict
->SetWithoutPathExpansion(extension_id_
, extension
);
319 if (!extension
->Get(key_
, &key_value
)) {
321 extension
->SetWithoutPathExpansion(key_
, value_as_t
);
323 CHECK(key_value
->GetType() == type_enum_value
);
324 value_as_t
= static_cast<T
*>(key_value
);
329 // Explicit instantiations for Dictionary and List value types.
330 template class ExtensionPrefs::ScopedUpdate
<base::DictionaryValue
,
331 base::Value::TYPE_DICTIONARY
>;
332 template class ExtensionPrefs::ScopedUpdate
<base::ListValue
,
333 base::Value::TYPE_LIST
>;
340 ExtensionPrefs
* ExtensionPrefs::Create(
342 const base::FilePath
& root_dir
,
343 ExtensionPrefValueMap
* extension_pref_value_map
,
344 scoped_ptr
<AppSorting
> app_sorting
,
345 bool extensions_disabled
,
346 const std::vector
<ExtensionPrefsObserver
*>& early_observers
) {
347 return ExtensionPrefs::Create(prefs
,
349 extension_pref_value_map
,
353 make_scoped_ptr(new TimeProvider()));
357 ExtensionPrefs
* ExtensionPrefs::Create(
358 PrefService
* pref_service
,
359 const base::FilePath
& root_dir
,
360 ExtensionPrefValueMap
* extension_pref_value_map
,
361 scoped_ptr
<AppSorting
> app_sorting
,
362 bool extensions_disabled
,
363 const std::vector
<ExtensionPrefsObserver
*>& early_observers
,
364 scoped_ptr
<TimeProvider
> time_provider
) {
365 return new ExtensionPrefs(pref_service
,
367 extension_pref_value_map
,
369 time_provider
.Pass(),
374 ExtensionPrefs::~ExtensionPrefs() {
378 ExtensionPrefs
* ExtensionPrefs::Get(content::BrowserContext
* context
) {
379 return ExtensionPrefsFactory::GetInstance()->GetForBrowserContext(context
);
382 static base::FilePath::StringType
MakePathRelative(const base::FilePath
& parent
,
383 const base::FilePath
& child
) {
384 if (!parent
.IsParent(child
))
385 return child
.value();
387 base::FilePath::StringType retval
= child
.value().substr(
388 parent
.value().length());
389 if (base::FilePath::IsSeparator(retval
[0]))
390 return retval
.substr(1);
395 void ExtensionPrefs::MakePathsRelative() {
396 const base::DictionaryValue
* dict
=
397 prefs_
->GetDictionary(pref_names::kExtensions
);
398 if (!dict
|| dict
->empty())
401 // Collect all extensions ids with absolute paths in |absolute_keys|.
402 std::set
<std::string
> absolute_keys
;
403 for (base::DictionaryValue::Iterator
i(*dict
); !i
.IsAtEnd(); i
.Advance()) {
404 const base::DictionaryValue
* extension_dict
= NULL
;
405 if (!i
.value().GetAsDictionary(&extension_dict
))
408 if (extension_dict
->GetInteger(kPrefLocation
, &location_value
) &&
409 Manifest::IsUnpackedLocation(
410 static_cast<Manifest::Location
>(location_value
))) {
411 // Unpacked extensions can have absolute paths.
414 base::FilePath::StringType path_string
;
415 if (!extension_dict
->GetString(kPrefPath
, &path_string
))
417 base::FilePath
path(path_string
);
418 if (path
.IsAbsolute())
419 absolute_keys
.insert(i
.key());
421 if (absolute_keys
.empty())
425 DictionaryPrefUpdate
update(prefs_
, pref_names::kExtensions
);
426 base::DictionaryValue
* update_dict
= update
.Get();
427 for (std::set
<std::string
>::iterator i
= absolute_keys
.begin();
428 i
!= absolute_keys
.end(); ++i
) {
429 base::DictionaryValue
* extension_dict
= NULL
;
430 if (!update_dict
->GetDictionaryWithoutPathExpansion(*i
, &extension_dict
)) {
431 NOTREACHED() << "Control should never reach here for extension " << *i
;
434 base::FilePath::StringType path_string
;
435 extension_dict
->GetString(kPrefPath
, &path_string
);
436 base::FilePath
path(path_string
);
437 extension_dict
->SetString(kPrefPath
,
438 MakePathRelative(install_directory_
, path
));
442 const base::DictionaryValue
* ExtensionPrefs::GetExtensionPref(
443 const std::string
& extension_id
) const {
444 const base::DictionaryValue
* extensions
=
445 prefs_
->GetDictionary(pref_names::kExtensions
);
446 const base::DictionaryValue
* extension_dict
= NULL
;
448 !extensions
->GetDictionary(extension_id
, &extension_dict
)) {
451 return extension_dict
;
454 void ExtensionPrefs::UpdateExtensionPref(const std::string
& extension_id
,
455 const std::string
& key
,
456 base::Value
* data_value
) {
457 if (!Extension::IdIsValid(extension_id
)) {
458 NOTREACHED() << "Invalid extension_id " << extension_id
;
461 ScopedExtensionPrefUpdate
update(prefs_
, extension_id
);
463 update
->Set(key
, data_value
);
465 update
->Remove(key
, NULL
);
468 void ExtensionPrefs::DeleteExtensionPrefs(const std::string
& extension_id
) {
469 extension_pref_value_map_
->UnregisterExtension(extension_id
);
470 FOR_EACH_OBSERVER(ExtensionPrefsObserver
,
472 OnExtensionPrefsDeleted(extension_id
));
473 DictionaryPrefUpdate
update(prefs_
, pref_names::kExtensions
);
474 base::DictionaryValue
* dict
= update
.Get();
475 dict
->Remove(extension_id
, NULL
);
478 bool ExtensionPrefs::ReadPrefAsBoolean(const std::string
& extension_id
,
479 const std::string
& pref_key
,
480 bool* out_value
) const {
481 const base::DictionaryValue
* ext
= GetExtensionPref(extension_id
);
482 if (!ext
|| !ext
->GetBoolean(pref_key
, out_value
))
488 bool ExtensionPrefs::ReadPrefAsInteger(const std::string
& extension_id
,
489 const std::string
& pref_key
,
490 int* out_value
) const {
491 const base::DictionaryValue
* ext
= GetExtensionPref(extension_id
);
492 if (!ext
|| !ext
->GetInteger(pref_key
, out_value
))
498 bool ExtensionPrefs::ReadPrefAsString(const std::string
& extension_id
,
499 const std::string
& pref_key
,
500 std::string
* out_value
) const {
501 const base::DictionaryValue
* ext
= GetExtensionPref(extension_id
);
502 if (!ext
|| !ext
->GetString(pref_key
, out_value
))
508 bool ExtensionPrefs::ReadPrefAsList(const std::string
& extension_id
,
509 const std::string
& pref_key
,
510 const base::ListValue
** out_value
) const {
511 const base::DictionaryValue
* ext
= GetExtensionPref(extension_id
);
512 const base::ListValue
* out
= NULL
;
513 if (!ext
|| !ext
->GetList(pref_key
, &out
))
521 bool ExtensionPrefs::ReadPrefAsDictionary(
522 const std::string
& extension_id
,
523 const std::string
& pref_key
,
524 const base::DictionaryValue
** out_value
) const {
525 const base::DictionaryValue
* ext
= GetExtensionPref(extension_id
);
526 const base::DictionaryValue
* out
= NULL
;
527 if (!ext
|| !ext
->GetDictionary(pref_key
, &out
))
535 bool ExtensionPrefs::HasPrefForExtension(
536 const std::string
& extension_id
) const {
537 return GetExtensionPref(extension_id
) != NULL
;
540 bool ExtensionPrefs::ReadPrefAsURLPatternSet(const std::string
& extension_id
,
541 const std::string
& pref_key
,
542 URLPatternSet
* result
,
544 const base::ListValue
* value
= NULL
;
545 if (!ReadPrefAsList(extension_id
, pref_key
, &value
))
548 bool allow_file_access
= AllowFileAccess(extension_id
);
549 return result
->Populate(*value
, valid_schemes
, allow_file_access
, NULL
);
552 void ExtensionPrefs::SetExtensionPrefURLPatternSet(
553 const std::string
& extension_id
,
554 const std::string
& pref_key
,
555 const URLPatternSet
& new_value
) {
556 UpdateExtensionPref(extension_id
, pref_key
, new_value
.ToValue().release());
559 bool ExtensionPrefs::ReadPrefAsBooleanAndReturn(
560 const std::string
& extension_id
,
561 const std::string
& pref_key
) const {
562 bool out_value
= false;
563 return ReadPrefAsBoolean(extension_id
, pref_key
, &out_value
) && out_value
;
566 PermissionSet
* ExtensionPrefs::ReadPrefAsPermissionSet(
567 const std::string
& extension_id
,
568 const std::string
& pref_key
) {
569 if (!GetExtensionPref(extension_id
))
572 // Retrieve the API permissions. Please refer SetExtensionPrefPermissionSet()
573 // for api_values format.
574 APIPermissionSet apis
;
575 const base::ListValue
* api_values
= NULL
;
576 std::string api_pref
= JoinPrefs(pref_key
, kPrefAPIs
);
577 if (ReadPrefAsList(extension_id
, api_pref
, &api_values
)) {
578 APIPermissionSet::ParseFromJSON(api_values
,
579 APIPermissionSet::kAllowInternalPermissions
,
583 // Retrieve the Manifest Keys permissions. Please refer to
584 // |SetExtensionPrefPermissionSet| for manifest_permissions_values format.
585 ManifestPermissionSet manifest_permissions
;
586 const base::ListValue
* manifest_permissions_values
= NULL
;
587 std::string manifest_permission_pref
=
588 JoinPrefs(pref_key
, kPrefManifestPermissions
);
589 if (ReadPrefAsList(extension_id
, manifest_permission_pref
,
590 &manifest_permissions_values
)) {
591 ManifestPermissionSet::ParseFromJSON(
592 manifest_permissions_values
, &manifest_permissions
, NULL
, NULL
);
595 // Retrieve the explicit host permissions.
596 URLPatternSet explicit_hosts
;
597 ReadPrefAsURLPatternSet(
598 extension_id
, JoinPrefs(pref_key
, kPrefExplicitHosts
),
599 &explicit_hosts
, Extension::kValidHostPermissionSchemes
);
601 // Retrieve the scriptable host permissions.
602 URLPatternSet scriptable_hosts
;
603 ReadPrefAsURLPatternSet(
604 extension_id
, JoinPrefs(pref_key
, kPrefScriptableHosts
),
605 &scriptable_hosts
, UserScript::ValidUserScriptSchemes());
607 return new PermissionSet(
608 apis
, manifest_permissions
, explicit_hosts
, scriptable_hosts
);
611 // Set the API or Manifest permissions.
612 // The format of api_values is:
613 // [ "permission_name1", // permissions do not support detail.
614 // "permission_name2",
615 // {"permission_name3": value },
616 // // permission supports detail, permission detail will be stored in value.
620 static base::ListValue
* CreatePermissionList(const T
& permissions
) {
621 base::ListValue
* values
= new base::ListValue();
622 for (typename
T::const_iterator i
= permissions
.begin();
623 i
!= permissions
.end(); ++i
) {
624 scoped_ptr
<base::Value
> detail(i
->ToValue());
626 base::DictionaryValue
* tmp
= new base::DictionaryValue();
627 tmp
->Set(i
->name(), detail
.release());
630 values
->Append(new base::StringValue(i
->name()));
636 void ExtensionPrefs::SetExtensionPrefPermissionSet(
637 const std::string
& extension_id
,
638 const std::string
& pref_key
,
639 const PermissionSet
* new_value
) {
640 std::string api_pref
= JoinPrefs(pref_key
, kPrefAPIs
);
641 base::ListValue
* api_values
= CreatePermissionList(new_value
->apis());
642 UpdateExtensionPref(extension_id
, api_pref
, api_values
);
644 std::string manifest_permissions_pref
=
645 JoinPrefs(pref_key
, kPrefManifestPermissions
);
646 base::ListValue
* manifest_permissions_values
= CreatePermissionList(
647 new_value
->manifest_permissions());
648 UpdateExtensionPref(extension_id
,
649 manifest_permissions_pref
,
650 manifest_permissions_values
);
652 // Set the explicit host permissions.
653 if (!new_value
->explicit_hosts().is_empty()) {
654 SetExtensionPrefURLPatternSet(extension_id
,
655 JoinPrefs(pref_key
, kPrefExplicitHosts
),
656 new_value
->explicit_hosts());
659 // Set the scriptable host permissions.
660 if (!new_value
->scriptable_hosts().is_empty()) {
661 SetExtensionPrefURLPatternSet(extension_id
,
662 JoinPrefs(pref_key
, kPrefScriptableHosts
),
663 new_value
->scriptable_hosts());
667 int ExtensionPrefs::IncrementAcknowledgePromptCount(
668 const std::string
& extension_id
) {
670 ReadPrefAsInteger(extension_id
, kPrefAcknowledgePromptCount
, &count
);
672 UpdateExtensionPref(extension_id
, kPrefAcknowledgePromptCount
,
673 new base::FundamentalValue(count
));
677 bool ExtensionPrefs::IsExternalExtensionAcknowledged(
678 const std::string
& extension_id
) {
679 return ReadPrefAsBooleanAndReturn(extension_id
, kPrefExternalAcknowledged
);
682 void ExtensionPrefs::AcknowledgeExternalExtension(
683 const std::string
& extension_id
) {
684 DCHECK(Extension::IdIsValid(extension_id
));
685 UpdateExtensionPref(extension_id
, kPrefExternalAcknowledged
,
686 new base::FundamentalValue(true));
687 UpdateExtensionPref(extension_id
, kPrefAcknowledgePromptCount
, NULL
);
690 bool ExtensionPrefs::IsBlacklistedExtensionAcknowledged(
691 const std::string
& extension_id
) {
692 return ReadPrefAsBooleanAndReturn(extension_id
, kPrefBlacklistAcknowledged
);
695 void ExtensionPrefs::AcknowledgeBlacklistedExtension(
696 const std::string
& extension_id
) {
697 DCHECK(Extension::IdIsValid(extension_id
));
698 UpdateExtensionPref(extension_id
, kPrefBlacklistAcknowledged
,
699 new base::FundamentalValue(true));
700 UpdateExtensionPref(extension_id
, kPrefAcknowledgePromptCount
, NULL
);
703 bool ExtensionPrefs::IsExternalInstallFirstRun(
704 const std::string
& extension_id
) {
705 return ReadPrefAsBooleanAndReturn(extension_id
, kPrefExternalInstallFirstRun
);
708 void ExtensionPrefs::SetExternalInstallFirstRun(
709 const std::string
& extension_id
) {
710 DCHECK(Extension::IdIsValid(extension_id
));
711 UpdateExtensionPref(extension_id
, kPrefExternalInstallFirstRun
,
712 new base::FundamentalValue(true));
715 bool ExtensionPrefs::HasWipeoutBeenAcknowledged(
716 const std::string
& extension_id
) {
717 return ReadPrefAsBooleanAndReturn(extension_id
, kPrefWipeoutAcknowledged
);
720 void ExtensionPrefs::SetWipeoutAcknowledged(
721 const std::string
& extension_id
,
723 UpdateExtensionPref(extension_id
, kPrefWipeoutAcknowledged
,
724 value
? base::Value::CreateBooleanValue(value
) : NULL
);
727 bool ExtensionPrefs::HasSettingsApiBubbleBeenAcknowledged(
728 const std::string
& extension_id
) {
729 return ReadPrefAsBooleanAndReturn(extension_id
,
730 kPrefSettingsBubbleAcknowledged
);
733 void ExtensionPrefs::SetSettingsApiBubbleBeenAcknowledged(
734 const std::string
& extension_id
,
736 UpdateExtensionPref(extension_id
,
737 kPrefSettingsBubbleAcknowledged
,
738 value
? base::Value::CreateBooleanValue(value
) : NULL
);
741 bool ExtensionPrefs::SetAlertSystemFirstRun() {
742 if (prefs_
->GetBoolean(pref_names::kAlertsInitialized
)) {
745 prefs_
->SetBoolean(pref_names::kAlertsInitialized
, true);
749 bool ExtensionPrefs::ExtensionsBlacklistedByDefault() const {
750 return admin_policy::BlacklistedByDefault(
751 prefs_
->GetList(pref_names::kInstallDenyList
));
754 bool ExtensionPrefs::DidExtensionEscalatePermissions(
755 const std::string
& extension_id
) {
756 return ReadPrefAsBooleanAndReturn(extension_id
,
757 kExtensionDidEscalatePermissions
);
760 void ExtensionPrefs::SetDidExtensionEscalatePermissions(
761 const Extension
* extension
, bool did_escalate
) {
762 UpdateExtensionPref(extension
->id(), kExtensionDidEscalatePermissions
,
763 new base::FundamentalValue(did_escalate
));
766 int ExtensionPrefs::GetDisableReasons(const std::string
& extension_id
) const {
768 if (ReadPrefAsInteger(extension_id
, kPrefDisableReasons
, &value
) &&
772 return Extension::DISABLE_NONE
;
775 void ExtensionPrefs::AddDisableReason(const std::string
& extension_id
,
776 Extension::DisableReason disable_reason
) {
777 ModifyDisableReason(extension_id
, disable_reason
, DISABLE_REASON_ADD
);
780 void ExtensionPrefs::RemoveDisableReason(
781 const std::string
& extension_id
,
782 Extension::DisableReason disable_reason
) {
783 ModifyDisableReason(extension_id
, disable_reason
, DISABLE_REASON_REMOVE
);
786 void ExtensionPrefs::ClearDisableReasons(const std::string
& extension_id
) {
788 extension_id
, Extension::DISABLE_NONE
, DISABLE_REASON_CLEAR
);
791 void ExtensionPrefs::ModifyDisableReason(const std::string
& extension_id
,
792 Extension::DisableReason reason
,
793 DisableReasonChange change
) {
794 int old_value
= GetDisableReasons(extension_id
);
795 int new_value
= old_value
;
797 case DISABLE_REASON_ADD
:
798 new_value
|= static_cast<int>(reason
);
800 case DISABLE_REASON_REMOVE
:
801 new_value
&= ~static_cast<int>(reason
);
803 case DISABLE_REASON_CLEAR
:
804 new_value
= Extension::DISABLE_NONE
;
808 if (old_value
== new_value
) // no change, return.
811 if (new_value
== Extension::DISABLE_NONE
) {
812 UpdateExtensionPref(extension_id
, kPrefDisableReasons
, NULL
);
814 UpdateExtensionPref(extension_id
,
816 new base::FundamentalValue(new_value
));
819 FOR_EACH_OBSERVER(ExtensionPrefsObserver
,
821 OnExtensionDisableReasonsChanged(extension_id
, new_value
));
824 std::set
<std::string
> ExtensionPrefs::GetBlacklistedExtensions() {
825 std::set
<std::string
> ids
;
827 const base::DictionaryValue
* extensions
=
828 prefs_
->GetDictionary(pref_names::kExtensions
);
832 for (base::DictionaryValue::Iterator
it(*extensions
);
833 !it
.IsAtEnd(); it
.Advance()) {
834 if (!it
.value().IsType(base::Value::TYPE_DICTIONARY
)) {
835 NOTREACHED() << "Invalid pref for extension " << it
.key();
838 if (IsBlacklistBitSet(
839 static_cast<const base::DictionaryValue
*>(&it
.value()))) {
840 ids
.insert(it
.key());
847 void ExtensionPrefs::SetExtensionBlacklisted(const std::string
& extension_id
,
848 bool is_blacklisted
) {
849 bool currently_blacklisted
= IsExtensionBlacklisted(extension_id
);
850 if (is_blacklisted
== currently_blacklisted
)
853 // Always make sure the "acknowledged" bit is cleared since the blacklist bit
855 UpdateExtensionPref(extension_id
, kPrefBlacklistAcknowledged
, NULL
);
857 if (is_blacklisted
) {
858 UpdateExtensionPref(extension_id
,
860 new base::FundamentalValue(true));
862 UpdateExtensionPref(extension_id
, kPrefBlacklist
, NULL
);
863 const base::DictionaryValue
* dict
= GetExtensionPref(extension_id
);
864 if (dict
&& dict
->empty())
865 DeleteExtensionPrefs(extension_id
);
869 bool ExtensionPrefs::IsExtensionBlacklisted(const std::string
& id
) const {
870 const base::DictionaryValue
* ext_prefs
= GetExtensionPref(id
);
871 return ext_prefs
&& IsBlacklistBitSet(ext_prefs
);
876 // Serializes |time| as a string value mapped to |key| in |dictionary|.
877 void SaveTime(base::DictionaryValue
* dictionary
,
879 const base::Time
& time
) {
882 std::string string_value
= base::Int64ToString(time
.ToInternalValue());
883 dictionary
->SetString(key
, string_value
);
886 // The opposite of SaveTime. If |key| is not found, this returns an empty Time
887 // (is_null() will return true).
888 base::Time
ReadTime(const base::DictionaryValue
* dictionary
, const char* key
) {
891 std::string string_value
;
893 if (dictionary
->GetString(key
, &string_value
)) {
894 if (base::StringToInt64(string_value
, &value
)) {
895 return base::Time::FromInternalValue(value
);
903 base::Time
ExtensionPrefs::LastPingDay(const std::string
& extension_id
) const {
904 DCHECK(Extension::IdIsValid(extension_id
));
905 return ReadTime(GetExtensionPref(extension_id
), kLastPingDay
);
908 void ExtensionPrefs::SetLastPingDay(const std::string
& extension_id
,
909 const base::Time
& time
) {
910 DCHECK(Extension::IdIsValid(extension_id
));
911 ScopedExtensionPrefUpdate
update(prefs_
, extension_id
);
912 SaveTime(update
.Get(), kLastPingDay
, time
);
915 base::Time
ExtensionPrefs::BlacklistLastPingDay() const {
916 return ReadTime(prefs_
->GetDictionary(kExtensionsBlacklistUpdate
),
920 void ExtensionPrefs::SetBlacklistLastPingDay(const base::Time
& time
) {
921 DictionaryPrefUpdate
update(prefs_
, kExtensionsBlacklistUpdate
);
922 SaveTime(update
.Get(), kLastPingDay
, time
);
925 base::Time
ExtensionPrefs::LastActivePingDay(const std::string
& extension_id
) {
926 DCHECK(Extension::IdIsValid(extension_id
));
927 return ReadTime(GetExtensionPref(extension_id
), kLastActivePingDay
);
930 void ExtensionPrefs::SetLastActivePingDay(const std::string
& extension_id
,
931 const base::Time
& time
) {
932 DCHECK(Extension::IdIsValid(extension_id
));
933 ScopedExtensionPrefUpdate
update(prefs_
, extension_id
);
934 SaveTime(update
.Get(), kLastActivePingDay
, time
);
937 bool ExtensionPrefs::GetActiveBit(const std::string
& extension_id
) {
938 const base::DictionaryValue
* dictionary
= GetExtensionPref(extension_id
);
940 if (dictionary
&& dictionary
->GetBoolean(kActiveBit
, &result
))
945 void ExtensionPrefs::SetActiveBit(const std::string
& extension_id
,
947 UpdateExtensionPref(extension_id
, kActiveBit
,
948 new base::FundamentalValue(active
));
951 void ExtensionPrefs::MigratePermissions(const ExtensionIdList
& extension_ids
) {
952 PermissionsInfo
* info
= PermissionsInfo::GetInstance();
953 for (ExtensionIdList::const_iterator ext_id
=
954 extension_ids
.begin(); ext_id
!= extension_ids
.end(); ++ext_id
) {
955 // An extension's granted permissions need to be migrated if the
956 // full_access bit is present. This bit was always present in the previous
957 // scheme and is never present now.
959 const base::DictionaryValue
* ext
= GetExtensionPref(*ext_id
);
960 if (!ext
|| !ext
->GetBoolean(kPrefOldGrantedFullAccess
, &full_access
))
963 // Remove the full access bit (empty list will get trimmed).
965 *ext_id
, kPrefOldGrantedFullAccess
, new base::ListValue());
967 // Add the plugin permission if the full access bit was set.
969 const base::ListValue
* apis
= NULL
;
970 base::ListValue
* new_apis
= NULL
;
972 std::string granted_apis
= JoinPrefs(kPrefGrantedPermissions
, kPrefAPIs
);
973 if (ext
->GetList(kPrefOldGrantedAPIs
, &apis
))
974 new_apis
= apis
->DeepCopy();
976 new_apis
= new base::ListValue();
978 std::string plugin_name
= info
->GetByID(APIPermission::kPlugin
)->name();
979 new_apis
->Append(new base::StringValue(plugin_name
));
980 UpdateExtensionPref(*ext_id
, granted_apis
, new_apis
);
983 // The granted permissions originally only held the effective hosts,
984 // which are a combination of host and user script host permissions.
985 // We now maintain these lists separately. For migration purposes, it
986 // does not matter how we treat the old effective hosts as long as the
987 // new effective hosts will be the same, so we move them to explicit
989 const base::ListValue
* hosts
= NULL
;
990 std::string explicit_hosts
=
991 JoinPrefs(kPrefGrantedPermissions
, kPrefExplicitHosts
);
992 if (ext
->GetList(kPrefOldGrantedHosts
, &hosts
)) {
994 *ext_id
, explicit_hosts
, hosts
->DeepCopy());
996 // We can get rid of the old one by setting it to an empty list.
997 UpdateExtensionPref(*ext_id
, kPrefOldGrantedHosts
, new base::ListValue());
1002 void ExtensionPrefs::MigrateDisableReasons(
1003 const ExtensionIdList
& extension_ids
) {
1004 for (ExtensionIdList::const_iterator ext_id
=
1005 extension_ids
.begin(); ext_id
!= extension_ids
.end(); ++ext_id
) {
1007 if (ReadPrefAsInteger(*ext_id
, kDeprecatedPrefDisableReason
, &value
)) {
1008 int new_value
= Extension::DISABLE_NONE
;
1010 case Extension::DEPRECATED_DISABLE_USER_ACTION
:
1011 new_value
= Extension::DISABLE_USER_ACTION
;
1013 case Extension::DEPRECATED_DISABLE_PERMISSIONS_INCREASE
:
1014 new_value
= Extension::DISABLE_PERMISSIONS_INCREASE
;
1016 case Extension::DEPRECATED_DISABLE_RELOAD
:
1017 new_value
= Extension::DISABLE_RELOAD
;
1021 UpdateExtensionPref(*ext_id
, kPrefDisableReasons
,
1022 new base::FundamentalValue(new_value
));
1023 // Remove the old disable reason.
1024 UpdateExtensionPref(*ext_id
, kDeprecatedPrefDisableReason
, NULL
);
1029 PermissionSet
* ExtensionPrefs::GetGrantedPermissions(
1030 const std::string
& extension_id
) {
1031 CHECK(Extension::IdIsValid(extension_id
));
1032 return ReadPrefAsPermissionSet(extension_id
, kPrefGrantedPermissions
);
1035 void ExtensionPrefs::AddGrantedPermissions(
1036 const std::string
& extension_id
,
1037 const PermissionSet
* permissions
) {
1038 CHECK(Extension::IdIsValid(extension_id
));
1040 scoped_refptr
<PermissionSet
> granted_permissions(
1041 GetGrantedPermissions(extension_id
));
1043 // The new granted permissions are the union of the already granted
1044 // permissions and the newly granted permissions.
1045 scoped_refptr
<PermissionSet
> new_perms(
1046 PermissionSet::CreateUnion(
1047 permissions
, granted_permissions
.get()));
1049 SetExtensionPrefPermissionSet(
1050 extension_id
, kPrefGrantedPermissions
, new_perms
.get());
1053 void ExtensionPrefs::RemoveGrantedPermissions(
1054 const std::string
& extension_id
,
1055 const PermissionSet
* permissions
) {
1056 CHECK(Extension::IdIsValid(extension_id
));
1058 scoped_refptr
<PermissionSet
> granted_permissions(
1059 GetGrantedPermissions(extension_id
));
1061 // The new granted permissions are the difference of the already granted
1062 // permissions and the newly ungranted permissions.
1063 scoped_refptr
<PermissionSet
> new_perms(
1064 PermissionSet::CreateDifference(
1065 granted_permissions
.get(), permissions
));
1067 SetExtensionPrefPermissionSet(
1068 extension_id
, kPrefGrantedPermissions
, new_perms
.get());
1071 PermissionSet
* ExtensionPrefs::GetActivePermissions(
1072 const std::string
& extension_id
) {
1073 CHECK(Extension::IdIsValid(extension_id
));
1074 return ReadPrefAsPermissionSet(extension_id
, kPrefActivePermissions
);
1077 void ExtensionPrefs::SetActivePermissions(
1078 const std::string
& extension_id
,
1079 const PermissionSet
* permissions
) {
1080 SetExtensionPrefPermissionSet(
1081 extension_id
, kPrefActivePermissions
, permissions
);
1084 void ExtensionPrefs::SetExtensionRunning(const std::string
& extension_id
,
1086 base::Value
* value
= new base::FundamentalValue(is_running
);
1087 UpdateExtensionPref(extension_id
, kPrefRunning
, value
);
1090 bool ExtensionPrefs::IsExtensionRunning(const std::string
& extension_id
) {
1091 const base::DictionaryValue
* extension
= GetExtensionPref(extension_id
);
1094 bool running
= false;
1095 extension
->GetBoolean(kPrefRunning
, &running
);
1099 void ExtensionPrefs::SetIsActive(const std::string
& extension_id
,
1101 base::Value
* value
= new base::FundamentalValue(is_active
);
1102 UpdateExtensionPref(extension_id
, kIsActive
, value
);
1105 bool ExtensionPrefs::IsActive(const std::string
& extension_id
) {
1106 const base::DictionaryValue
* extension
= GetExtensionPref(extension_id
);
1109 bool is_active
= false;
1110 extension
->GetBoolean(kIsActive
, &is_active
);
1114 bool ExtensionPrefs::IsIncognitoEnabled(const std::string
& extension_id
) const {
1115 return ReadPrefAsBooleanAndReturn(extension_id
, kPrefIncognitoEnabled
);
1118 void ExtensionPrefs::SetIsIncognitoEnabled(const std::string
& extension_id
,
1120 UpdateExtensionPref(extension_id
, kPrefIncognitoEnabled
,
1121 new base::FundamentalValue(enabled
));
1122 extension_pref_value_map_
->SetExtensionIncognitoState(extension_id
, enabled
);
1125 bool ExtensionPrefs::AllowFileAccess(const std::string
& extension_id
) const {
1126 return ReadPrefAsBooleanAndReturn(extension_id
, kPrefAllowFileAccess
);
1129 void ExtensionPrefs::SetAllowFileAccess(const std::string
& extension_id
,
1131 UpdateExtensionPref(extension_id
, kPrefAllowFileAccess
,
1132 new base::FundamentalValue(allow
));
1135 bool ExtensionPrefs::HasAllowFileAccessSetting(
1136 const std::string
& extension_id
) const {
1137 const base::DictionaryValue
* ext
= GetExtensionPref(extension_id
);
1138 return ext
&& ext
->HasKey(kPrefAllowFileAccess
);
1141 bool ExtensionPrefs::DoesExtensionHaveState(
1142 const std::string
& id
, Extension::State check_state
) const {
1143 const base::DictionaryValue
* extension
= GetExtensionPref(id
);
1145 if (!extension
|| !extension
->GetInteger(kPrefState
, &state
))
1148 if (state
< 0 || state
>= Extension::NUM_STATES
) {
1149 LOG(ERROR
) << "Bad pref 'state' for extension '" << id
<< "'";
1153 return state
== check_state
;
1156 bool ExtensionPrefs::IsExternalExtensionUninstalled(
1157 const std::string
& id
) const {
1158 return DoesExtensionHaveState(id
, Extension::EXTERNAL_EXTENSION_UNINSTALLED
);
1161 bool ExtensionPrefs::IsExtensionDisabled(
1162 const std::string
& id
) const {
1163 return DoesExtensionHaveState(id
, Extension::DISABLED
);
1166 ExtensionIdList
ExtensionPrefs::GetToolbarOrder() {
1167 ExtensionIdList id_list_out
;
1168 GetUserExtensionPrefIntoContainer(pref_names::kToolbar
, &id_list_out
);
1172 void ExtensionPrefs::SetToolbarOrder(const ExtensionIdList
& extension_ids
) {
1173 SetExtensionPrefFromContainer(pref_names::kToolbar
, extension_ids
);
1176 bool ExtensionPrefs::GetKnownDisabled(ExtensionIdSet
* id_set_out
) {
1177 return GetUserExtensionPrefIntoContainer(pref_names::kKnownDisabled
,
1181 void ExtensionPrefs::SetKnownDisabled(const ExtensionIdSet
& extension_ids
) {
1182 SetExtensionPrefFromContainer(pref_names::kKnownDisabled
, extension_ids
);
1185 void ExtensionPrefs::OnExtensionInstalled(
1186 const Extension
* extension
,
1187 Extension::State initial_state
,
1188 bool blacklisted_for_malware
,
1189 const syncer::StringOrdinal
& page_ordinal
,
1190 const std::string
& install_parameter
) {
1191 ScopedExtensionPrefUpdate
update(prefs_
, extension
->id());
1192 base::DictionaryValue
* extension_dict
= update
.Get();
1193 const base::Time install_time
= time_provider_
->GetCurrentTime();
1194 PopulateExtensionInfoPrefs(extension
,
1197 blacklisted_for_malware
,
1200 FinishExtensionInfoPrefs(extension
->id(), install_time
,
1201 extension
->RequiresSortOrdinal(),
1202 page_ordinal
, extension_dict
);
1205 void ExtensionPrefs::OnExtensionUninstalled(const std::string
& extension_id
,
1206 const Manifest::Location
& location
,
1207 bool external_uninstall
) {
1208 app_sorting_
->ClearOrdinals(extension_id
);
1210 // For external extensions, we save a preference reminding ourself not to try
1211 // and install the extension anymore (except when |external_uninstall| is
1212 // true, which signifies that the registry key was deleted or the pref file
1213 // no longer lists the extension).
1214 if (!external_uninstall
&& Manifest::IsExternalLocation(location
)) {
1215 UpdateExtensionPref(extension_id
, kPrefState
,
1216 new base::FundamentalValue(
1217 Extension::EXTERNAL_EXTENSION_UNINSTALLED
));
1218 extension_pref_value_map_
->SetExtensionState(extension_id
, false);
1219 FOR_EACH_OBSERVER(ExtensionPrefsObserver
,
1221 OnExtensionStateChanged(extension_id
, false));
1223 int creation_flags
= GetCreationFlags(extension_id
);
1224 if (creation_flags
& Extension::IS_EPHEMERAL
) {
1225 // Keep ephemeral apps around, but mark them as evicted.
1226 UpdateExtensionPref(extension_id
, kPrefEvictedEphemeralApp
,
1227 new base::FundamentalValue(true));
1229 DeleteExtensionPrefs(extension_id
);
1234 void ExtensionPrefs::SetExtensionState(const std::string
& extension_id
,
1235 Extension::State state
) {
1236 UpdateExtensionPref(extension_id
, kPrefState
,
1237 new base::FundamentalValue(state
));
1238 bool enabled
= (state
== Extension::ENABLED
);
1239 extension_pref_value_map_
->SetExtensionState(extension_id
, enabled
);
1240 FOR_EACH_OBSERVER(ExtensionPrefsObserver
,
1242 OnExtensionStateChanged(extension_id
, enabled
));
1245 void ExtensionPrefs::SetExtensionBlacklistState(const std::string
& extension_id
,
1246 BlacklistState state
) {
1247 SetExtensionBlacklisted(extension_id
, state
== BLACKLISTED_MALWARE
);
1248 UpdateExtensionPref(extension_id
, kPrefBlacklistState
,
1249 new base::FundamentalValue(state
));
1252 BlacklistState
ExtensionPrefs::GetExtensionBlacklistState(
1253 const std::string
& extension_id
) {
1254 if (IsExtensionBlacklisted(extension_id
))
1255 return BLACKLISTED_MALWARE
;
1256 const base::DictionaryValue
* ext_prefs
= GetExtensionPref(extension_id
);
1258 if (ext_prefs
&& ext_prefs
->GetInteger(kPrefBlacklistState
, &int_value
))
1259 return static_cast<BlacklistState
>(int_value
);
1261 return NOT_BLACKLISTED
;
1264 std::string
ExtensionPrefs::GetVersionString(const std::string
& extension_id
) {
1265 const base::DictionaryValue
* extension
= GetExtensionPref(extension_id
);
1267 return std::string();
1269 std::string version
;
1270 extension
->GetString(kPrefVersion
, &version
);
1275 void ExtensionPrefs::UpdateManifest(const Extension
* extension
) {
1276 if (!Manifest::IsUnpackedLocation(extension
->location())) {
1277 const base::DictionaryValue
* extension_dict
=
1278 GetExtensionPref(extension
->id());
1279 if (!extension_dict
)
1281 const base::DictionaryValue
* old_manifest
= NULL
;
1282 bool update_required
=
1283 !extension_dict
->GetDictionary(kPrefManifest
, &old_manifest
) ||
1284 !extension
->manifest()->value()->Equals(old_manifest
);
1285 if (update_required
) {
1286 UpdateExtensionPref(extension
->id(), kPrefManifest
,
1287 extension
->manifest()->value()->DeepCopy());
1292 base::FilePath
ExtensionPrefs::GetExtensionPath(
1293 const std::string
& extension_id
) {
1294 const base::DictionaryValue
* dict
= GetExtensionPref(extension_id
);
1296 return base::FilePath();
1299 if (!dict
->GetString(kPrefPath
, &path
))
1300 return base::FilePath();
1302 return install_directory_
.Append(base::FilePath::FromUTF8Unsafe(path
));
1305 scoped_ptr
<ExtensionInfo
> ExtensionPrefs::GetInstalledInfoHelper(
1306 const std::string
& extension_id
,
1307 const base::DictionaryValue
* extension
) const {
1309 if (!extension
->GetInteger(kPrefLocation
, &location_value
))
1310 return scoped_ptr
<ExtensionInfo
>();
1312 base::FilePath::StringType path
;
1313 if (!extension
->GetString(kPrefPath
, &path
))
1314 return scoped_ptr
<ExtensionInfo
>();
1316 // Make path absolute. Unpacked extensions will already have absolute paths,
1317 // otherwise make it so.
1318 Manifest::Location location
= static_cast<Manifest::Location
>(location_value
);
1319 if (!Manifest::IsUnpackedLocation(location
)) {
1320 DCHECK(location
== Manifest::COMPONENT
||
1321 !base::FilePath(path
).IsAbsolute());
1322 path
= install_directory_
.Append(path
).value();
1325 // Only the following extension types have data saved in the preferences.
1326 if (location
!= Manifest::INTERNAL
&&
1327 !Manifest::IsUnpackedLocation(location
) &&
1328 !Manifest::IsExternalLocation(location
)) {
1330 return scoped_ptr
<ExtensionInfo
>();
1333 const base::DictionaryValue
* manifest
= NULL
;
1334 if (!Manifest::IsUnpackedLocation(location
) &&
1335 !extension
->GetDictionary(kPrefManifest
, &manifest
)) {
1336 LOG(WARNING
) << "Missing manifest for extension " << extension_id
;
1337 // Just a warning for now.
1340 return scoped_ptr
<ExtensionInfo
>(new ExtensionInfo(
1341 manifest
, extension_id
, base::FilePath(path
), location
));
1344 scoped_ptr
<ExtensionInfo
> ExtensionPrefs::GetInstalledExtensionInfo(
1345 const std::string
& extension_id
) const {
1346 const base::DictionaryValue
* ext
= NULL
;
1347 const base::DictionaryValue
* extensions
=
1348 prefs_
->GetDictionary(pref_names::kExtensions
);
1350 !extensions
->GetDictionaryWithoutPathExpansion(extension_id
, &ext
))
1351 return scoped_ptr
<ExtensionInfo
>();
1353 if (!ext
->GetInteger(kPrefState
, &state_value
) ||
1354 state_value
== Extension::ENABLED_COMPONENT
) {
1355 // Old preferences files may not have kPrefState for component extensions.
1356 return scoped_ptr
<ExtensionInfo
>();
1359 if (state_value
== Extension::EXTERNAL_EXTENSION_UNINSTALLED
) {
1360 LOG(WARNING
) << "External extension with id " << extension_id
1361 << " has been uninstalled by the user";
1362 return scoped_ptr
<ExtensionInfo
>();
1365 if (IsEvictedEphemeralApp(ext
)) {
1366 // Hide evicted ephemeral apps.
1367 return scoped_ptr
<ExtensionInfo
>();
1370 return GetInstalledInfoHelper(extension_id
, ext
);
1373 scoped_ptr
<ExtensionPrefs::ExtensionsInfo
>
1374 ExtensionPrefs::GetInstalledExtensionsInfo() const {
1375 scoped_ptr
<ExtensionsInfo
> extensions_info(new ExtensionsInfo
);
1377 const base::DictionaryValue
* extensions
=
1378 prefs_
->GetDictionary(pref_names::kExtensions
);
1379 for (base::DictionaryValue::Iterator
extension_id(*extensions
);
1380 !extension_id
.IsAtEnd(); extension_id
.Advance()) {
1381 if (!Extension::IdIsValid(extension_id
.key()))
1384 scoped_ptr
<ExtensionInfo
> info
=
1385 GetInstalledExtensionInfo(extension_id
.key());
1387 extensions_info
->push_back(linked_ptr
<ExtensionInfo
>(info
.release()));
1390 return extensions_info
.Pass();
1393 scoped_ptr
<ExtensionPrefs::ExtensionsInfo
>
1394 ExtensionPrefs::GetUninstalledExtensionsInfo() const {
1395 scoped_ptr
<ExtensionsInfo
> extensions_info(new ExtensionsInfo
);
1397 const base::DictionaryValue
* extensions
=
1398 prefs_
->GetDictionary(pref_names::kExtensions
);
1399 for (base::DictionaryValue::Iterator
extension_id(*extensions
);
1400 !extension_id
.IsAtEnd(); extension_id
.Advance()) {
1401 const base::DictionaryValue
* ext
= NULL
;
1402 if (!Extension::IdIsValid(extension_id
.key()) ||
1403 !IsExternalExtensionUninstalled(extension_id
.key()) ||
1404 !extension_id
.value().GetAsDictionary(&ext
))
1407 scoped_ptr
<ExtensionInfo
> info
=
1408 GetInstalledInfoHelper(extension_id
.key(), ext
);
1410 extensions_info
->push_back(linked_ptr
<ExtensionInfo
>(info
.release()));
1413 return extensions_info
.Pass();
1416 void ExtensionPrefs::SetDelayedInstallInfo(
1417 const Extension
* extension
,
1418 Extension::State initial_state
,
1419 bool blacklisted_for_malware
,
1420 DelayReason delay_reason
,
1421 const syncer::StringOrdinal
& page_ordinal
,
1422 const std::string
& install_parameter
) {
1423 base::DictionaryValue
* extension_dict
= new base::DictionaryValue();
1424 PopulateExtensionInfoPrefs(extension
,
1425 time_provider_
->GetCurrentTime(),
1427 blacklisted_for_malware
,
1431 // Add transient data that is needed by FinishDelayedInstallInfo(), but
1432 // should not be in the final extension prefs. All entries here should have
1433 // a corresponding Remove() call in FinishDelayedInstallInfo().
1434 if (extension
->RequiresSortOrdinal()) {
1435 extension_dict
->SetString(
1436 kPrefSuggestedPageOrdinal
,
1437 page_ordinal
.IsValid() ? page_ordinal
.ToInternalValue()
1440 extension_dict
->SetInteger(kDelayedInstallReason
,
1441 static_cast<int>(delay_reason
));
1443 UpdateExtensionPref(extension
->id(), kDelayedInstallInfo
, extension_dict
);
1446 bool ExtensionPrefs::RemoveDelayedInstallInfo(
1447 const std::string
& extension_id
) {
1448 if (!GetExtensionPref(extension_id
))
1450 ScopedExtensionPrefUpdate
update(prefs_
, extension_id
);
1451 bool result
= update
->Remove(kDelayedInstallInfo
, NULL
);
1455 bool ExtensionPrefs::FinishDelayedInstallInfo(
1456 const std::string
& extension_id
) {
1457 CHECK(Extension::IdIsValid(extension_id
));
1458 ScopedExtensionPrefUpdate
update(prefs_
, extension_id
);
1459 base::DictionaryValue
* extension_dict
= update
.Get();
1460 base::DictionaryValue
* pending_install_dict
= NULL
;
1461 if (!extension_dict
->GetDictionary(kDelayedInstallInfo
,
1462 &pending_install_dict
)) {
1466 // Retrieve and clear transient values populated by SetDelayedInstallInfo().
1467 // Also do any other data cleanup that makes sense.
1468 std::string serialized_ordinal
;
1469 syncer::StringOrdinal suggested_page_ordinal
;
1470 bool needs_sort_ordinal
= false;
1471 if (pending_install_dict
->GetString(kPrefSuggestedPageOrdinal
,
1472 &serialized_ordinal
)) {
1473 suggested_page_ordinal
= syncer::StringOrdinal(serialized_ordinal
);
1474 needs_sort_ordinal
= true;
1475 pending_install_dict
->Remove(kPrefSuggestedPageOrdinal
, NULL
);
1477 pending_install_dict
->Remove(kDelayedInstallReason
, NULL
);
1479 const base::Time install_time
= time_provider_
->GetCurrentTime();
1480 pending_install_dict
->Set(
1482 new base::StringValue(
1483 base::Int64ToString(install_time
.ToInternalValue())));
1485 // Commit the delayed install data.
1486 for (base::DictionaryValue::Iterator
it(*pending_install_dict
); !it
.IsAtEnd();
1488 extension_dict
->Set(it
.key(), it
.value().DeepCopy());
1490 FinishExtensionInfoPrefs(extension_id
, install_time
, needs_sort_ordinal
,
1491 suggested_page_ordinal
, extension_dict
);
1495 scoped_ptr
<ExtensionInfo
> ExtensionPrefs::GetDelayedInstallInfo(
1496 const std::string
& extension_id
) const {
1497 const base::DictionaryValue
* extension_prefs
=
1498 GetExtensionPref(extension_id
);
1499 if (!extension_prefs
)
1500 return scoped_ptr
<ExtensionInfo
>();
1502 const base::DictionaryValue
* ext
= NULL
;
1503 if (!extension_prefs
->GetDictionary(kDelayedInstallInfo
, &ext
))
1504 return scoped_ptr
<ExtensionInfo
>();
1506 return GetInstalledInfoHelper(extension_id
, ext
);
1509 ExtensionPrefs::DelayReason
ExtensionPrefs::GetDelayedInstallReason(
1510 const std::string
& extension_id
) const {
1511 const base::DictionaryValue
* extension_prefs
=
1512 GetExtensionPref(extension_id
);
1513 if (!extension_prefs
)
1514 return DELAY_REASON_NONE
;
1516 const base::DictionaryValue
* ext
= NULL
;
1517 if (!extension_prefs
->GetDictionary(kDelayedInstallInfo
, &ext
))
1518 return DELAY_REASON_NONE
;
1521 if (!ext
->GetInteger(kDelayedInstallReason
, &delay_reason
))
1522 return DELAY_REASON_NONE
;
1524 return static_cast<DelayReason
>(delay_reason
);
1527 scoped_ptr
<ExtensionPrefs::ExtensionsInfo
> ExtensionPrefs::
1528 GetAllDelayedInstallInfo() const {
1529 scoped_ptr
<ExtensionsInfo
> extensions_info(new ExtensionsInfo
);
1531 const base::DictionaryValue
* extensions
=
1532 prefs_
->GetDictionary(pref_names::kExtensions
);
1533 for (base::DictionaryValue::Iterator
extension_id(*extensions
);
1534 !extension_id
.IsAtEnd(); extension_id
.Advance()) {
1535 if (!Extension::IdIsValid(extension_id
.key()))
1538 scoped_ptr
<ExtensionInfo
> info
= GetDelayedInstallInfo(extension_id
.key());
1540 extensions_info
->push_back(linked_ptr
<ExtensionInfo
>(info
.release()));
1543 return extensions_info
.Pass();
1546 scoped_ptr
<ExtensionPrefs::ExtensionsInfo
>
1547 ExtensionPrefs::GetEvictedEphemeralAppsInfo() const {
1548 scoped_ptr
<ExtensionsInfo
> extensions_info(new ExtensionsInfo
);
1550 const base::DictionaryValue
* extensions
=
1551 prefs_
->GetDictionary(pref_names::kExtensions
);
1552 for (base::DictionaryValue::Iterator
extension_id(*extensions
);
1553 !extension_id
.IsAtEnd(); extension_id
.Advance()) {
1554 const base::DictionaryValue
* ext
= NULL
;
1555 if (!Extension::IdIsValid(extension_id
.key()) ||
1556 !extension_id
.value().GetAsDictionary(&ext
)) {
1560 if (!IsEvictedEphemeralApp(ext
))
1563 scoped_ptr
<ExtensionInfo
> info
=
1564 GetInstalledInfoHelper(extension_id
.key(), ext
);
1566 extensions_info
->push_back(linked_ptr
<ExtensionInfo
>(info
.release()));
1569 return extensions_info
.Pass();
1572 scoped_ptr
<ExtensionInfo
> ExtensionPrefs::GetEvictedEphemeralAppInfo(
1573 const std::string
& extension_id
) const {
1574 const base::DictionaryValue
* extension_prefs
= GetExtensionPref(extension_id
);
1575 if (!extension_prefs
)
1576 return scoped_ptr
<ExtensionInfo
>();
1578 if (!IsEvictedEphemeralApp(extension_prefs
))
1579 return scoped_ptr
<ExtensionInfo
>();
1581 return GetInstalledInfoHelper(extension_id
, extension_prefs
);
1584 void ExtensionPrefs::RemoveEvictedEphemeralApp(
1585 const std::string
& extension_id
) {
1586 bool evicted_ephemeral_app
= false;
1587 if (ReadPrefAsBoolean(extension_id
,
1588 kPrefEvictedEphemeralApp
,
1589 &evicted_ephemeral_app
) && evicted_ephemeral_app
) {
1590 DeleteExtensionPrefs(extension_id
);
1594 bool ExtensionPrefs::WasAppDraggedByUser(const std::string
& extension_id
) {
1595 return ReadPrefAsBooleanAndReturn(extension_id
, kPrefUserDraggedApp
);
1598 void ExtensionPrefs::SetAppDraggedByUser(const std::string
& extension_id
) {
1599 UpdateExtensionPref(extension_id
, kPrefUserDraggedApp
,
1600 new base::FundamentalValue(true));
1603 bool ExtensionPrefs::IsFromWebStore(
1604 const std::string
& extension_id
) const {
1605 const base::DictionaryValue
* dictionary
= GetExtensionPref(extension_id
);
1606 bool result
= false;
1607 if (dictionary
&& dictionary
->GetBoolean(kPrefFromWebStore
, &result
))
1612 bool ExtensionPrefs::IsFromBookmark(
1613 const std::string
& extension_id
) const {
1614 const base::DictionaryValue
* dictionary
= GetExtensionPref(extension_id
);
1615 bool result
= false;
1616 if (dictionary
&& dictionary
->GetBoolean(kPrefFromBookmark
, &result
))
1621 int ExtensionPrefs::GetCreationFlags(const std::string
& extension_id
) const {
1622 int creation_flags
= Extension::NO_FLAGS
;
1623 if (!ReadPrefAsInteger(extension_id
, kPrefCreationFlags
, &creation_flags
)) {
1624 // Since kPrefCreationFlags was added later, it will be missing for
1625 // previously installed extensions.
1626 if (IsFromBookmark(extension_id
))
1627 creation_flags
|= Extension::FROM_BOOKMARK
;
1628 if (IsFromWebStore(extension_id
))
1629 creation_flags
|= Extension::FROM_WEBSTORE
;
1630 if (WasInstalledByDefault(extension_id
))
1631 creation_flags
|= Extension::WAS_INSTALLED_BY_DEFAULT
;
1632 if (WasInstalledByOem(extension_id
))
1633 creation_flags
|= Extension::WAS_INSTALLED_BY_OEM
;
1635 return creation_flags
;
1638 int ExtensionPrefs::GetDelayedInstallCreationFlags(
1639 const std::string
& extension_id
) const {
1640 int creation_flags
= Extension::NO_FLAGS
;
1641 const base::DictionaryValue
* delayed_info
= NULL
;
1642 if (ReadPrefAsDictionary(extension_id
, kDelayedInstallInfo
, &delayed_info
)) {
1643 delayed_info
->GetInteger(kPrefCreationFlags
, &creation_flags
);
1645 return creation_flags
;
1648 bool ExtensionPrefs::WasInstalledByDefault(
1649 const std::string
& extension_id
) const {
1650 const base::DictionaryValue
* dictionary
= GetExtensionPref(extension_id
);
1651 bool result
= false;
1653 dictionary
->GetBoolean(kPrefWasInstalledByDefault
, &result
))
1658 bool ExtensionPrefs::WasInstalledByOem(const std::string
& extension_id
) const {
1659 const base::DictionaryValue
* dictionary
= GetExtensionPref(extension_id
);
1660 bool result
= false;
1661 if (dictionary
&& dictionary
->GetBoolean(kPrefWasInstalledByOem
, &result
))
1666 base::Time
ExtensionPrefs::GetInstallTime(
1667 const std::string
& extension_id
) const {
1668 const base::DictionaryValue
* extension
= GetExtensionPref(extension_id
);
1671 return base::Time();
1673 std::string install_time_str
;
1674 if (!extension
->GetString(kPrefInstallTime
, &install_time_str
))
1675 return base::Time();
1676 int64 install_time_i64
= 0;
1677 if (!base::StringToInt64(install_time_str
, &install_time_i64
))
1678 return base::Time();
1679 return base::Time::FromInternalValue(install_time_i64
);
1682 base::Time
ExtensionPrefs::GetLastLaunchTime(
1683 const std::string
& extension_id
) const {
1684 const base::DictionaryValue
* extension
= GetExtensionPref(extension_id
);
1686 return base::Time();
1688 std::string launch_time_str
;
1689 if (!extension
->GetString(kPrefLastLaunchTime
, &launch_time_str
))
1690 return base::Time();
1691 int64 launch_time_i64
= 0;
1692 if (!base::StringToInt64(launch_time_str
, &launch_time_i64
))
1693 return base::Time();
1694 return base::Time::FromInternalValue(launch_time_i64
);
1697 void ExtensionPrefs::SetLastLaunchTime(const std::string
& extension_id
,
1698 const base::Time
& time
) {
1699 DCHECK(Extension::IdIsValid(extension_id
));
1700 ScopedExtensionPrefUpdate
update(prefs_
, extension_id
);
1701 SaveTime(update
.Get(), kPrefLastLaunchTime
, time
);
1704 void ExtensionPrefs::GetExtensions(ExtensionIdList
* out
) {
1707 scoped_ptr
<ExtensionsInfo
> extensions_info(GetInstalledExtensionsInfo());
1709 for (size_t i
= 0; i
< extensions_info
->size(); ++i
) {
1710 ExtensionInfo
* info
= extensions_info
->at(i
).get();
1711 out
->push_back(info
->extension_id
);
1716 ExtensionIdList
ExtensionPrefs::GetExtensionsFrom(
1717 const PrefService
* pref_service
) {
1718 ExtensionIdList result
;
1720 const base::DictionaryValue
* extension_prefs
= NULL
;
1721 const base::Value
* extension_prefs_value
=
1722 pref_service
->GetUserPrefValue(pref_names::kExtensions
);
1723 if (!extension_prefs_value
||
1724 !extension_prefs_value
->GetAsDictionary(&extension_prefs
)) {
1725 return result
; // Empty set
1728 for (base::DictionaryValue::Iterator
it(*extension_prefs
); !it
.IsAtEnd();
1730 const base::DictionaryValue
* ext
= NULL
;
1731 if (!it
.value().GetAsDictionary(&ext
)) {
1732 NOTREACHED() << "Invalid pref for extension " << it
.key();
1735 if (!IsBlacklistBitSet(ext
))
1736 result
.push_back(it
.key());
1741 void ExtensionPrefs::AddObserver(ExtensionPrefsObserver
* observer
) {
1742 observer_list_
.AddObserver(observer
);
1745 void ExtensionPrefs::RemoveObserver(ExtensionPrefsObserver
* observer
) {
1746 observer_list_
.RemoveObserver(observer
);
1749 void ExtensionPrefs::FixMissingPrefs(const ExtensionIdList
& extension_ids
) {
1750 // Fix old entries that did not get an installation time entry when they
1751 // were installed or don't have a preferences field.
1752 for (ExtensionIdList::const_iterator ext_id
= extension_ids
.begin();
1753 ext_id
!= extension_ids
.end(); ++ext_id
) {
1754 if (GetInstallTime(*ext_id
) == base::Time()) {
1755 VLOG(1) << "Could not parse installation time of extension "
1756 << *ext_id
<< ". It was probably installed before setting "
1757 << kPrefInstallTime
<< " was introduced. Updating "
1758 << kPrefInstallTime
<< " to the current time.";
1759 const base::Time install_time
= time_provider_
->GetCurrentTime();
1760 UpdateExtensionPref(*ext_id
,
1762 new base::StringValue(base::Int64ToString(
1763 install_time
.ToInternalValue())));
1768 void ExtensionPrefs::InitPrefStore() {
1769 if (extensions_disabled_
) {
1770 extension_pref_value_map_
->NotifyInitializationCompleted();
1774 // When this is called, the PrefService is initialized and provides access
1775 // to the user preferences stored in a JSON file.
1776 ExtensionIdList extension_ids
;
1777 GetExtensions(&extension_ids
);
1778 // Create empty preferences dictionary for each extension (these dictionaries
1779 // are pruned when persisting the preferences to disk).
1780 for (ExtensionIdList::iterator ext_id
= extension_ids
.begin();
1781 ext_id
!= extension_ids
.end(); ++ext_id
) {
1782 ScopedExtensionPrefUpdate
update(prefs_
, *ext_id
);
1783 // This creates an empty dictionary if none is stored.
1787 FixMissingPrefs(extension_ids
);
1788 MigratePermissions(extension_ids
);
1789 MigrateDisableReasons(extension_ids
);
1790 app_sorting_
->Initialize(extension_ids
);
1792 InitExtensionControlledPrefs(extension_pref_value_map_
);
1794 extension_pref_value_map_
->NotifyInitializationCompleted();
1797 bool ExtensionPrefs::HasIncognitoPrefValue(const std::string
& pref_key
) {
1798 bool has_incognito_pref_value
= false;
1799 extension_pref_value_map_
->GetEffectivePrefValue(pref_key
,
1801 &has_incognito_pref_value
);
1802 return has_incognito_pref_value
;
1805 URLPatternSet
ExtensionPrefs::GetAllowedInstallSites() {
1806 URLPatternSet result
;
1807 const base::ListValue
* list
=
1808 prefs_
->GetList(pref_names::kAllowedInstallSites
);
1811 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
1812 std::string entry_string
;
1813 URLPattern
entry(URLPattern::SCHEME_ALL
);
1814 if (!list
->GetString(i
, &entry_string
) ||
1815 entry
.Parse(entry_string
) != URLPattern::PARSE_SUCCESS
) {
1816 LOG(ERROR
) << "Invalid value for preference: "
1817 << pref_names::kAllowedInstallSites
<< "." << i
;
1820 result
.AddPattern(entry
);
1826 const base::DictionaryValue
* ExtensionPrefs::GetGeometryCache(
1827 const std::string
& extension_id
) const {
1828 const base::DictionaryValue
* extension_prefs
= GetExtensionPref(extension_id
);
1829 if (!extension_prefs
)
1832 const base::DictionaryValue
* ext
= NULL
;
1833 if (!extension_prefs
->GetDictionary(kPrefGeometryCache
, &ext
))
1839 void ExtensionPrefs::SetGeometryCache(
1840 const std::string
& extension_id
,
1841 scoped_ptr
<base::DictionaryValue
> cache
) {
1842 UpdateExtensionPref(extension_id
, kPrefGeometryCache
, cache
.release());
1845 const base::DictionaryValue
* ExtensionPrefs::GetInstallSignature() {
1846 return prefs_
->GetDictionary(kInstallSignature
);
1849 void ExtensionPrefs::SetInstallSignature(
1850 const base::DictionaryValue
* signature
) {
1852 prefs_
->Set(kInstallSignature
, *signature
);
1853 DVLOG(1) << "SetInstallSignature - saving";
1855 DVLOG(1) << "SetInstallSignature - clearing";
1856 prefs_
->ClearPref(kInstallSignature
);
1860 std::string
ExtensionPrefs::GetInstallParam(
1861 const std::string
& extension_id
) const {
1862 const base::DictionaryValue
* extension
= GetExtensionPref(extension_id
);
1863 if (!extension
) // Expected during unit testing.
1864 return std::string();
1865 std::string install_parameter
;
1866 if (!extension
->GetString(kPrefInstallParam
, &install_parameter
))
1867 return std::string();
1868 return install_parameter
;
1871 void ExtensionPrefs::SetInstallParam(const std::string
& extension_id
,
1872 const std::string
& install_parameter
) {
1873 UpdateExtensionPref(extension_id
,
1875 new base::StringValue(install_parameter
));
1878 ExtensionPrefs::ExtensionPrefs(
1880 const base::FilePath
& root_dir
,
1881 ExtensionPrefValueMap
* extension_pref_value_map
,
1882 scoped_ptr
<AppSorting
> app_sorting
,
1883 scoped_ptr
<TimeProvider
> time_provider
,
1884 bool extensions_disabled
,
1885 const std::vector
<ExtensionPrefsObserver
*>& early_observers
)
1887 install_directory_(root_dir
),
1888 extension_pref_value_map_(extension_pref_value_map
),
1889 app_sorting_(app_sorting
.Pass()),
1890 time_provider_(time_provider
.Pass()),
1891 extensions_disabled_(extensions_disabled
) {
1892 app_sorting_
->SetExtensionScopedPrefs(this);
1893 MakePathsRelative();
1895 // Ensure that any early observers are watching before prefs are initialized.
1896 for (std::vector
<ExtensionPrefsObserver
*>::const_iterator iter
=
1897 early_observers
.begin();
1898 iter
!= early_observers
.end();
1906 void ExtensionPrefs::SetNeedsStorageGarbageCollection(bool value
) {
1907 prefs_
->SetBoolean(pref_names::kStorageGarbageCollect
, value
);
1910 bool ExtensionPrefs::NeedsStorageGarbageCollection() {
1911 return prefs_
->GetBoolean(pref_names::kStorageGarbageCollect
);
1915 void ExtensionPrefs::RegisterProfilePrefs(
1916 user_prefs::PrefRegistrySyncable
* registry
) {
1917 registry
->RegisterDictionaryPref(
1918 pref_names::kExtensions
,
1919 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1920 registry
->RegisterListPref(pref_names::kToolbar
,
1921 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
1922 registry
->RegisterIntegerPref(
1923 pref_names::kToolbarSize
,
1924 -1, // default value
1925 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1926 registry
->RegisterDictionaryPref(
1927 kExtensionsBlacklistUpdate
,
1928 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1929 registry
->RegisterListPref(pref_names::kInstallAllowList
,
1930 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1931 registry
->RegisterListPref(pref_names::kInstallDenyList
,
1932 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1933 registry
->RegisterDictionaryPref(
1934 pref_names::kInstallForceList
,
1935 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1936 registry
->RegisterListPref(pref_names::kAllowedTypes
,
1937 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1938 registry
->RegisterBooleanPref(
1939 pref_names::kStorageGarbageCollect
,
1940 false, // default value
1941 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1942 registry
->RegisterInt64Pref(
1943 pref_names::kLastUpdateCheck
,
1945 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1946 registry
->RegisterInt64Pref(
1947 pref_names::kNextUpdateCheck
,
1949 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1950 registry
->RegisterListPref(pref_names::kAllowedInstallSites
,
1951 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1952 registry
->RegisterStringPref(
1953 pref_names::kLastChromeVersion
,
1954 std::string(), // default value
1955 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1956 registry
->RegisterListPref(pref_names::kKnownDisabled
,
1957 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1958 #if defined(TOOLKIT_VIEWS)
1959 registry
->RegisterIntegerPref(
1960 pref_names::kBrowserActionContainerWidth
,
1962 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1964 registry
->RegisterDictionaryPref(
1966 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1968 registry
->RegisterListPref(pref_names::kNativeMessagingBlacklist
,
1969 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1970 registry
->RegisterListPref(pref_names::kNativeMessagingWhitelist
,
1971 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1972 registry
->RegisterBooleanPref(
1973 pref_names::kNativeMessagingUserLevelHosts
,
1974 true, // default value
1975 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
1978 template <class ExtensionIdContainer
>
1979 bool ExtensionPrefs::GetUserExtensionPrefIntoContainer(
1981 ExtensionIdContainer
* id_container_out
) {
1982 DCHECK(id_container_out
->empty());
1984 const base::Value
* user_pref_value
= prefs_
->GetUserPrefValue(pref
);
1985 const base::ListValue
* user_pref_as_list
;
1986 if (!user_pref_value
|| !user_pref_value
->GetAsList(&user_pref_as_list
))
1989 std::insert_iterator
<ExtensionIdContainer
> insert_iterator(
1990 *id_container_out
, id_container_out
->end());
1991 std::string extension_id
;
1992 for (base::ListValue::const_iterator value_it
= user_pref_as_list
->begin();
1993 value_it
!= user_pref_as_list
->end(); ++value_it
) {
1994 if (!(*value_it
)->GetAsString(&extension_id
)) {
1998 insert_iterator
= extension_id
;
2003 template <class ExtensionIdContainer
>
2004 void ExtensionPrefs::SetExtensionPrefFromContainer(
2006 const ExtensionIdContainer
& strings
) {
2007 ListPrefUpdate
update(prefs_
, pref
);
2008 base::ListValue
* list_of_values
= update
.Get();
2009 list_of_values
->Clear();
2010 for (typename
ExtensionIdContainer::const_iterator iter
= strings
.begin();
2011 iter
!= strings
.end(); ++iter
) {
2012 list_of_values
->Append(new base::StringValue(*iter
));
2016 void ExtensionPrefs::PopulateExtensionInfoPrefs(
2017 const Extension
* extension
,
2018 const base::Time install_time
,
2019 Extension::State initial_state
,
2020 bool blacklisted_for_malware
,
2021 const std::string
& install_parameter
,
2022 base::DictionaryValue
* extension_dict
) {
2023 // Leave the state blank for component extensions so that old chrome versions
2024 // loading new profiles do not fail in GetInstalledExtensionInfo. Older
2025 // Chrome versions would only check for an omitted state.
2026 if (initial_state
!= Extension::ENABLED_COMPONENT
)
2027 extension_dict
->Set(kPrefState
, new base::FundamentalValue(initial_state
));
2029 extension_dict
->Set(kPrefLocation
,
2030 new base::FundamentalValue(extension
->location()));
2031 extension_dict
->Set(kPrefCreationFlags
,
2032 new base::FundamentalValue(extension
->creation_flags()));
2033 extension_dict
->Set(kPrefFromWebStore
,
2034 new base::FundamentalValue(extension
->from_webstore()));
2035 extension_dict
->Set(kPrefFromBookmark
,
2036 new base::FundamentalValue(extension
->from_bookmark()));
2037 extension_dict
->Set(
2038 kPrefWasInstalledByDefault
,
2039 new base::FundamentalValue(extension
->was_installed_by_default()));
2040 extension_dict
->Set(
2041 kPrefWasInstalledByOem
,
2042 new base::FundamentalValue(extension
->was_installed_by_oem()));
2043 extension_dict
->Set(kPrefInstallTime
,
2044 new base::StringValue(
2045 base::Int64ToString(install_time
.ToInternalValue())));
2046 if (blacklisted_for_malware
)
2047 extension_dict
->Set(kPrefBlacklist
, new base::FundamentalValue(true));
2049 base::FilePath::StringType path
= MakePathRelative(install_directory_
,
2051 extension_dict
->Set(kPrefPath
, new base::StringValue(path
));
2052 if (!install_parameter
.empty()) {
2053 extension_dict
->Set(kPrefInstallParam
,
2054 new base::StringValue(install_parameter
));
2056 // We store prefs about LOAD extensions, but don't cache their manifest
2057 // since it may change on disk.
2058 if (!Manifest::IsUnpackedLocation(extension
->location())) {
2059 extension_dict
->Set(kPrefManifest
,
2060 extension
->manifest()->value()->DeepCopy());
2064 void ExtensionPrefs::InitExtensionControlledPrefs(
2065 ExtensionPrefValueMap
* value_map
) {
2066 ExtensionIdList extension_ids
;
2067 GetExtensions(&extension_ids
);
2069 for (ExtensionIdList::iterator extension_id
= extension_ids
.begin();
2070 extension_id
!= extension_ids
.end();
2072 base::Time install_time
= GetInstallTime(*extension_id
);
2073 bool is_enabled
= !IsExtensionDisabled(*extension_id
);
2074 bool is_incognito_enabled
= IsIncognitoEnabled(*extension_id
);
2075 value_map
->RegisterExtension(
2076 *extension_id
, install_time
, is_enabled
, is_incognito_enabled
);
2079 ExtensionPrefsObserver
,
2081 OnExtensionRegistered(*extension_id
, install_time
, is_enabled
));
2083 // Set regular extension controlled prefs.
2084 LoadExtensionControlledPrefs(
2085 this, value_map
, *extension_id
, kExtensionPrefsScopeRegular
);
2086 // Set incognito extension controlled prefs.
2087 LoadExtensionControlledPrefs(this,
2090 kExtensionPrefsScopeIncognitoPersistent
);
2091 // Set regular-only extension controlled prefs.
2092 LoadExtensionControlledPrefs(
2093 this, value_map
, *extension_id
, kExtensionPrefsScopeRegularOnly
);
2095 FOR_EACH_OBSERVER(ExtensionPrefsObserver
,
2097 OnExtensionPrefsLoaded(*extension_id
, this));
2101 void ExtensionPrefs::FinishExtensionInfoPrefs(
2102 const std::string
& extension_id
,
2103 const base::Time install_time
,
2104 bool needs_sort_ordinal
,
2105 const syncer::StringOrdinal
& suggested_page_ordinal
,
2106 base::DictionaryValue
* extension_dict
) {
2107 // Reinitializes various preferences with empty dictionaries.
2108 if (!extension_dict
->HasKey(pref_names::kPrefPreferences
)) {
2109 extension_dict
->Set(pref_names::kPrefPreferences
,
2110 new base::DictionaryValue
);
2113 if (!extension_dict
->HasKey(pref_names::kPrefIncognitoPreferences
)) {
2114 extension_dict
->Set(pref_names::kPrefIncognitoPreferences
,
2115 new base::DictionaryValue
);
2118 if (!extension_dict
->HasKey(pref_names::kPrefRegularOnlyPreferences
)) {
2119 extension_dict
->Set(pref_names::kPrefRegularOnlyPreferences
,
2120 new base::DictionaryValue
);
2123 if (!extension_dict
->HasKey(pref_names::kPrefContentSettings
))
2124 extension_dict
->Set(pref_names::kPrefContentSettings
, new base::ListValue
);
2126 if (!extension_dict
->HasKey(pref_names::kPrefIncognitoContentSettings
)) {
2127 extension_dict
->Set(pref_names::kPrefIncognitoContentSettings
,
2128 new base::ListValue
);
2131 // If this point has been reached, any pending installs should be considered
2133 extension_dict
->Remove(kDelayedInstallInfo
, NULL
);
2135 // Clear state that may be registered from a previous install.
2136 extension_dict
->Remove(EventRouter::kRegisteredEvents
, NULL
);
2138 // When evicted ephemeral apps are re-installed, this flag must be reset.
2139 extension_dict
->Remove(kPrefEvictedEphemeralApp
, NULL
);
2141 // FYI, all code below here races on sudden shutdown because |extension_dict|,
2142 // |app_sorting_|, |extension_pref_value_map_|, and (potentially) observers
2143 // are updated non-transactionally. This is probably not fixable without
2144 // nested transactional updates to pref dictionaries.
2145 if (needs_sort_ordinal
)
2146 app_sorting_
->EnsureValidOrdinals(extension_id
, suggested_page_ordinal
);
2148 bool is_enabled
= false;
2150 if (extension_dict
->GetInteger(kPrefState
, &initial_state
)) {
2151 is_enabled
= initial_state
== Extension::ENABLED
;
2153 bool is_incognito_enabled
= IsIncognitoEnabled(extension_id
);
2155 extension_pref_value_map_
->RegisterExtension(
2156 extension_id
, install_time
, is_enabled
, is_incognito_enabled
);
2159 ExtensionPrefsObserver
,
2161 OnExtensionRegistered(extension_id
, install_time
, is_enabled
));
2164 } // namespace extensions