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.
4
5#include "extensions/browser/extension_prefs.h"
6
7#include <iterator>
8
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/pref_registry/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/install_flag.h"
23#include "extensions/browser/pref_names.h"
24#include "extensions/common/feature_switch.h"
25#include "extensions/common/manifest.h"
26#include "extensions/common/permissions/permission_set.h"
27#include "extensions/common/permissions/permissions_info.h"
28#include "extensions/common/url_pattern.h"
29#include "extensions/common/user_script.h"
30#include "ui/base/l10n/l10n_util.h"
31
32using base::Value;
33using base::DictionaryValue;
34using base::ListValue;
35
36namespace extensions {
37
38namespace {
39
40// Additional preferences keys, which are not needed by external clients.
41
42// True if this extension is running. Note this preference stops getting updated
43// during Chrome shutdown (and won't be updated on a browser crash) and so can
44// be used at startup to determine whether the extension was running when Chrome
45// was last terminated.
46const char kPrefRunning[] = "running";
47
48// Whether this extension had windows when it was last running.
49const char kIsActive[] = "is_active";
50
51// Where an extension was installed from. (see Manifest::Location)
52const char kPrefLocation[] = "location";
53
54// Enabled, disabled, killed, etc. (see Extension::State)
55const char kPrefState[] = "state";
56
57// The path to the current version's manifest file.
58const char kPrefPath[] = "path";
59
60// The dictionary containing the extension's manifest.
61const char kPrefManifest[] = "manifest";
62
63// The version number.
64const char kPrefVersion[] = "manifest.version";
65
66// Indicates whether an extension is blacklisted.
67const char kPrefBlacklist[] = "blacklist";
68
69// If extension is greylisted.
70const char kPrefBlacklistState[] = "blacklist_state";
71
72// The count of how many times we prompted the user to acknowledge an
73// extension.
74const char kPrefAcknowledgePromptCount[] = "ack_prompt_count";
75
76// Indicates whether the user has acknowledged various types of extensions.
77const char kPrefExternalAcknowledged[] = "ack_external";
78const char kPrefBlacklistAcknowledged[] = "ack_blacklist";
79const char kPrefWipeoutAcknowledged[] = "ack_wiped";
80const char kPrefSettingsBubbleAcknowledged[] = "ack_settings_bubble";
81const char kPrefNtpBubbleAcknowledged[] = "ack_ntp_bubble";
82const char kPrefProxyBubbleAcknowledged[] = "ack_proxy_bubble";
83
84// Indicates whether the external extension was installed during the first
85// run of this profile.
86const char kPrefExternalInstallFirstRun[] = "external_first_run";
87
88// Indicates whether to show an install warning when the user enables.
89const char kExtensionDidEscalatePermissions[] = "install_warning_on_enable";
90
91// DO NOT USE, use kPrefDisableReasons instead.
92// Indicates whether the extension was updated while it was disabled.
93const char kDeprecatedPrefDisableReason[] = "disable_reason";
94
95// A bitmask of all the reasons an extension is disabled.
96const char kPrefDisableReasons[] = "disable_reasons";
97
98// The key for a serialized Time value indicating the start of the day (from the
99// server's perspective) an extension last included a "ping" parameter during
100// its update check.
101const char kLastPingDay[] = "lastpingday";
102
103// Similar to kLastPingDay, but for "active" instead of "rollcall" pings.
104const char kLastActivePingDay[] = "last_active_pingday";
105
106// A bit we use to keep track of whether we need to do an "active" ping.
107const char kActiveBit[] = "active_bit";
108
109// Path for settings specific to blacklist update.
110const char kExtensionsBlacklistUpdate[] = "extensions.blacklistupdate";
111
112// Path for the delayed install info dictionary preference. The actual string
113// value is a legacy artifact for when delayed installs only pertained to
114// updates that were waiting for idle.
115const char kDelayedInstallInfo[] = "idle_install_info";
116
117// Reason why the extension's install was delayed.
118const char kDelayedInstallReason[] = "delay_install_reason";
119
120// Path for the suggested page ordinal of a delayed extension install.
121const char kPrefSuggestedPageOrdinal[] = "suggested_page_ordinal";
122
123// A preference that, if true, will allow this extension to run in incognito
124// mode.
125const char kPrefIncognitoEnabled[] = "incognito";
126
127// A preference to control whether an extension is allowed to inject script in
128// pages with file URLs.
129const char kPrefAllowFileAccess[] = "newAllowFileAccess";
130// TODO(jstritar): As part of fixing http://crbug.com/91577, we revoked all
131// extension file access by renaming the pref. We should eventually clean up
132// the old flag and possibly go back to that name.
133// const char kPrefAllowFileAccessOld[] = "allowFileAccess";
134
135// A preference specifying if the user dragged the app on the NTP.
136const char kPrefUserDraggedApp[] = "user_dragged_app_ntp";
137
138// Preferences that hold which permissions the user has granted the extension.
139// We explicitly keep track of these so that extensions can contain unknown
140// permissions, for backwards compatibility reasons, and we can still prompt
141// the user to accept them once recognized. We store the active permission
142// permissions because they may differ from those defined in the manifest.
143const char kPrefActivePermissions[] = "active_permissions";
144const char kPrefGrantedPermissions[] = "granted_permissions";
145
146// The preference names for PermissionSet values.
147const char kPrefAPIs[] = "api";
148const char kPrefManifestPermissions[] = "manifest_permissions";
149const char kPrefExplicitHosts[] = "explicit_host";
150const char kPrefScriptableHosts[] = "scriptable_host";
151
152// The preference names for the old granted permissions scheme.
153const char kPrefOldGrantedFullAccess[] = "granted_permissions.full";
154const char kPrefOldGrantedHosts[] = "granted_permissions.host";
155const char kPrefOldGrantedAPIs[] = "granted_permissions.api";
156
157// A preference that indicates when an extension was installed.
158const char kPrefInstallTime[] = "install_time";
159
160// A preference which saves the creation flags for extensions.
161const char kPrefCreationFlags[] = "creation_flags";
162
163// A preference that indicates whether the extension was installed from the
164// Chrome Web Store.
165const char kPrefFromWebStore[] = "from_webstore";
166
167// A preference that indicates whether the extension was installed from a
168// mock App created from a bookmark.
169const char kPrefFromBookmark[] = "from_bookmark";
170
171// A preference that indicates whether the extension was installed as a
172// default app.
173const char kPrefWasInstalledByDefault[] = "was_installed_by_default";
174
175// A preference that indicates whether the extension was installed as an
176// OEM app.
177const char kPrefWasInstalledByOem[] = "was_installed_by_oem";
178
179// Key for Geometry Cache preference.
180const char kPrefGeometryCache[] = "geometry_cache";
181
182// A preference that indicates when an extension is last launched.
183const char kPrefLastLaunchTime[] = "last_launch_time";
184
185// A preference indicating whether the extension is an ephemeral app.
186const char kPrefEphemeralApp[] = "ephemeral_app";
187
188// Am installation parameter bundled with an extension.
189const char kPrefInstallParam[] = "install_parameter";
190
191// A list of installed ids and a signature.
192const char kInstallSignature[] = "extensions.install_signature";
193
194// A boolean preference that indicates whether the extension should not be
195// synced. Default value is false.
196const char kPrefDoNotSync[] = "do_not_sync";
197
198// Provider of write access to a dictionary storing extension prefs.
199class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate {
200 public:
201  ScopedExtensionPrefUpdate(PrefService* service,
202                            const std::string& extension_id) :
203    DictionaryPrefUpdate(service, pref_names::kExtensions),
204    extension_id_(extension_id) {}
205
206  virtual ~ScopedExtensionPrefUpdate() {
207  }
208
209  // DictionaryPrefUpdate overrides:
210  virtual base::DictionaryValue* Get() OVERRIDE {
211    base::DictionaryValue* dict = DictionaryPrefUpdate::Get();
212    base::DictionaryValue* extension = NULL;
213    if (!dict->GetDictionary(extension_id_, &extension)) {
214      // Extension pref does not exist, create it.
215      extension = new base::DictionaryValue();
216      dict->SetWithoutPathExpansion(extension_id_, extension);
217    }
218    return extension;
219  }
220
221 private:
222  const std::string extension_id_;
223
224  DISALLOW_COPY_AND_ASSIGN(ScopedExtensionPrefUpdate);
225};
226
227std::string JoinPrefs(const std::string& parent, const char* child) {
228  return parent + "." + child;
229}
230
231// Checks if kPrefBlacklist is set to true in the base::DictionaryValue.
232// Return false if the value is false or kPrefBlacklist does not exist.
233// This is used to decide if an extension is blacklisted.
234bool IsBlacklistBitSet(const base::DictionaryValue* ext) {
235  bool bool_value;
236  return ext->GetBoolean(kPrefBlacklist, &bool_value) && bool_value;
237}
238
239void 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))
245    return;
246  std::string key = extension_id + "." + scope_string;
247
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))
252    return;
253
254  for (base::DictionaryValue::Iterator iter(*preferences); !iter.IsAtEnd();
255       iter.Advance()) {
256    value_map->SetExtensionPref(
257        extension_id, iter.key(), scope, iter.value().DeepCopy());
258  }
259}
260
261}  // namespace
262
263//
264// TimeProvider
265//
266
267ExtensionPrefs::TimeProvider::TimeProvider() {
268}
269
270ExtensionPrefs::TimeProvider::~TimeProvider() {
271}
272
273base::Time ExtensionPrefs::TimeProvider::GetCurrentTime() const {
274  return base::Time::Now();
275}
276
277//
278// ScopedUpdate
279//
280template <typename T, base::Value::Type type_enum_value>
281ExtensionPrefs::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),
287      key_(key) {
288  DCHECK(Extension::IdIsValid(extension_id_));
289}
290
291template <typename T, base::Value::Type type_enum_value>
292ExtensionPrefs::ScopedUpdate<T, type_enum_value>::~ScopedUpdate() {
293}
294
295template <typename T, base::Value::Type type_enum_value>
296T* 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)) {
302    return NULL;
303  }
304  return key_value->GetType() == type_enum_value ?
305      static_cast<T*>(key_value) :
306      NULL;
307}
308
309template <typename T, base::Value::Type type_enum_value>
310T* 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);
318  }
319  if (!extension->Get(key_, &key_value)) {
320    value_as_t = new T;
321    extension->SetWithoutPathExpansion(key_, value_as_t);
322  } else {
323    CHECK(key_value->GetType() == type_enum_value);
324    value_as_t = static_cast<T*>(key_value);
325  }
326  return value_as_t;
327}
328
329// Explicit instantiations for Dictionary and List value types.
330template class ExtensionPrefs::ScopedUpdate<base::DictionaryValue,
331                                            base::Value::TYPE_DICTIONARY>;
332template class ExtensionPrefs::ScopedUpdate<base::ListValue,
333                                            base::Value::TYPE_LIST>;
334
335//
336// ExtensionPrefs
337//
338
339// static
340ExtensionPrefs* ExtensionPrefs::Create(
341    PrefService* prefs,
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,
348                                root_dir,
349                                extension_pref_value_map,
350                                app_sorting.Pass(),
351                                extensions_disabled,
352                                early_observers,
353                                make_scoped_ptr(new TimeProvider()));
354}
355
356// static
357ExtensionPrefs* 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,
366                            root_dir,
367                            extension_pref_value_map,
368                            app_sorting.Pass(),
369                            time_provider.Pass(),
370                            extensions_disabled,
371                            early_observers);
372}
373
374ExtensionPrefs::~ExtensionPrefs() {
375}
376
377// static
378ExtensionPrefs* ExtensionPrefs::Get(content::BrowserContext* context) {
379  return ExtensionPrefsFactory::GetInstance()->GetForBrowserContext(context);
380}
381
382static base::FilePath::StringType MakePathRelative(const base::FilePath& parent,
383                                             const base::FilePath& child) {
384  if (!parent.IsParent(child))
385    return child.value();
386
387  base::FilePath::StringType retval = child.value().substr(
388      parent.value().length());
389  if (base::FilePath::IsSeparator(retval[0]))
390    return retval.substr(1);
391  else
392    return retval;
393}
394
395void ExtensionPrefs::MakePathsRelative() {
396  const base::DictionaryValue* dict =
397      prefs_->GetDictionary(pref_names::kExtensions);
398  if (!dict || dict->empty())
399    return;
400
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))
406      continue;
407    int location_value;
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.
412      continue;
413    }
414    base::FilePath::StringType path_string;
415    if (!extension_dict->GetString(kPrefPath, &path_string))
416      continue;
417    base::FilePath path(path_string);
418    if (path.IsAbsolute())
419      absolute_keys.insert(i.key());
420  }
421  if (absolute_keys.empty())
422    return;
423
424  // Fix these paths.
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;
432      continue;
433    }
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));
439  }
440}
441
442const 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;
447  if (!extensions ||
448      !extensions->GetDictionary(extension_id, &extension_dict)) {
449    return NULL;
450  }
451  return extension_dict;
452}
453
454void 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;
459    return;
460  }
461  ScopedExtensionPrefUpdate update(prefs_, extension_id);
462  if (data_value)
463    update->Set(key, data_value);
464  else
465    update->Remove(key, NULL);
466}
467
468void ExtensionPrefs::DeleteExtensionPrefs(const std::string& extension_id) {
469  extension_pref_value_map_->UnregisterExtension(extension_id);
470  FOR_EACH_OBSERVER(ExtensionPrefsObserver,
471                    observer_list_,
472                    OnExtensionPrefsDeleted(extension_id));
473  DictionaryPrefUpdate update(prefs_, pref_names::kExtensions);
474  base::DictionaryValue* dict = update.Get();
475  dict->Remove(extension_id, NULL);
476}
477
478bool 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))
483    return false;
484
485  return true;
486}
487
488bool 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))
493    return false;
494
495  return true;
496}
497
498bool 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))
503    return false;
504
505  return true;
506}
507
508bool 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))
514    return false;
515  if (out_value)
516    *out_value = out;
517
518  return true;
519}
520
521bool 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))
528    return false;
529  if (out_value)
530    *out_value = out;
531
532  return true;
533}
534
535bool ExtensionPrefs::HasPrefForExtension(
536    const std::string& extension_id) const {
537  return GetExtensionPref(extension_id) != NULL;
538}
539
540bool ExtensionPrefs::ReadPrefAsURLPatternSet(const std::string& extension_id,
541                                             const std::string& pref_key,
542                                             URLPatternSet* result,
543                                             int valid_schemes) {
544  const base::ListValue* value = NULL;
545  if (!ReadPrefAsList(extension_id, pref_key, &value))
546    return false;
547
548  bool allow_file_access = AllowFileAccess(extension_id);
549  return result->Populate(*value, valid_schemes, allow_file_access, NULL);
550}
551
552void 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());
557}
558
559bool 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;
564}
565
566PermissionSet* ExtensionPrefs::ReadPrefAsPermissionSet(
567    const std::string& extension_id,
568    const std::string& pref_key) {
569  if (!GetExtensionPref(extension_id))
570    return NULL;
571
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,
580                                    &apis, NULL, NULL);
581  }
582
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);
593  }
594
595  // Retrieve the explicit host permissions.
596  URLPatternSet explicit_hosts;
597  ReadPrefAsURLPatternSet(
598      extension_id, JoinPrefs(pref_key, kPrefExplicitHosts),
599      &explicit_hosts, Extension::kValidHostPermissionSchemes);
600
601  // Retrieve the scriptable host permissions.
602  URLPatternSet scriptable_hosts;
603  ReadPrefAsURLPatternSet(
604      extension_id, JoinPrefs(pref_key, kPrefScriptableHosts),
605      &scriptable_hosts, UserScript::ValidUserScriptSchemes());
606
607  return new PermissionSet(
608      apis, manifest_permissions, explicit_hosts, scriptable_hosts);
609}
610
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.
617//   ...
618// ]
619template<typename T>
620static 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());
625    if (detail) {
626      base::DictionaryValue* tmp = new base::DictionaryValue();
627      tmp->Set(i->name(), detail.release());
628      values->Append(tmp);
629    } else {
630      values->Append(new base::StringValue(i->name()));
631    }
632  }
633  return values;
634}
635
636void 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);
643
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);
651
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());
657  }
658
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());
664  }
665}
666
667int ExtensionPrefs::IncrementAcknowledgePromptCount(
668    const std::string& extension_id) {
669  int count = 0;
670  ReadPrefAsInteger(extension_id, kPrefAcknowledgePromptCount, &count);
671  ++count;
672  UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount,
673                      new base::FundamentalValue(count));
674  return count;
675}
676
677bool ExtensionPrefs::IsExternalExtensionAcknowledged(
678    const std::string& extension_id) {
679  return ReadPrefAsBooleanAndReturn(extension_id, kPrefExternalAcknowledged);
680}
681
682void 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);
688}
689
690bool ExtensionPrefs::IsBlacklistedExtensionAcknowledged(
691    const std::string& extension_id) {
692  return ReadPrefAsBooleanAndReturn(extension_id, kPrefBlacklistAcknowledged);
693}
694
695void 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);
701}
702
703bool ExtensionPrefs::IsExternalInstallFirstRun(
704    const std::string& extension_id) {
705  return ReadPrefAsBooleanAndReturn(extension_id, kPrefExternalInstallFirstRun);
706}
707
708void ExtensionPrefs::SetExternalInstallFirstRun(
709    const std::string& extension_id) {
710  DCHECK(Extension::IdIsValid(extension_id));
711  UpdateExtensionPref(extension_id, kPrefExternalInstallFirstRun,
712                      new base::FundamentalValue(true));
713}
714
715bool ExtensionPrefs::HasWipeoutBeenAcknowledged(
716    const std::string& extension_id) {
717  return ReadPrefAsBooleanAndReturn(extension_id, kPrefWipeoutAcknowledged);
718}
719
720void ExtensionPrefs::SetWipeoutAcknowledged(
721    const std::string& extension_id,
722    bool value) {
723  UpdateExtensionPref(extension_id, kPrefWipeoutAcknowledged,
724                      value ? base::Value::CreateBooleanValue(value) : NULL);
725}
726
727bool ExtensionPrefs::HasSettingsApiBubbleBeenAcknowledged(
728    const std::string& extension_id) {
729  return ReadPrefAsBooleanAndReturn(extension_id,
730                                    kPrefSettingsBubbleAcknowledged);
731}
732
733void ExtensionPrefs::SetSettingsApiBubbleBeenAcknowledged(
734    const std::string& extension_id,
735    bool value) {
736  UpdateExtensionPref(extension_id,
737                      kPrefSettingsBubbleAcknowledged,
738                      value ? base::Value::CreateBooleanValue(value) : NULL);
739}
740
741bool ExtensionPrefs::HasNtpOverriddenBubbleBeenAcknowledged(
742    const std::string& extension_id) {
743  return ReadPrefAsBooleanAndReturn(extension_id, kPrefNtpBubbleAcknowledged);
744}
745
746void ExtensionPrefs::SetNtpOverriddenBubbleBeenAcknowledged(
747    const std::string& extension_id,
748    bool value) {
749  UpdateExtensionPref(extension_id,
750                      kPrefNtpBubbleAcknowledged,
751                      value ? base::Value::CreateBooleanValue(value) : NULL);
752}
753
754bool ExtensionPrefs::HasProxyOverriddenBubbleBeenAcknowledged(
755    const std::string& extension_id) {
756  return ReadPrefAsBooleanAndReturn(extension_id, kPrefProxyBubbleAcknowledged);
757}
758
759void ExtensionPrefs::SetProxyOverriddenBubbleBeenAcknowledged(
760    const std::string& extension_id,
761    bool value) {
762  UpdateExtensionPref(extension_id,
763                      kPrefProxyBubbleAcknowledged,
764                      value ? base::Value::CreateBooleanValue(value) : NULL);
765}
766
767bool ExtensionPrefs::SetAlertSystemFirstRun() {
768  if (prefs_->GetBoolean(pref_names::kAlertsInitialized)) {
769    return true;
770  }
771  prefs_->SetBoolean(pref_names::kAlertsInitialized, true);
772  return false;
773}
774
775bool ExtensionPrefs::ExtensionsBlacklistedByDefault() const {
776  return admin_policy::BlacklistedByDefault(
777      prefs_->GetList(pref_names::kInstallDenyList));
778}
779
780bool ExtensionPrefs::DidExtensionEscalatePermissions(
781    const std::string& extension_id) {
782  return ReadPrefAsBooleanAndReturn(extension_id,
783                                    kExtensionDidEscalatePermissions);
784}
785
786void ExtensionPrefs::SetDidExtensionEscalatePermissions(
787    const Extension* extension, bool did_escalate) {
788  UpdateExtensionPref(extension->id(), kExtensionDidEscalatePermissions,
789                      new base::FundamentalValue(did_escalate));
790}
791
792int ExtensionPrefs::GetDisableReasons(const std::string& extension_id) const {
793  int value = -1;
794  if (ReadPrefAsInteger(extension_id, kPrefDisableReasons, &value) &&
795      value >= 0) {
796    return value;
797  }
798  return Extension::DISABLE_NONE;
799}
800
801bool ExtensionPrefs::HasDisableReason(
802    const std::string& extension_id,
803    Extension::DisableReason disable_reason) const {
804  return (GetDisableReasons(extension_id) & disable_reason) != 0;
805}
806
807void ExtensionPrefs::AddDisableReason(const std::string& extension_id,
808                                      Extension::DisableReason disable_reason) {
809  ModifyDisableReason(extension_id, disable_reason, DISABLE_REASON_ADD);
810}
811
812void ExtensionPrefs::RemoveDisableReason(
813    const std::string& extension_id,
814    Extension::DisableReason disable_reason) {
815  ModifyDisableReason(extension_id, disable_reason, DISABLE_REASON_REMOVE);
816}
817
818void ExtensionPrefs::ClearDisableReasons(const std::string& extension_id) {
819  ModifyDisableReason(
820      extension_id, Extension::DISABLE_NONE, DISABLE_REASON_CLEAR);
821}
822
823void ExtensionPrefs::ModifyDisableReason(const std::string& extension_id,
824                                         Extension::DisableReason reason,
825                                         DisableReasonChange change) {
826  int old_value = GetDisableReasons(extension_id);
827  int new_value = old_value;
828  switch (change) {
829    case DISABLE_REASON_ADD:
830      new_value |= static_cast<int>(reason);
831      break;
832    case DISABLE_REASON_REMOVE:
833      new_value &= ~static_cast<int>(reason);
834      break;
835    case DISABLE_REASON_CLEAR:
836      new_value = Extension::DISABLE_NONE;
837      break;
838  }
839
840  if (old_value == new_value)  // no change, return.
841    return;
842
843  if (new_value == Extension::DISABLE_NONE) {
844    UpdateExtensionPref(extension_id, kPrefDisableReasons, NULL);
845  } else {
846    UpdateExtensionPref(extension_id,
847                        kPrefDisableReasons,
848                        new base::FundamentalValue(new_value));
849  }
850
851  FOR_EACH_OBSERVER(ExtensionPrefsObserver,
852                    observer_list_,
853                    OnExtensionDisableReasonsChanged(extension_id, new_value));
854}
855
856std::set<std::string> ExtensionPrefs::GetBlacklistedExtensions() {
857  std::set<std::string> ids;
858
859  const base::DictionaryValue* extensions =
860      prefs_->GetDictionary(pref_names::kExtensions);
861  if (!extensions)
862    return ids;
863
864  for (base::DictionaryValue::Iterator it(*extensions);
865       !it.IsAtEnd(); it.Advance()) {
866    if (!it.value().IsType(base::Value::TYPE_DICTIONARY)) {
867      NOTREACHED() << "Invalid pref for extension " << it.key();
868      continue;
869    }
870    if (IsBlacklistBitSet(
871            static_cast<const base::DictionaryValue*>(&it.value()))) {
872      ids.insert(it.key());
873    }
874  }
875
876  return ids;
877}
878
879void ExtensionPrefs::SetExtensionBlacklisted(const std::string& extension_id,
880                                             bool is_blacklisted) {
881  bool currently_blacklisted = IsExtensionBlacklisted(extension_id);
882  if (is_blacklisted == currently_blacklisted)
883    return;
884
885  // Always make sure the "acknowledged" bit is cleared since the blacklist bit
886  // is changing.
887  UpdateExtensionPref(extension_id, kPrefBlacklistAcknowledged, NULL);
888
889  if (is_blacklisted) {
890    UpdateExtensionPref(extension_id,
891                        kPrefBlacklist,
892                        new base::FundamentalValue(true));
893  } else {
894    UpdateExtensionPref(extension_id, kPrefBlacklist, NULL);
895    const base::DictionaryValue* dict = GetExtensionPref(extension_id);
896    if (dict && dict->empty())
897      DeleteExtensionPrefs(extension_id);
898  }
899}
900
901bool ExtensionPrefs::IsExtensionBlacklisted(const std::string& id) const {
902  const base::DictionaryValue* ext_prefs = GetExtensionPref(id);
903  return ext_prefs && IsBlacklistBitSet(ext_prefs);
904}
905
906namespace {
907
908// Serializes a 64bit integer as a string value.
909void SaveInt64(base::DictionaryValue* dictionary,
910               const char* key,
911               const int64 value) {
912  if (!dictionary)
913    return;
914
915  std::string string_value = base::Int64ToString(value);
916  dictionary->SetString(key, string_value);
917}
918
919// Deserializes a 64bit integer stored as a string value.
920bool ReadInt64(const base::DictionaryValue* dictionary,
921               const char* key,
922               int64* value) {
923  if (!dictionary)
924    return false;
925
926  std::string string_value;
927  if (!dictionary->GetString(key, &string_value))
928    return false;
929
930  return base::StringToInt64(string_value, value);
931}
932
933// Serializes |time| as a string value mapped to |key| in |dictionary|.
934void SaveTime(base::DictionaryValue* dictionary,
935              const char* key,
936              const base::Time& time) {
937  SaveInt64(dictionary, key, time.ToInternalValue());
938}
939
940// The opposite of SaveTime. If |key| is not found, this returns an empty Time
941// (is_null() will return true).
942base::Time ReadTime(const base::DictionaryValue* dictionary, const char* key) {
943  int64 value;
944  if (ReadInt64(dictionary, key, &value))
945    return base::Time::FromInternalValue(value);
946
947  return base::Time();
948}
949
950}  // namespace
951
952base::Time ExtensionPrefs::LastPingDay(const std::string& extension_id) const {
953  DCHECK(Extension::IdIsValid(extension_id));
954  return ReadTime(GetExtensionPref(extension_id), kLastPingDay);
955}
956
957void ExtensionPrefs::SetLastPingDay(const std::string& extension_id,
958                                    const base::Time& time) {
959  DCHECK(Extension::IdIsValid(extension_id));
960  ScopedExtensionPrefUpdate update(prefs_, extension_id);
961  SaveTime(update.Get(), kLastPingDay, time);
962}
963
964base::Time ExtensionPrefs::BlacklistLastPingDay() const {
965  return ReadTime(prefs_->GetDictionary(kExtensionsBlacklistUpdate),
966                  kLastPingDay);
967}
968
969void ExtensionPrefs::SetBlacklistLastPingDay(const base::Time& time) {
970  DictionaryPrefUpdate update(prefs_, kExtensionsBlacklistUpdate);
971  SaveTime(update.Get(), kLastPingDay, time);
972}
973
974base::Time ExtensionPrefs::LastActivePingDay(const std::string& extension_id) {
975  DCHECK(Extension::IdIsValid(extension_id));
976  return ReadTime(GetExtensionPref(extension_id), kLastActivePingDay);
977}
978
979void ExtensionPrefs::SetLastActivePingDay(const std::string& extension_id,
980                                          const base::Time& time) {
981  DCHECK(Extension::IdIsValid(extension_id));
982  ScopedExtensionPrefUpdate update(prefs_, extension_id);
983  SaveTime(update.Get(), kLastActivePingDay, time);
984}
985
986bool ExtensionPrefs::GetActiveBit(const std::string& extension_id) {
987  const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
988  bool result = false;
989  if (dictionary && dictionary->GetBoolean(kActiveBit, &result))
990    return result;
991  return false;
992}
993
994void ExtensionPrefs::SetActiveBit(const std::string& extension_id,
995                                  bool active) {
996  UpdateExtensionPref(extension_id, kActiveBit,
997                      new base::FundamentalValue(active));
998}
999
1000void ExtensionPrefs::MigratePermissions(const ExtensionIdList& extension_ids) {
1001  PermissionsInfo* info = PermissionsInfo::GetInstance();
1002  for (ExtensionIdList::const_iterator ext_id =
1003       extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) {
1004    // An extension's granted permissions need to be migrated if the
1005    // full_access bit is present. This bit was always present in the previous
1006    // scheme and is never present now.
1007    bool full_access;
1008    const base::DictionaryValue* ext = GetExtensionPref(*ext_id);
1009    if (!ext || !ext->GetBoolean(kPrefOldGrantedFullAccess, &full_access))
1010      continue;
1011
1012    // Remove the full access bit (empty list will get trimmed).
1013    UpdateExtensionPref(
1014        *ext_id, kPrefOldGrantedFullAccess, new base::ListValue());
1015
1016    // Add the plugin permission if the full access bit was set.
1017    if (full_access) {
1018      const base::ListValue* apis = NULL;
1019      base::ListValue* new_apis = NULL;
1020
1021      std::string granted_apis = JoinPrefs(kPrefGrantedPermissions, kPrefAPIs);
1022      if (ext->GetList(kPrefOldGrantedAPIs, &apis))
1023        new_apis = apis->DeepCopy();
1024      else
1025        new_apis = new base::ListValue();
1026
1027      std::string plugin_name = info->GetByID(APIPermission::kPlugin)->name();
1028      new_apis->Append(new base::StringValue(plugin_name));
1029      UpdateExtensionPref(*ext_id, granted_apis, new_apis);
1030    }
1031
1032    // The granted permissions originally only held the effective hosts,
1033    // which are a combination of host and user script host permissions.
1034    // We now maintain these lists separately. For migration purposes, it
1035    // does not matter how we treat the old effective hosts as long as the
1036    // new effective hosts will be the same, so we move them to explicit
1037    // host permissions.
1038    const base::ListValue* hosts = NULL;
1039    std::string explicit_hosts =
1040        JoinPrefs(kPrefGrantedPermissions, kPrefExplicitHosts);
1041    if (ext->GetList(kPrefOldGrantedHosts, &hosts)) {
1042      UpdateExtensionPref(
1043          *ext_id, explicit_hosts, hosts->DeepCopy());
1044
1045      // We can get rid of the old one by setting it to an empty list.
1046      UpdateExtensionPref(*ext_id, kPrefOldGrantedHosts, new base::ListValue());
1047    }
1048  }
1049}
1050
1051void ExtensionPrefs::MigrateDisableReasons(
1052    const ExtensionIdList& extension_ids) {
1053  for (ExtensionIdList::const_iterator ext_id =
1054       extension_ids.begin(); ext_id != extension_ids.end(); ++ext_id) {
1055    int value = -1;
1056    if (ReadPrefAsInteger(*ext_id, kDeprecatedPrefDisableReason, &value)) {
1057      int new_value = Extension::DISABLE_NONE;
1058      switch (value) {
1059        case Extension::DEPRECATED_DISABLE_USER_ACTION:
1060          new_value = Extension::DISABLE_USER_ACTION;
1061          break;
1062        case Extension::DEPRECATED_DISABLE_PERMISSIONS_INCREASE:
1063          new_value = Extension::DISABLE_PERMISSIONS_INCREASE;
1064          break;
1065        case Extension::DEPRECATED_DISABLE_RELOAD:
1066          new_value = Extension::DISABLE_RELOAD;
1067          break;
1068      }
1069
1070      UpdateExtensionPref(*ext_id, kPrefDisableReasons,
1071                          new base::FundamentalValue(new_value));
1072      // Remove the old disable reason.
1073      UpdateExtensionPref(*ext_id, kDeprecatedPrefDisableReason, NULL);
1074    }
1075  }
1076}
1077
1078PermissionSet* ExtensionPrefs::GetGrantedPermissions(
1079    const std::string& extension_id) {
1080  CHECK(Extension::IdIsValid(extension_id));
1081  return ReadPrefAsPermissionSet(extension_id, kPrefGrantedPermissions);
1082}
1083
1084void ExtensionPrefs::AddGrantedPermissions(
1085    const std::string& extension_id,
1086    const PermissionSet* permissions) {
1087  CHECK(Extension::IdIsValid(extension_id));
1088
1089  scoped_refptr<PermissionSet> granted_permissions(
1090      GetGrantedPermissions(extension_id));
1091
1092  // The new granted permissions are the union of the already granted
1093  // permissions and the newly granted permissions.
1094  scoped_refptr<PermissionSet> new_perms(
1095      PermissionSet::CreateUnion(
1096          permissions, granted_permissions.get()));
1097
1098  SetExtensionPrefPermissionSet(
1099      extension_id, kPrefGrantedPermissions, new_perms.get());
1100}
1101
1102void ExtensionPrefs::RemoveGrantedPermissions(
1103    const std::string& extension_id,
1104    const PermissionSet* permissions) {
1105  CHECK(Extension::IdIsValid(extension_id));
1106
1107  scoped_refptr<PermissionSet> granted_permissions(
1108      GetGrantedPermissions(extension_id));
1109
1110  // The new granted permissions are the difference of the already granted
1111  // permissions and the newly ungranted permissions.
1112  scoped_refptr<PermissionSet> new_perms(
1113      PermissionSet::CreateDifference(
1114          granted_permissions.get(), permissions));
1115
1116  SetExtensionPrefPermissionSet(
1117      extension_id, kPrefGrantedPermissions, new_perms.get());
1118}
1119
1120PermissionSet* ExtensionPrefs::GetActivePermissions(
1121    const std::string& extension_id) {
1122  CHECK(Extension::IdIsValid(extension_id));
1123  return ReadPrefAsPermissionSet(extension_id, kPrefActivePermissions);
1124}
1125
1126void ExtensionPrefs::SetActivePermissions(
1127    const std::string& extension_id,
1128    const PermissionSet* permissions) {
1129  SetExtensionPrefPermissionSet(
1130      extension_id, kPrefActivePermissions, permissions);
1131}
1132
1133void ExtensionPrefs::SetExtensionRunning(const std::string& extension_id,
1134    bool is_running) {
1135  base::Value* value = new base::FundamentalValue(is_running);
1136  UpdateExtensionPref(extension_id, kPrefRunning, value);
1137}
1138
1139bool ExtensionPrefs::IsExtensionRunning(const std::string& extension_id) {
1140  const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1141  if (!extension)
1142    return false;
1143  bool running = false;
1144  extension->GetBoolean(kPrefRunning, &running);
1145  return running;
1146}
1147
1148void ExtensionPrefs::SetIsActive(const std::string& extension_id,
1149                                 bool is_active) {
1150  base::Value* value = new base::FundamentalValue(is_active);
1151  UpdateExtensionPref(extension_id, kIsActive, value);
1152}
1153
1154bool ExtensionPrefs::IsActive(const std::string& extension_id) {
1155  const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1156  if (!extension)
1157    return false;
1158  bool is_active = false;
1159  extension->GetBoolean(kIsActive, &is_active);
1160  return is_active;
1161}
1162
1163bool ExtensionPrefs::IsIncognitoEnabled(const std::string& extension_id) const {
1164  return ReadPrefAsBooleanAndReturn(extension_id, kPrefIncognitoEnabled);
1165}
1166
1167void ExtensionPrefs::SetIsIncognitoEnabled(const std::string& extension_id,
1168                                           bool enabled) {
1169  UpdateExtensionPref(extension_id, kPrefIncognitoEnabled,
1170                      new base::FundamentalValue(enabled));
1171  extension_pref_value_map_->SetExtensionIncognitoState(extension_id, enabled);
1172}
1173
1174bool ExtensionPrefs::AllowFileAccess(const std::string& extension_id) const {
1175  return ReadPrefAsBooleanAndReturn(extension_id, kPrefAllowFileAccess);
1176}
1177
1178void ExtensionPrefs::SetAllowFileAccess(const std::string& extension_id,
1179                                        bool allow) {
1180  UpdateExtensionPref(extension_id, kPrefAllowFileAccess,
1181                      new base::FundamentalValue(allow));
1182}
1183
1184bool ExtensionPrefs::HasAllowFileAccessSetting(
1185    const std::string& extension_id) const {
1186  const base::DictionaryValue* ext = GetExtensionPref(extension_id);
1187  return ext && ext->HasKey(kPrefAllowFileAccess);
1188}
1189
1190bool ExtensionPrefs::DoesExtensionHaveState(
1191    const std::string& id, Extension::State check_state) const {
1192  const base::DictionaryValue* extension = GetExtensionPref(id);
1193  int state = -1;
1194  if (!extension || !extension->GetInteger(kPrefState, &state))
1195    return false;
1196
1197  if (state < 0 || state >= Extension::NUM_STATES) {
1198    LOG(ERROR) << "Bad pref 'state' for extension '" << id << "'";
1199    return false;
1200  }
1201
1202  return state == check_state;
1203}
1204
1205bool ExtensionPrefs::IsExternalExtensionUninstalled(
1206    const std::string& id) const {
1207  return DoesExtensionHaveState(id, Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1208}
1209
1210bool ExtensionPrefs::IsExtensionDisabled(
1211    const std::string& id) const {
1212  return DoesExtensionHaveState(id, Extension::DISABLED);
1213}
1214
1215ExtensionIdList ExtensionPrefs::GetToolbarOrder() {
1216  ExtensionIdList id_list_out;
1217  GetUserExtensionPrefIntoContainer(pref_names::kToolbar, &id_list_out);
1218  return id_list_out;
1219}
1220
1221void ExtensionPrefs::SetToolbarOrder(const ExtensionIdList& extension_ids) {
1222  SetExtensionPrefFromContainer(pref_names::kToolbar, extension_ids);
1223}
1224
1225bool ExtensionPrefs::GetKnownDisabled(ExtensionIdSet* id_set_out) {
1226  return GetUserExtensionPrefIntoContainer(pref_names::kKnownDisabled,
1227                                           id_set_out);
1228}
1229
1230void ExtensionPrefs::SetKnownDisabled(const ExtensionIdSet& extension_ids) {
1231  SetExtensionPrefFromContainer(pref_names::kKnownDisabled, extension_ids);
1232}
1233
1234void ExtensionPrefs::OnExtensionInstalled(
1235    const Extension* extension,
1236    Extension::State initial_state,
1237    const syncer::StringOrdinal& page_ordinal,
1238    int install_flags,
1239    const std::string& install_parameter) {
1240  ScopedExtensionPrefUpdate update(prefs_, extension->id());
1241  base::DictionaryValue* extension_dict = update.Get();
1242  const base::Time install_time = time_provider_->GetCurrentTime();
1243  PopulateExtensionInfoPrefs(extension,
1244                             install_time,
1245                             initial_state,
1246                             install_flags,
1247                             install_parameter,
1248                             extension_dict);
1249  FinishExtensionInfoPrefs(extension->id(), install_time,
1250                           extension->RequiresSortOrdinal(),
1251                           page_ordinal, extension_dict);
1252}
1253
1254void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
1255                                            const Manifest::Location& location,
1256                                            bool external_uninstall) {
1257  app_sorting_->ClearOrdinals(extension_id);
1258
1259  // For external extensions, we save a preference reminding ourself not to try
1260  // and install the extension anymore (except when |external_uninstall| is
1261  // true, which signifies that the registry key was deleted or the pref file
1262  // no longer lists the extension).
1263  if (!external_uninstall && Manifest::IsExternalLocation(location)) {
1264    UpdateExtensionPref(extension_id, kPrefState,
1265                        new base::FundamentalValue(
1266                            Extension::EXTERNAL_EXTENSION_UNINSTALLED));
1267    extension_pref_value_map_->SetExtensionState(extension_id, false);
1268    FOR_EACH_OBSERVER(ExtensionPrefsObserver,
1269                      observer_list_,
1270                      OnExtensionStateChanged(extension_id, false));
1271  } else {
1272    DeleteExtensionPrefs(extension_id);
1273  }
1274}
1275
1276void ExtensionPrefs::SetExtensionState(const std::string& extension_id,
1277                                       Extension::State state) {
1278  UpdateExtensionPref(extension_id, kPrefState,
1279                      new base::FundamentalValue(state));
1280  bool enabled = (state == Extension::ENABLED);
1281  extension_pref_value_map_->SetExtensionState(extension_id, enabled);
1282  FOR_EACH_OBSERVER(ExtensionPrefsObserver,
1283                    observer_list_,
1284                    OnExtensionStateChanged(extension_id, enabled));
1285}
1286
1287void ExtensionPrefs::SetExtensionBlacklistState(const std::string& extension_id,
1288                                                BlacklistState state) {
1289  SetExtensionBlacklisted(extension_id, state == BLACKLISTED_MALWARE);
1290  UpdateExtensionPref(extension_id, kPrefBlacklistState,
1291                      new base::FundamentalValue(state));
1292}
1293
1294BlacklistState ExtensionPrefs::GetExtensionBlacklistState(
1295    const std::string& extension_id) {
1296  if (IsExtensionBlacklisted(extension_id))
1297    return BLACKLISTED_MALWARE;
1298  const base::DictionaryValue* ext_prefs = GetExtensionPref(extension_id);
1299  int int_value;
1300  if (ext_prefs && ext_prefs->GetInteger(kPrefBlacklistState, &int_value))
1301    return static_cast<BlacklistState>(int_value);
1302
1303  return NOT_BLACKLISTED;
1304}
1305
1306std::string ExtensionPrefs::GetVersionString(const std::string& extension_id) {
1307  const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1308  if (!extension)
1309    return std::string();
1310
1311  std::string version;
1312  extension->GetString(kPrefVersion, &version);
1313
1314  return version;
1315}
1316
1317void ExtensionPrefs::UpdateManifest(const Extension* extension) {
1318  if (!Manifest::IsUnpackedLocation(extension->location())) {
1319    const base::DictionaryValue* extension_dict =
1320        GetExtensionPref(extension->id());
1321    if (!extension_dict)
1322      return;
1323    const base::DictionaryValue* old_manifest = NULL;
1324    bool update_required =
1325        !extension_dict->GetDictionary(kPrefManifest, &old_manifest) ||
1326        !extension->manifest()->value()->Equals(old_manifest);
1327    if (update_required) {
1328      UpdateExtensionPref(extension->id(), kPrefManifest,
1329                          extension->manifest()->value()->DeepCopy());
1330    }
1331  }
1332}
1333
1334scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledInfoHelper(
1335    const std::string& extension_id,
1336    const base::DictionaryValue* extension) const {
1337  int location_value;
1338  if (!extension->GetInteger(kPrefLocation, &location_value))
1339    return scoped_ptr<ExtensionInfo>();
1340
1341  base::FilePath::StringType path;
1342  if (!extension->GetString(kPrefPath, &path))
1343    return scoped_ptr<ExtensionInfo>();
1344
1345  // Make path absolute. Unpacked extensions will already have absolute paths,
1346  // otherwise make it so.
1347  Manifest::Location location = static_cast<Manifest::Location>(location_value);
1348#if !defined(OS_CHROMEOS)
1349  if (!Manifest::IsUnpackedLocation(location)) {
1350    DCHECK(location == Manifest::COMPONENT ||
1351           !base::FilePath(path).IsAbsolute());
1352#else
1353  // On Chrome OS some extensions can be installed to shared location and
1354  // thus use absolute paths in prefs.
1355  if (!base::FilePath(path).IsAbsolute()) {
1356#endif  // !defined(OS_CHROMEOS)
1357    path = install_directory_.Append(path).value();
1358  }
1359
1360  // Only the following extension types have data saved in the preferences.
1361  if (location != Manifest::INTERNAL &&
1362      !Manifest::IsUnpackedLocation(location) &&
1363      !Manifest::IsExternalLocation(location)) {
1364    NOTREACHED();
1365    return scoped_ptr<ExtensionInfo>();
1366  }
1367
1368  const base::DictionaryValue* manifest = NULL;
1369  if (!Manifest::IsUnpackedLocation(location) &&
1370      !extension->GetDictionary(kPrefManifest, &manifest)) {
1371    LOG(WARNING) << "Missing manifest for extension " << extension_id;
1372    // Just a warning for now.
1373  }
1374
1375  return scoped_ptr<ExtensionInfo>(new ExtensionInfo(
1376      manifest, extension_id, base::FilePath(path), location));
1377}
1378
1379scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledExtensionInfo(
1380    const std::string& extension_id) const {
1381  const base::DictionaryValue* ext = NULL;
1382  const base::DictionaryValue* extensions =
1383      prefs_->GetDictionary(pref_names::kExtensions);
1384  if (!extensions ||
1385      !extensions->GetDictionaryWithoutPathExpansion(extension_id, &ext))
1386    return scoped_ptr<ExtensionInfo>();
1387  int state_value;
1388  if (!ext->GetInteger(kPrefState, &state_value) ||
1389      state_value == Extension::ENABLED_COMPONENT) {
1390    // Old preferences files may not have kPrefState for component extensions.
1391    return scoped_ptr<ExtensionInfo>();
1392  }
1393
1394  if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) {
1395    LOG(WARNING) << "External extension with id " << extension_id
1396                 << " has been uninstalled by the user";
1397    return scoped_ptr<ExtensionInfo>();
1398  }
1399
1400  return GetInstalledInfoHelper(extension_id, ext);
1401}
1402
1403scoped_ptr<ExtensionPrefs::ExtensionsInfo>
1404ExtensionPrefs::GetInstalledExtensionsInfo() const {
1405  scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1406
1407  const base::DictionaryValue* extensions =
1408      prefs_->GetDictionary(pref_names::kExtensions);
1409  for (base::DictionaryValue::Iterator extension_id(*extensions);
1410       !extension_id.IsAtEnd(); extension_id.Advance()) {
1411    if (!Extension::IdIsValid(extension_id.key()))
1412      continue;
1413
1414    scoped_ptr<ExtensionInfo> info =
1415        GetInstalledExtensionInfo(extension_id.key());
1416    if (info)
1417      extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1418  }
1419
1420  return extensions_info.Pass();
1421}
1422
1423scoped_ptr<ExtensionPrefs::ExtensionsInfo>
1424ExtensionPrefs::GetUninstalledExtensionsInfo() const {
1425  scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1426
1427  const base::DictionaryValue* extensions =
1428      prefs_->GetDictionary(pref_names::kExtensions);
1429  for (base::DictionaryValue::Iterator extension_id(*extensions);
1430       !extension_id.IsAtEnd(); extension_id.Advance()) {
1431    const base::DictionaryValue* ext = NULL;
1432    if (!Extension::IdIsValid(extension_id.key()) ||
1433        !IsExternalExtensionUninstalled(extension_id.key()) ||
1434        !extension_id.value().GetAsDictionary(&ext))
1435      continue;
1436
1437    scoped_ptr<ExtensionInfo> info =
1438        GetInstalledInfoHelper(extension_id.key(), ext);
1439    if (info)
1440      extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1441  }
1442
1443  return extensions_info.Pass();
1444}
1445
1446void ExtensionPrefs::SetDelayedInstallInfo(
1447    const Extension* extension,
1448    Extension::State initial_state,
1449    int install_flags,
1450    DelayReason delay_reason,
1451    const syncer::StringOrdinal& page_ordinal,
1452    const std::string& install_parameter) {
1453  base::DictionaryValue* extension_dict = new base::DictionaryValue();
1454  PopulateExtensionInfoPrefs(extension,
1455                             time_provider_->GetCurrentTime(),
1456                             initial_state,
1457                             install_flags,
1458                             install_parameter,
1459                             extension_dict);
1460
1461  // Add transient data that is needed by FinishDelayedInstallInfo(), but
1462  // should not be in the final extension prefs. All entries here should have
1463  // a corresponding Remove() call in FinishDelayedInstallInfo().
1464  if (extension->RequiresSortOrdinal()) {
1465    extension_dict->SetString(
1466        kPrefSuggestedPageOrdinal,
1467        page_ordinal.IsValid() ? page_ordinal.ToInternalValue()
1468                               : std::string());
1469  }
1470  extension_dict->SetInteger(kDelayedInstallReason,
1471                             static_cast<int>(delay_reason));
1472
1473  UpdateExtensionPref(extension->id(), kDelayedInstallInfo, extension_dict);
1474}
1475
1476bool ExtensionPrefs::RemoveDelayedInstallInfo(
1477    const std::string& extension_id) {
1478  if (!GetExtensionPref(extension_id))
1479    return false;
1480  ScopedExtensionPrefUpdate update(prefs_, extension_id);
1481  bool result = update->Remove(kDelayedInstallInfo, NULL);
1482  return result;
1483}
1484
1485bool ExtensionPrefs::FinishDelayedInstallInfo(
1486    const std::string& extension_id) {
1487  CHECK(Extension::IdIsValid(extension_id));
1488  ScopedExtensionPrefUpdate update(prefs_, extension_id);
1489  base::DictionaryValue* extension_dict = update.Get();
1490  base::DictionaryValue* pending_install_dict = NULL;
1491  if (!extension_dict->GetDictionary(kDelayedInstallInfo,
1492                                     &pending_install_dict)) {
1493    return false;
1494  }
1495
1496  // Retrieve and clear transient values populated by SetDelayedInstallInfo().
1497  // Also do any other data cleanup that makes sense.
1498  std::string serialized_ordinal;
1499  syncer::StringOrdinal suggested_page_ordinal;
1500  bool needs_sort_ordinal = false;
1501  if (pending_install_dict->GetString(kPrefSuggestedPageOrdinal,
1502                                      &serialized_ordinal)) {
1503    suggested_page_ordinal = syncer::StringOrdinal(serialized_ordinal);
1504    needs_sort_ordinal = true;
1505    pending_install_dict->Remove(kPrefSuggestedPageOrdinal, NULL);
1506  }
1507  pending_install_dict->Remove(kDelayedInstallReason, NULL);
1508
1509  const base::Time install_time = time_provider_->GetCurrentTime();
1510  pending_install_dict->Set(
1511      kPrefInstallTime,
1512      new base::StringValue(
1513          base::Int64ToString(install_time.ToInternalValue())));
1514
1515  // Commit the delayed install data.
1516  for (base::DictionaryValue::Iterator it(*pending_install_dict); !it.IsAtEnd();
1517       it.Advance()) {
1518    extension_dict->Set(it.key(), it.value().DeepCopy());
1519  }
1520  FinishExtensionInfoPrefs(extension_id, install_time, needs_sort_ordinal,
1521                           suggested_page_ordinal, extension_dict);
1522  return true;
1523}
1524
1525scoped_ptr<ExtensionInfo> ExtensionPrefs::GetDelayedInstallInfo(
1526    const std::string& extension_id) const {
1527  const base::DictionaryValue* extension_prefs =
1528      GetExtensionPref(extension_id);
1529  if (!extension_prefs)
1530    return scoped_ptr<ExtensionInfo>();
1531
1532  const base::DictionaryValue* ext = NULL;
1533  if (!extension_prefs->GetDictionary(kDelayedInstallInfo, &ext))
1534    return scoped_ptr<ExtensionInfo>();
1535
1536  return GetInstalledInfoHelper(extension_id, ext);
1537}
1538
1539ExtensionPrefs::DelayReason ExtensionPrefs::GetDelayedInstallReason(
1540    const std::string& extension_id) const {
1541  const base::DictionaryValue* extension_prefs =
1542      GetExtensionPref(extension_id);
1543  if (!extension_prefs)
1544    return DELAY_REASON_NONE;
1545
1546  const base::DictionaryValue* ext = NULL;
1547  if (!extension_prefs->GetDictionary(kDelayedInstallInfo, &ext))
1548    return DELAY_REASON_NONE;
1549
1550  int delay_reason;
1551  if (!ext->GetInteger(kDelayedInstallReason, &delay_reason))
1552    return DELAY_REASON_NONE;
1553
1554  return static_cast<DelayReason>(delay_reason);
1555}
1556
1557scoped_ptr<ExtensionPrefs::ExtensionsInfo> ExtensionPrefs::
1558    GetAllDelayedInstallInfo() const {
1559  scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
1560
1561  const base::DictionaryValue* extensions =
1562      prefs_->GetDictionary(pref_names::kExtensions);
1563  for (base::DictionaryValue::Iterator extension_id(*extensions);
1564       !extension_id.IsAtEnd(); extension_id.Advance()) {
1565    if (!Extension::IdIsValid(extension_id.key()))
1566      continue;
1567
1568    scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key());
1569    if (info)
1570      extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
1571  }
1572
1573  return extensions_info.Pass();
1574}
1575
1576bool ExtensionPrefs::IsEphemeralApp(const std::string& extension_id) const {
1577  if (ReadPrefAsBooleanAndReturn(extension_id, kPrefEphemeralApp))
1578    return true;
1579
1580  // Ephemerality was previously stored in the creation flags, so we must also
1581  // check it for backcompatibility.
1582  return (GetCreationFlags(extension_id) & Extension::IS_EPHEMERAL) != 0;
1583}
1584
1585void ExtensionPrefs::OnEphemeralAppPromoted(const std::string& extension_id) {
1586  DCHECK(IsEphemeralApp(extension_id));
1587
1588  UpdateExtensionPref(
1589      extension_id, kPrefEphemeralApp, new base::FundamentalValue(false));
1590}
1591
1592bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) {
1593  return ReadPrefAsBooleanAndReturn(extension_id, kPrefUserDraggedApp);
1594}
1595
1596void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) {
1597  UpdateExtensionPref(extension_id, kPrefUserDraggedApp,
1598                      new base::FundamentalValue(true));
1599}
1600
1601bool ExtensionPrefs::IsFromWebStore(
1602    const std::string& extension_id) const {
1603  const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1604  bool result = false;
1605  if (dictionary && dictionary->GetBoolean(kPrefFromWebStore, &result))
1606    return result;
1607  return false;
1608}
1609
1610bool ExtensionPrefs::IsFromBookmark(
1611    const std::string& extension_id) const {
1612  const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1613  bool result = false;
1614  if (dictionary && dictionary->GetBoolean(kPrefFromBookmark, &result))
1615    return result;
1616  return false;
1617}
1618
1619int ExtensionPrefs::GetCreationFlags(const std::string& extension_id) const {
1620  int creation_flags = Extension::NO_FLAGS;
1621  if (!ReadPrefAsInteger(extension_id, kPrefCreationFlags, &creation_flags)) {
1622    // Since kPrefCreationFlags was added later, it will be missing for
1623    // previously installed extensions.
1624    if (IsFromBookmark(extension_id))
1625      creation_flags |= Extension::FROM_BOOKMARK;
1626    if (IsFromWebStore(extension_id))
1627      creation_flags |= Extension::FROM_WEBSTORE;
1628    if (WasInstalledByDefault(extension_id))
1629      creation_flags |= Extension::WAS_INSTALLED_BY_DEFAULT;
1630    if (WasInstalledByOem(extension_id))
1631      creation_flags |= Extension::WAS_INSTALLED_BY_OEM;
1632  }
1633  return creation_flags;
1634}
1635
1636int ExtensionPrefs::GetDelayedInstallCreationFlags(
1637    const std::string& extension_id) const {
1638  int creation_flags = Extension::NO_FLAGS;
1639  const base::DictionaryValue* delayed_info = NULL;
1640  if (ReadPrefAsDictionary(extension_id, kDelayedInstallInfo, &delayed_info)) {
1641    delayed_info->GetInteger(kPrefCreationFlags, &creation_flags);
1642  }
1643  return creation_flags;
1644}
1645
1646bool ExtensionPrefs::WasInstalledByDefault(
1647    const std::string& extension_id) const {
1648  const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1649  bool result = false;
1650  if (dictionary &&
1651      dictionary->GetBoolean(kPrefWasInstalledByDefault, &result))
1652    return result;
1653  return false;
1654}
1655
1656bool ExtensionPrefs::WasInstalledByOem(const std::string& extension_id) const {
1657  const base::DictionaryValue* dictionary = GetExtensionPref(extension_id);
1658  bool result = false;
1659  if (dictionary && dictionary->GetBoolean(kPrefWasInstalledByOem, &result))
1660    return result;
1661  return false;
1662}
1663
1664base::Time ExtensionPrefs::GetInstallTime(
1665    const std::string& extension_id) const {
1666  const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1667  if (!extension) {
1668    NOTREACHED();
1669    return base::Time();
1670  }
1671  std::string install_time_str;
1672  if (!extension->GetString(kPrefInstallTime, &install_time_str))
1673    return base::Time();
1674  int64 install_time_i64 = 0;
1675  if (!base::StringToInt64(install_time_str, &install_time_i64))
1676    return base::Time();
1677  return base::Time::FromInternalValue(install_time_i64);
1678}
1679
1680bool ExtensionPrefs::DoNotSync(const std::string& extension_id) const {
1681  bool do_not_sync;
1682  if (!ReadPrefAsBoolean(extension_id, kPrefDoNotSync, &do_not_sync))
1683    return false;
1684
1685  return do_not_sync;
1686}
1687
1688base::Time ExtensionPrefs::GetLastLaunchTime(
1689    const std::string& extension_id) const {
1690  const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1691  if (!extension)
1692    return base::Time();
1693
1694  std::string launch_time_str;
1695  if (!extension->GetString(kPrefLastLaunchTime, &launch_time_str))
1696    return base::Time();
1697  int64 launch_time_i64 = 0;
1698  if (!base::StringToInt64(launch_time_str, &launch_time_i64))
1699    return base::Time();
1700  return base::Time::FromInternalValue(launch_time_i64);
1701}
1702
1703void ExtensionPrefs::SetLastLaunchTime(const std::string& extension_id,
1704                                       const base::Time& time) {
1705  DCHECK(Extension::IdIsValid(extension_id));
1706  ScopedExtensionPrefUpdate update(prefs_, extension_id);
1707  SaveTime(update.Get(), kPrefLastLaunchTime, time);
1708}
1709
1710void ExtensionPrefs::GetExtensions(ExtensionIdList* out) {
1711  CHECK(out);
1712
1713  scoped_ptr<ExtensionsInfo> extensions_info(GetInstalledExtensionsInfo());
1714
1715  for (size_t i = 0; i < extensions_info->size(); ++i) {
1716    ExtensionInfo* info = extensions_info->at(i).get();
1717    out->push_back(info->extension_id);
1718  }
1719}
1720
1721// static
1722ExtensionIdList ExtensionPrefs::GetExtensionsFrom(
1723    const PrefService* pref_service) {
1724  ExtensionIdList result;
1725
1726  const base::DictionaryValue* extension_prefs = NULL;
1727  const base::Value* extension_prefs_value =
1728      pref_service->GetUserPrefValue(pref_names::kExtensions);
1729  if (!extension_prefs_value ||
1730      !extension_prefs_value->GetAsDictionary(&extension_prefs)) {
1731    return result;  // Empty set
1732  }
1733
1734  for (base::DictionaryValue::Iterator it(*extension_prefs); !it.IsAtEnd();
1735       it.Advance()) {
1736    const base::DictionaryValue* ext = NULL;
1737    if (!it.value().GetAsDictionary(&ext)) {
1738      NOTREACHED() << "Invalid pref for extension " << it.key();
1739      continue;
1740    }
1741    if (!IsBlacklistBitSet(ext))
1742      result.push_back(it.key());
1743  }
1744  return result;
1745}
1746
1747void ExtensionPrefs::AddObserver(ExtensionPrefsObserver* observer) {
1748  observer_list_.AddObserver(observer);
1749}
1750
1751void ExtensionPrefs::RemoveObserver(ExtensionPrefsObserver* observer) {
1752  observer_list_.RemoveObserver(observer);
1753}
1754
1755void ExtensionPrefs::FixMissingPrefs(const ExtensionIdList& extension_ids) {
1756  // Fix old entries that did not get an installation time entry when they
1757  // were installed or don't have a preferences field.
1758  for (ExtensionIdList::const_iterator ext_id = extension_ids.begin();
1759       ext_id != extension_ids.end(); ++ext_id) {
1760    if (GetInstallTime(*ext_id) == base::Time()) {
1761      VLOG(1) << "Could not parse installation time of extension "
1762              << *ext_id << ". It was probably installed before setting "
1763              << kPrefInstallTime << " was introduced. Updating "
1764              << kPrefInstallTime << " to the current time.";
1765      const base::Time install_time = time_provider_->GetCurrentTime();
1766      UpdateExtensionPref(*ext_id,
1767                          kPrefInstallTime,
1768                          new base::StringValue(base::Int64ToString(
1769                              install_time.ToInternalValue())));
1770    }
1771  }
1772}
1773
1774void ExtensionPrefs::InitPrefStore() {
1775  if (extensions_disabled_) {
1776    extension_pref_value_map_->NotifyInitializationCompleted();
1777    return;
1778  }
1779
1780  // When this is called, the PrefService is initialized and provides access
1781  // to the user preferences stored in a JSON file.
1782  ExtensionIdList extension_ids;
1783  GetExtensions(&extension_ids);
1784  // Create empty preferences dictionary for each extension (these dictionaries
1785  // are pruned when persisting the preferences to disk).
1786  for (ExtensionIdList::iterator ext_id = extension_ids.begin();
1787       ext_id != extension_ids.end(); ++ext_id) {
1788    ScopedExtensionPrefUpdate update(prefs_, *ext_id);
1789    // This creates an empty dictionary if none is stored.
1790    update.Get();
1791  }
1792
1793  FixMissingPrefs(extension_ids);
1794  MigratePermissions(extension_ids);
1795  MigrateDisableReasons(extension_ids);
1796  app_sorting_->Initialize(extension_ids);
1797
1798  InitExtensionControlledPrefs(extension_pref_value_map_);
1799
1800  extension_pref_value_map_->NotifyInitializationCompleted();
1801}
1802
1803bool ExtensionPrefs::HasIncognitoPrefValue(const std::string& pref_key) {
1804  bool has_incognito_pref_value = false;
1805  extension_pref_value_map_->GetEffectivePrefValue(pref_key,
1806                                                   true,
1807                                                   &has_incognito_pref_value);
1808  return has_incognito_pref_value;
1809}
1810
1811URLPatternSet ExtensionPrefs::GetAllowedInstallSites() {
1812  URLPatternSet result;
1813  const base::ListValue* list =
1814      prefs_->GetList(pref_names::kAllowedInstallSites);
1815  CHECK(list);
1816
1817  for (size_t i = 0; i < list->GetSize(); ++i) {
1818    std::string entry_string;
1819    URLPattern entry(URLPattern::SCHEME_ALL);
1820    if (!list->GetString(i, &entry_string) ||
1821        entry.Parse(entry_string) != URLPattern::PARSE_SUCCESS) {
1822      LOG(ERROR) << "Invalid value for preference: "
1823                 << pref_names::kAllowedInstallSites << "." << i;
1824      continue;
1825    }
1826    result.AddPattern(entry);
1827  }
1828
1829  return result;
1830}
1831
1832const base::DictionaryValue* ExtensionPrefs::GetGeometryCache(
1833    const std::string& extension_id) const {
1834  const base::DictionaryValue* extension_prefs = GetExtensionPref(extension_id);
1835  if (!extension_prefs)
1836    return NULL;
1837
1838  const base::DictionaryValue* ext = NULL;
1839  if (!extension_prefs->GetDictionary(kPrefGeometryCache, &ext))
1840    return NULL;
1841
1842  return ext;
1843}
1844
1845void ExtensionPrefs::SetGeometryCache(
1846    const std::string& extension_id,
1847    scoped_ptr<base::DictionaryValue> cache) {
1848  UpdateExtensionPref(extension_id, kPrefGeometryCache, cache.release());
1849}
1850
1851const base::DictionaryValue* ExtensionPrefs::GetInstallSignature() {
1852  return prefs_->GetDictionary(kInstallSignature);
1853}
1854
1855void ExtensionPrefs::SetInstallSignature(
1856    const base::DictionaryValue* signature) {
1857  if (signature) {
1858    prefs_->Set(kInstallSignature, *signature);
1859    DVLOG(1) << "SetInstallSignature - saving";
1860  } else {
1861    DVLOG(1) << "SetInstallSignature - clearing";
1862    prefs_->ClearPref(kInstallSignature);
1863  }
1864}
1865
1866std::string ExtensionPrefs::GetInstallParam(
1867    const std::string& extension_id) const {
1868  const base::DictionaryValue* extension = GetExtensionPref(extension_id);
1869  if (!extension)  // Expected during unit testing.
1870    return std::string();
1871  std::string install_parameter;
1872  if (!extension->GetString(kPrefInstallParam, &install_parameter))
1873    return std::string();
1874  return install_parameter;
1875}
1876
1877void ExtensionPrefs::SetInstallParam(const std::string& extension_id,
1878                                     const std::string& install_parameter) {
1879  UpdateExtensionPref(extension_id,
1880                      kPrefInstallParam,
1881                      new base::StringValue(install_parameter));
1882}
1883
1884ExtensionPrefs::ExtensionPrefs(
1885    PrefService* prefs,
1886    const base::FilePath& root_dir,
1887    ExtensionPrefValueMap* extension_pref_value_map,
1888    scoped_ptr<AppSorting> app_sorting,
1889    scoped_ptr<TimeProvider> time_provider,
1890    bool extensions_disabled,
1891    const std::vector<ExtensionPrefsObserver*>& early_observers)
1892    : prefs_(prefs),
1893      install_directory_(root_dir),
1894      extension_pref_value_map_(extension_pref_value_map),
1895      app_sorting_(app_sorting.Pass()),
1896      time_provider_(time_provider.Pass()),
1897      extensions_disabled_(extensions_disabled) {
1898  app_sorting_->SetExtensionScopedPrefs(this);
1899  MakePathsRelative();
1900
1901  // Ensure that any early observers are watching before prefs are initialized.
1902  for (std::vector<ExtensionPrefsObserver*>::const_iterator iter =
1903           early_observers.begin();
1904       iter != early_observers.end();
1905       ++iter) {
1906    AddObserver(*iter);
1907  }
1908
1909  InitPrefStore();
1910}
1911
1912void ExtensionPrefs::SetNeedsStorageGarbageCollection(bool value) {
1913  prefs_->SetBoolean(pref_names::kStorageGarbageCollect, value);
1914}
1915
1916bool ExtensionPrefs::NeedsStorageGarbageCollection() {
1917  return prefs_->GetBoolean(pref_names::kStorageGarbageCollect);
1918}
1919
1920// static
1921void ExtensionPrefs::RegisterProfilePrefs(
1922    user_prefs::PrefRegistrySyncable* registry) {
1923  registry->RegisterDictionaryPref(
1924      pref_names::kExtensions,
1925      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1926  registry->RegisterListPref(pref_names::kToolbar,
1927                             user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
1928  registry->RegisterIntegerPref(
1929      pref_names::kToolbarSize,
1930      -1,  // default value
1931      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1932  registry->RegisterDictionaryPref(
1933      kExtensionsBlacklistUpdate,
1934      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1935  registry->RegisterListPref(pref_names::kInstallAllowList,
1936                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1937  registry->RegisterListPref(pref_names::kInstallDenyList,
1938                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1939  registry->RegisterDictionaryPref(
1940      pref_names::kInstallForceList,
1941      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1942  registry->RegisterListPref(pref_names::kAllowedTypes,
1943                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1944  registry->RegisterBooleanPref(
1945      pref_names::kStorageGarbageCollect,
1946      false,  // default value
1947      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1948  registry->RegisterInt64Pref(
1949      pref_names::kLastUpdateCheck,
1950      0,  // default value
1951      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1952  registry->RegisterInt64Pref(
1953      pref_names::kNextUpdateCheck,
1954      0,  // default value
1955      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1956  registry->RegisterListPref(pref_names::kAllowedInstallSites,
1957                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1958  registry->RegisterStringPref(
1959      pref_names::kLastChromeVersion,
1960      std::string(),  // default value
1961      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1962  registry->RegisterListPref(pref_names::kKnownDisabled,
1963                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1964#if defined(TOOLKIT_VIEWS)
1965  registry->RegisterIntegerPref(
1966      pref_names::kBrowserActionContainerWidth,
1967      0,
1968      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1969#endif
1970  registry->RegisterDictionaryPref(
1971      kInstallSignature,
1972      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1973
1974  registry->RegisterListPref(pref_names::kNativeMessagingBlacklist,
1975                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1976  registry->RegisterListPref(pref_names::kNativeMessagingWhitelist,
1977                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1978  registry->RegisterBooleanPref(
1979      pref_names::kNativeMessagingUserLevelHosts,
1980      true,  // default value
1981      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1982}
1983
1984template <class ExtensionIdContainer>
1985bool ExtensionPrefs::GetUserExtensionPrefIntoContainer(
1986    const char* pref,
1987    ExtensionIdContainer* id_container_out) {
1988  DCHECK(id_container_out->empty());
1989
1990  const base::Value* user_pref_value = prefs_->GetUserPrefValue(pref);
1991  const base::ListValue* user_pref_as_list;
1992  if (!user_pref_value || !user_pref_value->GetAsList(&user_pref_as_list))
1993    return false;
1994
1995  std::insert_iterator<ExtensionIdContainer> insert_iterator(
1996      *id_container_out, id_container_out->end());
1997  std::string extension_id;
1998  for (base::ListValue::const_iterator value_it = user_pref_as_list->begin();
1999       value_it != user_pref_as_list->end(); ++value_it) {
2000    if (!(*value_it)->GetAsString(&extension_id)) {
2001      NOTREACHED();
2002      continue;
2003    }
2004    insert_iterator = extension_id;
2005  }
2006  return true;
2007}
2008
2009template <class ExtensionIdContainer>
2010void ExtensionPrefs::SetExtensionPrefFromContainer(
2011    const char* pref,
2012    const ExtensionIdContainer& strings) {
2013  ListPrefUpdate update(prefs_, pref);
2014  base::ListValue* list_of_values = update.Get();
2015  list_of_values->Clear();
2016  for (typename ExtensionIdContainer::const_iterator iter = strings.begin();
2017       iter != strings.end(); ++iter) {
2018    list_of_values->Append(new base::StringValue(*iter));
2019  }
2020}
2021
2022void ExtensionPrefs::PopulateExtensionInfoPrefs(
2023    const Extension* extension,
2024    const base::Time install_time,
2025    Extension::State initial_state,
2026    int install_flags,
2027    const std::string& install_parameter,
2028    base::DictionaryValue* extension_dict) {
2029  // Leave the state blank for component extensions so that old chrome versions
2030  // loading new profiles do not fail in GetInstalledExtensionInfo. Older
2031  // Chrome versions would only check for an omitted state.
2032  if (initial_state != Extension::ENABLED_COMPONENT)
2033    extension_dict->Set(kPrefState, new base::FundamentalValue(initial_state));
2034
2035  extension_dict->Set(kPrefLocation,
2036                      new base::FundamentalValue(extension->location()));
2037  extension_dict->Set(kPrefCreationFlags,
2038                      new base::FundamentalValue(extension->creation_flags()));
2039  extension_dict->Set(kPrefFromWebStore,
2040                      new base::FundamentalValue(extension->from_webstore()));
2041  extension_dict->Set(kPrefFromBookmark,
2042                      new base::FundamentalValue(extension->from_bookmark()));
2043  extension_dict->Set(
2044      kPrefWasInstalledByDefault,
2045      new base::FundamentalValue(extension->was_installed_by_default()));
2046  extension_dict->Set(
2047      kPrefWasInstalledByOem,
2048      new base::FundamentalValue(extension->was_installed_by_oem()));
2049  extension_dict->Set(kPrefInstallTime,
2050                      new base::StringValue(
2051                          base::Int64ToString(install_time.ToInternalValue())));
2052  if (install_flags & kInstallFlagIsBlacklistedForMalware)
2053    extension_dict->Set(kPrefBlacklist, new base::FundamentalValue(true));
2054
2055  // TODO(tmdiep): Delete the pref if false, don't write false.
2056  bool is_ephemeral = (install_flags & kInstallFlagIsEphemeral) != 0;
2057  extension_dict->Set(kPrefEphemeralApp,
2058                      new base::FundamentalValue(is_ephemeral));
2059
2060  base::FilePath::StringType path = MakePathRelative(install_directory_,
2061                                                     extension->path());
2062  extension_dict->Set(kPrefPath, new base::StringValue(path));
2063  if (!install_parameter.empty()) {
2064    extension_dict->Set(kPrefInstallParam,
2065                        new base::StringValue(install_parameter));
2066  }
2067  // We store prefs about LOAD extensions, but don't cache their manifest
2068  // since it may change on disk.
2069  if (!Manifest::IsUnpackedLocation(extension->location())) {
2070    extension_dict->Set(kPrefManifest,
2071                        extension->manifest()->value()->DeepCopy());
2072  }
2073
2074  // Only writes kPrefDoNotSync when it is not the default.
2075  if (install_flags & kInstallFlagDoNotSync)
2076    extension_dict->Set(kPrefDoNotSync, new base::FundamentalValue(true));
2077  else
2078    extension_dict->Remove(kPrefDoNotSync, NULL);
2079}
2080
2081void ExtensionPrefs::InitExtensionControlledPrefs(
2082    ExtensionPrefValueMap* value_map) {
2083  ExtensionIdList extension_ids;
2084  GetExtensions(&extension_ids);
2085
2086  for (ExtensionIdList::iterator extension_id = extension_ids.begin();
2087       extension_id != extension_ids.end();
2088       ++extension_id) {
2089    base::Time install_time = GetInstallTime(*extension_id);
2090    bool is_enabled = !IsExtensionDisabled(*extension_id);
2091    bool is_incognito_enabled = IsIncognitoEnabled(*extension_id);
2092    value_map->RegisterExtension(
2093        *extension_id, install_time, is_enabled, is_incognito_enabled);
2094
2095    FOR_EACH_OBSERVER(
2096        ExtensionPrefsObserver,
2097        observer_list_,
2098        OnExtensionRegistered(*extension_id, install_time, is_enabled));
2099
2100    // Set regular extension controlled prefs.
2101    LoadExtensionControlledPrefs(
2102        this, value_map, *extension_id, kExtensionPrefsScopeRegular);
2103    // Set incognito extension controlled prefs.
2104    LoadExtensionControlledPrefs(this,
2105                                 value_map,
2106                                 *extension_id,
2107                                 kExtensionPrefsScopeIncognitoPersistent);
2108    // Set regular-only extension controlled prefs.
2109    LoadExtensionControlledPrefs(
2110        this, value_map, *extension_id, kExtensionPrefsScopeRegularOnly);
2111
2112    FOR_EACH_OBSERVER(ExtensionPrefsObserver,
2113                      observer_list_,
2114                      OnExtensionPrefsLoaded(*extension_id, this));
2115  }
2116}
2117
2118void ExtensionPrefs::FinishExtensionInfoPrefs(
2119    const std::string& extension_id,
2120    const base::Time install_time,
2121    bool needs_sort_ordinal,
2122    const syncer::StringOrdinal& suggested_page_ordinal,
2123    base::DictionaryValue* extension_dict) {
2124  // Reinitializes various preferences with empty dictionaries.
2125  if (!extension_dict->HasKey(pref_names::kPrefPreferences)) {
2126    extension_dict->Set(pref_names::kPrefPreferences,
2127                        new base::DictionaryValue);
2128  }
2129
2130  if (!extension_dict->HasKey(pref_names::kPrefIncognitoPreferences)) {
2131    extension_dict->Set(pref_names::kPrefIncognitoPreferences,
2132                        new base::DictionaryValue);
2133  }
2134
2135  if (!extension_dict->HasKey(pref_names::kPrefRegularOnlyPreferences)) {
2136    extension_dict->Set(pref_names::kPrefRegularOnlyPreferences,
2137                        new base::DictionaryValue);
2138  }
2139
2140  if (!extension_dict->HasKey(pref_names::kPrefContentSettings))
2141    extension_dict->Set(pref_names::kPrefContentSettings, new base::ListValue);
2142
2143  if (!extension_dict->HasKey(pref_names::kPrefIncognitoContentSettings)) {
2144    extension_dict->Set(pref_names::kPrefIncognitoContentSettings,
2145                        new base::ListValue);
2146  }
2147
2148  // If this point has been reached, any pending installs should be considered
2149  // out of date.
2150  extension_dict->Remove(kDelayedInstallInfo, NULL);
2151
2152  // Clear state that may be registered from a previous install.
2153  extension_dict->Remove(EventRouter::kRegisteredEvents, NULL);
2154
2155  // FYI, all code below here races on sudden shutdown because |extension_dict|,
2156  // |app_sorting_|, |extension_pref_value_map_|, and (potentially) observers
2157  // are updated non-transactionally. This is probably not fixable without
2158  // nested transactional updates to pref dictionaries.
2159  if (needs_sort_ordinal)
2160    app_sorting_->EnsureValidOrdinals(extension_id, suggested_page_ordinal);
2161
2162  bool is_enabled = false;
2163  int initial_state;
2164  if (extension_dict->GetInteger(kPrefState, &initial_state)) {
2165    is_enabled = initial_state == Extension::ENABLED;
2166  }
2167  bool is_incognito_enabled = IsIncognitoEnabled(extension_id);
2168
2169  extension_pref_value_map_->RegisterExtension(
2170      extension_id, install_time, is_enabled, is_incognito_enabled);
2171
2172  FOR_EACH_OBSERVER(
2173      ExtensionPrefsObserver,
2174      observer_list_,
2175      OnExtensionRegistered(extension_id, install_time, is_enabled));
2176}
2177
2178}  // namespace extensions
2179