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