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