Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / extension_prefs.cc
index 24f7e58..e0cd673 100644 (file)
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/value_conversions.h"
-#include "chrome/browser/extensions/api/content_settings/content_settings_store.h"
-#include "components/user_prefs/pref_registry_syncable.h"
-#include "extensions/browser/admin_policy.h"
+#include "components/crx_file/id_util.h"
+#include "components/pref_registry/pref_registry_syncable.h"
 #include "extensions/browser/app_sorting.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_pref_store.h"
 #include "extensions/browser/extension_prefs_factory.h"
+#include "extensions/browser/extension_prefs_observer.h"
+#include "extensions/browser/install_flag.h"
 #include "extensions/browser/pref_names.h"
 #include "extensions/common/feature_switch.h"
 #include "extensions/common/manifest.h"
@@ -77,6 +78,8 @@ const char kPrefExternalAcknowledged[] = "ack_external";
 const char kPrefBlacklistAcknowledged[] = "ack_blacklist";
 const char kPrefWipeoutAcknowledged[] = "ack_wiped";
 const char kPrefSettingsBubbleAcknowledged[] = "ack_settings_bubble";
+const char kPrefNtpBubbleAcknowledged[] = "ack_ntp_bubble";
+const char kPrefProxyBubbleAcknowledged[] = "ack_proxy_bubble";
 
 // Indicates whether the external extension was installed during the first
 // run of this profile.
@@ -179,10 +182,8 @@ const char kPrefGeometryCache[] = "geometry_cache";
 // A preference that indicates when an extension is last launched.
 const char kPrefLastLaunchTime[] = "last_launch_time";
 
-// A preference that marks an ephemeral app that was evicted from the cache.
-// Their data is retained and garbage collected when inactive for a long period
-// of time.
-const char kPrefEvictedEphemeralApp[] = "evicted_ephemeral_app";
+// A preference indicating whether the extension is an ephemeral app.
+const char kPrefEphemeralApp[] = "ephemeral_app";
 
 // Am installation parameter bundled with an extension.
 const char kPrefInstallParam[] = "install_parameter";
@@ -190,6 +191,12 @@ const char kPrefInstallParam[] = "install_parameter";
 // A list of installed ids and a signature.
 const char kInstallSignature[] = "extensions.install_signature";
 
+// A boolean preference that indicates whether the extension should not be
+// synced. Default value is false.
+const char kPrefDoNotSync[] = "do_not_sync";
+
+const char kCorruptedDisableCount[] = "extensions.corrupted_disable_count";
+
 // Provider of write access to a dictionary storing extension prefs.
 class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate {
  public:
@@ -231,11 +238,6 @@ bool IsBlacklistBitSet(const base::DictionaryValue* ext) {
   return ext->GetBoolean(kPrefBlacklist, &bool_value) && bool_value;
 }
 
-bool IsEvictedEphemeralApp(const base::DictionaryValue* ext) {
-  bool bool_value;
-  return ext->GetBoolean(kPrefEvictedEphemeralApp, &bool_value) && bool_value;
-}
-
 void LoadExtensionControlledPrefs(ExtensionPrefs* prefs,
                                   ExtensionPrefValueMap* value_map,
                                   const std::string& extension_id,
@@ -258,53 +260,6 @@ void LoadExtensionControlledPrefs(ExtensionPrefs* prefs,
   }
 }
 
-void InitExtensionControlledPrefs(ExtensionPrefs* prefs,
-                                  ExtensionPrefValueMap* value_map) {
-  ExtensionIdList extension_ids;
-  prefs->GetExtensions(&extension_ids);
-
-  for (ExtensionIdList::iterator extension_id = extension_ids.begin();
-       extension_id != extension_ids.end();
-       ++extension_id) {
-    base::Time install_time = prefs->GetInstallTime(*extension_id);
-    bool is_enabled = !prefs->IsExtensionDisabled(*extension_id);
-    bool is_incognito_enabled = prefs->IsIncognitoEnabled(*extension_id);
-    value_map->RegisterExtension(
-        *extension_id, install_time, is_enabled, is_incognito_enabled);
-    prefs->content_settings_store()->RegisterExtension(
-        *extension_id, install_time, is_enabled);
-
-    // Set regular extension controlled prefs.
-    LoadExtensionControlledPrefs(
-        prefs, value_map, *extension_id, kExtensionPrefsScopeRegular);
-    // Set incognito extension controlled prefs.
-    LoadExtensionControlledPrefs(prefs,
-                                 value_map,
-                                 *extension_id,
-                                 kExtensionPrefsScopeIncognitoPersistent);
-    // Set regular-only extension controlled prefs.
-    LoadExtensionControlledPrefs(
-        prefs, value_map, *extension_id, kExtensionPrefsScopeRegularOnly);
-
-    // Set content settings.
-    const base::ListValue* content_settings = NULL;
-    if (prefs->ReadPrefAsList(*extension_id,
-                              pref_names::kPrefContentSettings,
-                              &content_settings)) {
-      prefs->content_settings_store()->SetExtensionContentSettingFromList(
-          *extension_id, content_settings, kExtensionPrefsScopeRegular);
-    }
-    if (prefs->ReadPrefAsList(*extension_id,
-                              pref_names::kPrefIncognitoContentSettings,
-                              &content_settings)) {
-      prefs->content_settings_store()->SetExtensionContentSettingFromList(
-          *extension_id,
-          content_settings,
-          kExtensionPrefsScopeIncognitoPersistent);
-    }
-  }
-}
-
 }  // namespace
 
 //
@@ -332,7 +287,7 @@ ExtensionPrefs::ScopedUpdate<T, type_enum_value>::ScopedUpdate(
     : update_(prefs->pref_service(), pref_names::kExtensions),
       extension_id_(extension_id),
       key_(key) {
-  DCHECK(Extension::IdIsValid(extension_id_));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id_));
 }
 
 template <typename T, base::Value::Type type_enum_value>
@@ -389,12 +344,14 @@ ExtensionPrefs* ExtensionPrefs::Create(
     const base::FilePath& root_dir,
     ExtensionPrefValueMap* extension_pref_value_map,
     scoped_ptr<AppSorting> app_sorting,
-    bool extensions_disabled) {
+    bool extensions_disabled,
+    const std::vector<ExtensionPrefsObserver*>& early_observers) {
   return ExtensionPrefs::Create(prefs,
                                 root_dir,
                                 extension_pref_value_map,
                                 app_sorting.Pass(),
                                 extensions_disabled,
+                                early_observers,
                                 make_scoped_ptr(new TimeProvider()));
 }
 
@@ -405,13 +362,15 @@ ExtensionPrefs* ExtensionPrefs::Create(
     ExtensionPrefValueMap* extension_pref_value_map,
     scoped_ptr<AppSorting> app_sorting,
     bool extensions_disabled,
+    const std::vector<ExtensionPrefsObserver*>& early_observers,
     scoped_ptr<TimeProvider> time_provider) {
   return new ExtensionPrefs(pref_service,
                             root_dir,
                             extension_pref_value_map,
                             app_sorting.Pass(),
                             time_provider.Pass(),
-                            extensions_disabled);
+                            extensions_disabled,
+                            early_observers);
 }
 
 ExtensionPrefs::~ExtensionPrefs() {
@@ -497,7 +456,7 @@ const base::DictionaryValue* ExtensionPrefs::GetExtensionPref(
 void ExtensionPrefs::UpdateExtensionPref(const std::string& extension_id,
                                          const std::string& key,
                                          base::Value* data_value) {
-  if (!Extension::IdIsValid(extension_id)) {
+  if (!crx_file::id_util::IdIsValid(extension_id)) {
     NOTREACHED() << "Invalid extension_id " << extension_id;
     return;
   }
@@ -510,7 +469,9 @@ void ExtensionPrefs::UpdateExtensionPref(const std::string& extension_id,
 
 void ExtensionPrefs::DeleteExtensionPrefs(const std::string& extension_id) {
   extension_pref_value_map_->UnregisterExtension(extension_id);
-  content_settings_store_->UnregisterExtension(extension_id);
+  FOR_EACH_OBSERVER(ExtensionPrefsObserver,
+                    observer_list_,
+                    OnExtensionPrefsDeleted(extension_id));
   DictionaryPrefUpdate update(prefs_, pref_names::kExtensions);
   base::DictionaryValue* dict = update.Get();
   dict->Remove(extension_id, NULL);
@@ -722,7 +683,7 @@ bool ExtensionPrefs::IsExternalExtensionAcknowledged(
 
 void ExtensionPrefs::AcknowledgeExternalExtension(
     const std::string& extension_id) {
-  DCHECK(Extension::IdIsValid(extension_id));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id));
   UpdateExtensionPref(extension_id, kPrefExternalAcknowledged,
                       new base::FundamentalValue(true));
   UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, NULL);
@@ -735,7 +696,7 @@ bool ExtensionPrefs::IsBlacklistedExtensionAcknowledged(
 
 void ExtensionPrefs::AcknowledgeBlacklistedExtension(
     const std::string& extension_id) {
-  DCHECK(Extension::IdIsValid(extension_id));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id));
   UpdateExtensionPref(extension_id, kPrefBlacklistAcknowledged,
                       new base::FundamentalValue(true));
   UpdateExtensionPref(extension_id, kPrefAcknowledgePromptCount, NULL);
@@ -748,7 +709,7 @@ bool ExtensionPrefs::IsExternalInstallFirstRun(
 
 void ExtensionPrefs::SetExternalInstallFirstRun(
     const std::string& extension_id) {
-  DCHECK(Extension::IdIsValid(extension_id));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id));
   UpdateExtensionPref(extension_id, kPrefExternalInstallFirstRun,
                       new base::FundamentalValue(true));
 }
@@ -761,8 +722,9 @@ bool ExtensionPrefs::HasWipeoutBeenAcknowledged(
 void ExtensionPrefs::SetWipeoutAcknowledged(
     const std::string& extension_id,
     bool value) {
-  UpdateExtensionPref(extension_id, kPrefWipeoutAcknowledged,
-                      value ? base::Value::CreateBooleanValue(value) : NULL);
+  UpdateExtensionPref(extension_id,
+                      kPrefWipeoutAcknowledged,
+                      value ? new base::FundamentalValue(value) : NULL);
 }
 
 bool ExtensionPrefs::HasSettingsApiBubbleBeenAcknowledged(
@@ -776,7 +738,33 @@ void ExtensionPrefs::SetSettingsApiBubbleBeenAcknowledged(
     bool value) {
   UpdateExtensionPref(extension_id,
                       kPrefSettingsBubbleAcknowledged,
-                      value ? base::Value::CreateBooleanValue(value) : NULL);
+                      value ? new base::FundamentalValue(value) : NULL);
+}
+
+bool ExtensionPrefs::HasNtpOverriddenBubbleBeenAcknowledged(
+    const std::string& extension_id) {
+  return ReadPrefAsBooleanAndReturn(extension_id, kPrefNtpBubbleAcknowledged);
+}
+
+void ExtensionPrefs::SetNtpOverriddenBubbleBeenAcknowledged(
+    const std::string& extension_id,
+    bool value) {
+  UpdateExtensionPref(extension_id,
+                      kPrefNtpBubbleAcknowledged,
+                      value ? new base::FundamentalValue(value) : NULL);
+}
+
+bool ExtensionPrefs::HasProxyOverriddenBubbleBeenAcknowledged(
+    const std::string& extension_id) {
+  return ReadPrefAsBooleanAndReturn(extension_id, kPrefProxyBubbleAcknowledged);
+}
+
+void ExtensionPrefs::SetProxyOverriddenBubbleBeenAcknowledged(
+    const std::string& extension_id,
+    bool value) {
+  UpdateExtensionPref(extension_id,
+                      kPrefProxyBubbleAcknowledged,
+                      value ? new base::FundamentalValue(value) : NULL);
 }
 
 bool ExtensionPrefs::SetAlertSystemFirstRun() {
@@ -787,11 +775,6 @@ bool ExtensionPrefs::SetAlertSystemFirstRun() {
   return false;
 }
 
-bool ExtensionPrefs::ExtensionsBlacklistedByDefault() const {
-  return admin_policy::BlacklistedByDefault(
-      prefs_->GetList(pref_names::kInstallDenyList));
-}
-
 bool ExtensionPrefs::DidExtensionEscalatePermissions(
     const std::string& extension_id) {
   return ReadPrefAsBooleanAndReturn(extension_id,
@@ -813,6 +796,12 @@ int ExtensionPrefs::GetDisableReasons(const std::string& extension_id) const {
   return Extension::DISABLE_NONE;
 }
 
+bool ExtensionPrefs::HasDisableReason(
+    const std::string& extension_id,
+    Extension::DisableReason disable_reason) const {
+  return (GetDisableReasons(extension_id) & disable_reason) != 0;
+}
+
 void ExtensionPrefs::AddDisableReason(const std::string& extension_id,
                                       Extension::DisableReason disable_reason) {
   ModifyDisableReason(extension_id, disable_reason, DISABLE_REASON_ADD);
@@ -857,7 +846,7 @@ void ExtensionPrefs::ModifyDisableReason(const std::string& extension_id,
                         new base::FundamentalValue(new_value));
   }
 
-  FOR_EACH_OBSERVER(Observer,
+  FOR_EACH_OBSERVER(ExtensionPrefsObserver,
                     observer_list_,
                     OnExtensionDisableReasonsChanged(extension_id, new_value));
 }
@@ -914,41 +903,58 @@ bool ExtensionPrefs::IsExtensionBlacklisted(const std::string& id) const {
 
 namespace {
 
+// Serializes a 64bit integer as a string value.
+void SaveInt64(base::DictionaryValue* dictionary,
+               const char* key,
+               const int64 value) {
+  if (!dictionary)
+    return;
+
+  std::string string_value = base::Int64ToString(value);
+  dictionary->SetString(key, string_value);
+}
+
+// Deserializes a 64bit integer stored as a string value.
+bool ReadInt64(const base::DictionaryValue* dictionary,
+               const char* key,
+               int64* value) {
+  if (!dictionary)
+    return false;
+
+  std::string string_value;
+  if (!dictionary->GetString(key, &string_value))
+    return false;
+
+  return base::StringToInt64(string_value, value);
+}
+
 // Serializes |time| as a string value mapped to |key| in |dictionary|.
 void SaveTime(base::DictionaryValue* dictionary,
               const char* key,
               const base::Time& time) {
-  if (!dictionary)
-    return;
-  std::string string_value = base::Int64ToString(time.ToInternalValue());
-  dictionary->SetString(key, string_value);
+  SaveInt64(dictionary, key, time.ToInternalValue());
 }
 
 // The opposite of SaveTime. If |key| is not found, this returns an empty Time
 // (is_null() will return true).
 base::Time ReadTime(const base::DictionaryValue* dictionary, const char* key) {
-  if (!dictionary)
-    return base::Time();
-  std::string string_value;
   int64 value;
-  if (dictionary->GetString(key, &string_value)) {
-    if (base::StringToInt64(string_value, &value)) {
-      return base::Time::FromInternalValue(value);
-    }
-  }
+  if (ReadInt64(dictionary, key, &value))
+    return base::Time::FromInternalValue(value);
+
   return base::Time();
 }
 
 }  // namespace
 
 base::Time ExtensionPrefs::LastPingDay(const std::string& extension_id) const {
-  DCHECK(Extension::IdIsValid(extension_id));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id));
   return ReadTime(GetExtensionPref(extension_id), kLastPingDay);
 }
 
 void ExtensionPrefs::SetLastPingDay(const std::string& extension_id,
                                     const base::Time& time) {
-  DCHECK(Extension::IdIsValid(extension_id));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id));
   ScopedExtensionPrefUpdate update(prefs_, extension_id);
   SaveTime(update.Get(), kLastPingDay, time);
 }
@@ -964,13 +970,13 @@ void ExtensionPrefs::SetBlacklistLastPingDay(const base::Time& time) {
 }
 
 base::Time ExtensionPrefs::LastActivePingDay(const std::string& extension_id) {
-  DCHECK(Extension::IdIsValid(extension_id));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id));
   return ReadTime(GetExtensionPref(extension_id), kLastActivePingDay);
 }
 
 void ExtensionPrefs::SetLastActivePingDay(const std::string& extension_id,
                                           const base::Time& time) {
-  DCHECK(Extension::IdIsValid(extension_id));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id));
   ScopedExtensionPrefUpdate update(prefs_, extension_id);
   SaveTime(update.Get(), kLastActivePingDay, time);
 }
@@ -996,7 +1002,7 @@ void ExtensionPrefs::MigratePermissions(const ExtensionIdList& extension_ids) {
     // An extension's granted permissions need to be migrated if the
     // full_access bit is present. This bit was always present in the previous
     // scheme and is never present now.
-    bool full_access;
+    bool full_access = false;
     const base::DictionaryValue* ext = GetExtensionPref(*ext_id);
     if (!ext || !ext->GetBoolean(kPrefOldGrantedFullAccess, &full_access))
       continue;
@@ -1069,14 +1075,14 @@ void ExtensionPrefs::MigrateDisableReasons(
 
 PermissionSet* ExtensionPrefs::GetGrantedPermissions(
     const std::string& extension_id) {
-  CHECK(Extension::IdIsValid(extension_id));
+  CHECK(crx_file::id_util::IdIsValid(extension_id));
   return ReadPrefAsPermissionSet(extension_id, kPrefGrantedPermissions);
 }
 
 void ExtensionPrefs::AddGrantedPermissions(
     const std::string& extension_id,
     const PermissionSet* permissions) {
-  CHECK(Extension::IdIsValid(extension_id));
+  CHECK(crx_file::id_util::IdIsValid(extension_id));
 
   scoped_refptr<PermissionSet> granted_permissions(
       GetGrantedPermissions(extension_id));
@@ -1094,7 +1100,7 @@ void ExtensionPrefs::AddGrantedPermissions(
 void ExtensionPrefs::RemoveGrantedPermissions(
     const std::string& extension_id,
     const PermissionSet* permissions) {
-  CHECK(Extension::IdIsValid(extension_id));
+  CHECK(crx_file::id_util::IdIsValid(extension_id));
 
   scoped_refptr<PermissionSet> granted_permissions(
       GetGrantedPermissions(extension_id));
@@ -1111,7 +1117,7 @@ void ExtensionPrefs::RemoveGrantedPermissions(
 
 PermissionSet* ExtensionPrefs::GetActivePermissions(
     const std::string& extension_id) {
-  CHECK(Extension::IdIsValid(extension_id));
+  CHECK(crx_file::id_util::IdIsValid(extension_id));
   return ReadPrefAsPermissionSet(extension_id, kPrefActivePermissions);
 }
 
@@ -1214,20 +1220,11 @@ void ExtensionPrefs::SetToolbarOrder(const ExtensionIdList& extension_ids) {
   SetExtensionPrefFromContainer(pref_names::kToolbar, extension_ids);
 }
 
-bool ExtensionPrefs::GetKnownDisabled(ExtensionIdSet* id_set_out) {
-  return GetUserExtensionPrefIntoContainer(pref_names::kKnownDisabled,
-                                           id_set_out);
-}
-
-void ExtensionPrefs::SetKnownDisabled(const ExtensionIdSet& extension_ids) {
-  SetExtensionPrefFromContainer(pref_names::kKnownDisabled, extension_ids);
-}
-
 void ExtensionPrefs::OnExtensionInstalled(
     const Extension* extension,
     Extension::State initial_state,
-    bool blacklisted_for_malware,
     const syncer::StringOrdinal& page_ordinal,
+    int install_flags,
     const std::string& install_parameter) {
   ScopedExtensionPrefUpdate update(prefs_, extension->id());
   base::DictionaryValue* extension_dict = update.Get();
@@ -1235,12 +1232,17 @@ void ExtensionPrefs::OnExtensionInstalled(
   PopulateExtensionInfoPrefs(extension,
                              install_time,
                              initial_state,
-                             blacklisted_for_malware,
+                             install_flags,
                              install_parameter,
                              extension_dict);
-  FinishExtensionInfoPrefs(extension->id(), install_time,
-                           extension->RequiresSortOrdinal(),
-                           page_ordinal, extension_dict);
+
+  bool requires_sort_ordinal = extension->RequiresSortOrdinal() &&
+                               (install_flags & kInstallFlagIsEphemeral) == 0;
+  FinishExtensionInfoPrefs(extension->id(),
+                           install_time,
+                           requires_sort_ordinal,
+                           page_ordinal,
+                           extension_dict);
 }
 
 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
@@ -1257,16 +1259,11 @@ void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
                         new base::FundamentalValue(
                             Extension::EXTERNAL_EXTENSION_UNINSTALLED));
     extension_pref_value_map_->SetExtensionState(extension_id, false);
-    content_settings_store_->SetExtensionState(extension_id, false);
+    FOR_EACH_OBSERVER(ExtensionPrefsObserver,
+                      observer_list_,
+                      OnExtensionStateChanged(extension_id, false));
   } else {
-    int creation_flags = GetCreationFlags(extension_id);
-    if (creation_flags & Extension::IS_EPHEMERAL) {
-      // Keep ephemeral apps around, but mark them as evicted.
-      UpdateExtensionPref(extension_id, kPrefEvictedEphemeralApp,
-                          new base::FundamentalValue(true));
-    } else {
-      DeleteExtensionPrefs(extension_id);
-    }
+    DeleteExtensionPrefs(extension_id);
   }
 }
 
@@ -1276,7 +1273,9 @@ void ExtensionPrefs::SetExtensionState(const std::string& extension_id,
                       new base::FundamentalValue(state));
   bool enabled = (state == Extension::ENABLED);
   extension_pref_value_map_->SetExtensionState(extension_id, enabled);
-  content_settings_store_->SetExtensionState(extension_id, enabled);
+  FOR_EACH_OBSERVER(ExtensionPrefsObserver,
+                    observer_list_,
+                    OnExtensionStateChanged(extension_id, enabled));
 }
 
 void ExtensionPrefs::SetExtensionBlacklistState(const std::string& extension_id,
@@ -1291,7 +1290,7 @@ BlacklistState ExtensionPrefs::GetExtensionBlacklistState(
   if (IsExtensionBlacklisted(extension_id))
     return BLACKLISTED_MALWARE;
   const base::DictionaryValue* ext_prefs = GetExtensionPref(extension_id);
-  int int_value;
+  int int_value = 0;
   if (ext_prefs && ext_prefs->GetInteger(kPrefBlacklistState, &int_value))
     return static_cast<BlacklistState>(int_value);
 
@@ -1326,19 +1325,6 @@ void ExtensionPrefs::UpdateManifest(const Extension* extension) {
   }
 }
 
-base::FilePath ExtensionPrefs::GetExtensionPath(
-    const std::string& extension_id) {
-  const base::DictionaryValue* dict = GetExtensionPref(extension_id);
-  if (!dict)
-    return base::FilePath();
-
-  std::string path;
-  if (!dict->GetString(kPrefPath, &path))
-    return base::FilePath();
-
-  return install_directory_.Append(base::FilePath::FromUTF8Unsafe(path));
-}
-
 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledInfoHelper(
     const std::string& extension_id,
     const base::DictionaryValue* extension) const {
@@ -1346,17 +1332,14 @@ scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledInfoHelper(
   if (!extension->GetInteger(kPrefLocation, &location_value))
     return scoped_ptr<ExtensionInfo>();
 
-  base::FilePath::StringType path;
-  if (!extension->GetString(kPrefPath, &path))
-    return scoped_ptr<ExtensionInfo>();
-
-  // Make path absolute. Unpacked extensions will already have absolute paths,
-  // otherwise make it so.
   Manifest::Location location = static_cast<Manifest::Location>(location_value);
-  if (!Manifest::IsUnpackedLocation(location)) {
-    DCHECK(location == Manifest::COMPONENT ||
-           !base::FilePath(path).IsAbsolute());
-    path = install_directory_.Append(path).value();
+  if (location == Manifest::COMPONENT) {
+    // Component extensions are ignored. Component extensions may have data
+    // saved in preferences, but they are already loaded at this point (by
+    // ComponentLoader) and shouldn't be populated into the result of
+    // GetInstalledExtensionsInfo, otherwise InstalledLoader would also want to
+    // load them.
+    return scoped_ptr<ExtensionInfo>();
   }
 
   // Only the following extension types have data saved in the preferences.
@@ -1374,6 +1357,14 @@ scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledInfoHelper(
     // Just a warning for now.
   }
 
+  base::FilePath::StringType path;
+  if (!extension->GetString(kPrefPath, &path))
+    return scoped_ptr<ExtensionInfo>();
+
+  // Make path absolute. Most (but not all) extension types have relative paths.
+  if (!base::FilePath(path).IsAbsolute())
+    path = install_directory_.Append(path).value();
+
   return scoped_ptr<ExtensionInfo>(new ExtensionInfo(
       manifest, extension_id, base::FilePath(path), location));
 }
@@ -1387,23 +1378,13 @@ scoped_ptr<ExtensionInfo> ExtensionPrefs::GetInstalledExtensionInfo(
       !extensions->GetDictionaryWithoutPathExpansion(extension_id, &ext))
     return scoped_ptr<ExtensionInfo>();
   int state_value;
-  if (!ext->GetInteger(kPrefState, &state_value) ||
-      state_value == Extension::ENABLED_COMPONENT) {
-    // Old preferences files may not have kPrefState for component extensions.
-    return scoped_ptr<ExtensionInfo>();
-  }
-
-  if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) {
+  if (ext->GetInteger(kPrefState, &state_value) &&
+      state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) {
     LOG(WARNING) << "External extension with id " << extension_id
                  << " has been uninstalled by the user";
     return scoped_ptr<ExtensionInfo>();
   }
 
-  if (IsEvictedEphemeralApp(ext)) {
-    // Hide evicted ephemeral apps.
-    return scoped_ptr<ExtensionInfo>();
-  }
-
   return GetInstalledInfoHelper(extension_id, ext);
 }
 
@@ -1415,7 +1396,7 @@ ExtensionPrefs::GetInstalledExtensionsInfo() const {
       prefs_->GetDictionary(pref_names::kExtensions);
   for (base::DictionaryValue::Iterator extension_id(*extensions);
        !extension_id.IsAtEnd(); extension_id.Advance()) {
-    if (!Extension::IdIsValid(extension_id.key()))
+    if (!crx_file::id_util::IdIsValid(extension_id.key()))
       continue;
 
     scoped_ptr<ExtensionInfo> info =
@@ -1436,7 +1417,7 @@ ExtensionPrefs::GetUninstalledExtensionsInfo() const {
   for (base::DictionaryValue::Iterator extension_id(*extensions);
        !extension_id.IsAtEnd(); extension_id.Advance()) {
     const base::DictionaryValue* ext = NULL;
-    if (!Extension::IdIsValid(extension_id.key()) ||
+    if (!crx_file::id_util::IdIsValid(extension_id.key()) ||
         !IsExternalExtensionUninstalled(extension_id.key()) ||
         !extension_id.value().GetAsDictionary(&ext))
       continue;
@@ -1453,7 +1434,7 @@ ExtensionPrefs::GetUninstalledExtensionsInfo() const {
 void ExtensionPrefs::SetDelayedInstallInfo(
     const Extension* extension,
     Extension::State initial_state,
-    bool blacklisted_for_malware,
+    int install_flags,
     DelayReason delay_reason,
     const syncer::StringOrdinal& page_ordinal,
     const std::string& install_parameter) {
@@ -1461,14 +1442,15 @@ void ExtensionPrefs::SetDelayedInstallInfo(
   PopulateExtensionInfoPrefs(extension,
                              time_provider_->GetCurrentTime(),
                              initial_state,
-                             blacklisted_for_malware,
+                             install_flags,
                              install_parameter,
                              extension_dict);
 
   // Add transient data that is needed by FinishDelayedInstallInfo(), but
   // should not be in the final extension prefs. All entries here should have
   // a corresponding Remove() call in FinishDelayedInstallInfo().
-  if (extension->RequiresSortOrdinal()) {
+  if (extension->RequiresSortOrdinal() &&
+      (install_flags & kInstallFlagIsEphemeral) == 0) {
     extension_dict->SetString(
         kPrefSuggestedPageOrdinal,
         page_ordinal.IsValid() ? page_ordinal.ToInternalValue()
@@ -1491,7 +1473,7 @@ bool ExtensionPrefs::RemoveDelayedInstallInfo(
 
 bool ExtensionPrefs::FinishDelayedInstallInfo(
     const std::string& extension_id) {
-  CHECK(Extension::IdIsValid(extension_id));
+  CHECK(crx_file::id_util::IdIsValid(extension_id));
   ScopedExtensionPrefUpdate update(prefs_, extension_id);
   base::DictionaryValue* extension_dict = update.Get();
   base::DictionaryValue* pending_install_dict = NULL;
@@ -1519,6 +1501,11 @@ bool ExtensionPrefs::FinishDelayedInstallInfo(
       new base::StringValue(
           base::Int64ToString(install_time.ToInternalValue())));
 
+  // Some extension pref values are written conditionally. If they are not
+  // present in the delayed install data, they should be removed when the
+  // delayed install is committed.
+  extension_dict->Remove(kPrefEphemeralApp, NULL);
+
   // Commit the delayed install data.
   for (base::DictionaryValue::Iterator it(*pending_install_dict); !it.IsAtEnd();
        it.Advance()) {
@@ -1569,7 +1556,7 @@ scoped_ptr<ExtensionPrefs::ExtensionsInfo> ExtensionPrefs::
       prefs_->GetDictionary(pref_names::kExtensions);
   for (base::DictionaryValue::Iterator extension_id(*extensions);
        !extension_id.IsAtEnd(); extension_id.Advance()) {
-    if (!Extension::IdIsValid(extension_id.key()))
+    if (!crx_file::id_util::IdIsValid(extension_id.key()))
       continue;
 
     scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key());
@@ -1580,51 +1567,30 @@ scoped_ptr<ExtensionPrefs::ExtensionsInfo> ExtensionPrefs::
   return extensions_info.Pass();
 }
 
-scoped_ptr<ExtensionPrefs::ExtensionsInfo>
-ExtensionPrefs::GetEvictedEphemeralAppsInfo() const {
-  scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo);
-
-  const base::DictionaryValue* extensions =
-      prefs_->GetDictionary(pref_names::kExtensions);
-  for (base::DictionaryValue::Iterator extension_id(*extensions);
-       !extension_id.IsAtEnd(); extension_id.Advance()) {
-    const base::DictionaryValue* ext = NULL;
-    if (!Extension::IdIsValid(extension_id.key()) ||
-        !extension_id.value().GetAsDictionary(&ext)) {
-      continue;
-    }
-
-    if (!IsEvictedEphemeralApp(ext))
-      continue;
-
-    scoped_ptr<ExtensionInfo> info =
-        GetInstalledInfoHelper(extension_id.key(), ext);
-    if (info)
-      extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release()));
-  }
+bool ExtensionPrefs::IsEphemeralApp(const std::string& extension_id) const {
+  if (ReadPrefAsBooleanAndReturn(extension_id, kPrefEphemeralApp))
+    return true;
 
-  return extensions_info.Pass();
+  // Ephemerality was previously stored in the creation flags, so we must also
+  // check it for backcompatibility.
+  return (GetCreationFlags(extension_id) & Extension::IS_EPHEMERAL) != 0;
 }
 
-scoped_ptr<ExtensionInfo> ExtensionPrefs::GetEvictedEphemeralAppInfo(
-    const std::string& extension_id) const {
-  const base::DictionaryValue* extension_prefs = GetExtensionPref(extension_id);
-  if (!extension_prefs)
-    return scoped_ptr<ExtensionInfo>();
+void ExtensionPrefs::OnEphemeralAppPromoted(const std::string& extension_id) {
+  DCHECK(IsEphemeralApp(extension_id));
 
-  if (!IsEvictedEphemeralApp(extension_prefs))
-    return scoped_ptr<ExtensionInfo>();
-
-  return GetInstalledInfoHelper(extension_id, extension_prefs);
-}
+  UpdateExtensionPref(extension_id, kPrefEphemeralApp, NULL);
 
-void ExtensionPrefs::RemoveEvictedEphemeralApp(
-    const std::string& extension_id) {
-  bool evicted_ephemeral_app = false;
-  if (ReadPrefAsBoolean(extension_id,
-                        kPrefEvictedEphemeralApp,
-                        &evicted_ephemeral_app) && evicted_ephemeral_app) {
-    DeleteExtensionPrefs(extension_id);
+  // Ephemerality was previously stored in the creation flags, so ensure the bit
+  // is cleared.
+  int creation_flags = Extension::NO_FLAGS;
+  if (ReadPrefAsInteger(extension_id, kPrefCreationFlags, &creation_flags)) {
+    if (creation_flags & Extension::IS_EPHEMERAL) {
+      creation_flags &= ~static_cast<int>(Extension::IS_EPHEMERAL);
+      UpdateExtensionPref(extension_id,
+                          kPrefCreationFlags,
+                          new base::FundamentalValue(creation_flags));
+    }
   }
 }
 
@@ -1716,6 +1682,14 @@ base::Time ExtensionPrefs::GetInstallTime(
   return base::Time::FromInternalValue(install_time_i64);
 }
 
+bool ExtensionPrefs::DoNotSync(const std::string& extension_id) const {
+  bool do_not_sync;
+  if (!ReadPrefAsBoolean(extension_id, kPrefDoNotSync, &do_not_sync))
+    return false;
+
+  return do_not_sync;
+}
+
 base::Time ExtensionPrefs::GetLastLaunchTime(
     const std::string& extension_id) const {
   const base::DictionaryValue* extension = GetExtensionPref(extension_id);
@@ -1733,7 +1707,7 @@ base::Time ExtensionPrefs::GetLastLaunchTime(
 
 void ExtensionPrefs::SetLastLaunchTime(const std::string& extension_id,
                                        const base::Time& time) {
-  DCHECK(Extension::IdIsValid(extension_id));
+  DCHECK(crx_file::id_util::IdIsValid(extension_id));
   ScopedExtensionPrefUpdate update(prefs_, extension_id);
   SaveTime(update.Get(), kPrefLastLaunchTime, time);
 }
@@ -1775,11 +1749,11 @@ ExtensionIdList ExtensionPrefs::GetExtensionsFrom(
   return result;
 }
 
-void ExtensionPrefs::AddObserver(Observer* observer) {
+void ExtensionPrefs::AddObserver(ExtensionPrefsObserver* observer) {
   observer_list_.AddObserver(observer);
 }
 
-void ExtensionPrefs::RemoveObserver(Observer* observer) {
+void ExtensionPrefs::RemoveObserver(ExtensionPrefsObserver* observer) {
   observer_list_.RemoveObserver(observer);
 }
 
@@ -1826,7 +1800,7 @@ void ExtensionPrefs::InitPrefStore() {
   MigrateDisableReasons(extension_ids);
   app_sorting_->Initialize(extension_ids);
 
-  InitExtensionControlledPrefs(this, extension_pref_value_map_);
+  InitExtensionControlledPrefs(extension_pref_value_map_);
 
   extension_pref_value_map_->NotifyInitializationCompleted();
 }
@@ -1839,27 +1813,6 @@ bool ExtensionPrefs::HasIncognitoPrefValue(const std::string& pref_key) {
   return has_incognito_pref_value;
 }
 
-URLPatternSet ExtensionPrefs::GetAllowedInstallSites() {
-  URLPatternSet result;
-  const base::ListValue* list =
-      prefs_->GetList(pref_names::kAllowedInstallSites);
-  CHECK(list);
-
-  for (size_t i = 0; i < list->GetSize(); ++i) {
-    std::string entry_string;
-    URLPattern entry(URLPattern::SCHEME_ALL);
-    if (!list->GetString(i, &entry_string) ||
-        entry.Parse(entry_string) != URLPattern::PARSE_SUCCESS) {
-      LOG(ERROR) << "Invalid value for preference: "
-                 << pref_names::kAllowedInstallSites << "." << i;
-      continue;
-    }
-    result.AddPattern(entry);
-  }
-
-  return result;
-}
-
 const base::DictionaryValue* ExtensionPrefs::GetGeometryCache(
     const std::string& extension_id) const {
   const base::DictionaryValue* extension_prefs = GetExtensionPref(extension_id);
@@ -1897,10 +1850,8 @@ void ExtensionPrefs::SetInstallSignature(
 std::string ExtensionPrefs::GetInstallParam(
     const std::string& extension_id) const {
   const base::DictionaryValue* extension = GetExtensionPref(extension_id);
-  if (!extension) {
-    NOTREACHED();
+  if (!extension)  // Expected during unit testing.
     return std::string();
-  }
   std::string install_parameter;
   if (!extension->GetString(kPrefInstallParam, &install_parameter))
     return std::string();
@@ -1914,22 +1865,40 @@ void ExtensionPrefs::SetInstallParam(const std::string& extension_id,
                       new base::StringValue(install_parameter));
 }
 
+int ExtensionPrefs::GetCorruptedDisableCount() {
+  return prefs_->GetInteger(kCorruptedDisableCount);
+}
+
+void ExtensionPrefs::IncrementCorruptedDisableCount() {
+  int count = prefs_->GetInteger(kCorruptedDisableCount);
+  prefs_->SetInteger(kCorruptedDisableCount, count + 1);
+}
+
 ExtensionPrefs::ExtensionPrefs(
     PrefService* prefs,
     const base::FilePath& root_dir,
     ExtensionPrefValueMap* extension_pref_value_map,
     scoped_ptr<AppSorting> app_sorting,
     scoped_ptr<TimeProvider> time_provider,
-    bool extensions_disabled)
+    bool extensions_disabled,
+    const std::vector<ExtensionPrefsObserver*>& early_observers)
     : prefs_(prefs),
       install_directory_(root_dir),
       extension_pref_value_map_(extension_pref_value_map),
       app_sorting_(app_sorting.Pass()),
-      content_settings_store_(new ContentSettingsStore()),
       time_provider_(time_provider.Pass()),
       extensions_disabled_(extensions_disabled) {
   app_sorting_->SetExtensionScopedPrefs(this);
   MakePathsRelative();
+
+  // Ensure that any early observers are watching before prefs are initialized.
+  for (std::vector<ExtensionPrefsObserver*>::const_iterator iter =
+           early_observers.begin();
+       iter != early_observers.end();
+       ++iter) {
+    AddObserver(*iter);
+  }
+
   InitPrefStore();
 }
 
@@ -1983,14 +1952,6 @@ void ExtensionPrefs::RegisterProfilePrefs(
       pref_names::kLastChromeVersion,
       std::string(),  // default value
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-  registry->RegisterListPref(pref_names::kKnownDisabled,
-                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-#if defined(TOOLKIT_VIEWS)
-  registry->RegisterIntegerPref(
-      pref_names::kBrowserActionContainerWidth,
-      0,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-#endif
   registry->RegisterDictionaryPref(
       kInstallSignature,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
@@ -2003,6 +1964,16 @@ void ExtensionPrefs::RegisterProfilePrefs(
       pref_names::kNativeMessagingUserLevelHosts,
       true,  // default value
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+  registry->RegisterIntegerPref(
+      kCorruptedDisableCount,
+      0,  // default value
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+
+#if !defined(OS_MACOSX)
+  registry->RegisterBooleanPref(
+      pref_names::kAppFullscreenAllowed, true,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+#endif
 }
 
 template <class ExtensionIdContainer>
@@ -2047,15 +2018,10 @@ void ExtensionPrefs::PopulateExtensionInfoPrefs(
     const Extension* extension,
     const base::Time install_time,
     Extension::State initial_state,
-    bool blacklisted_for_malware,
+    int install_flags,
     const std::string& install_parameter,
     base::DictionaryValue* extension_dict) {
-  // Leave the state blank for component extensions so that old chrome versions
-  // loading new profiles do not fail in GetInstalledExtensionInfo. Older
-  // Chrome versions would only check for an omitted state.
-  if (initial_state != Extension::ENABLED_COMPONENT)
-    extension_dict->Set(kPrefState, new base::FundamentalValue(initial_state));
-
+  extension_dict->Set(kPrefState, new base::FundamentalValue(initial_state));
   extension_dict->Set(kPrefLocation,
                       new base::FundamentalValue(extension->location()));
   extension_dict->Set(kPrefCreationFlags,
@@ -2073,9 +2039,14 @@ void ExtensionPrefs::PopulateExtensionInfoPrefs(
   extension_dict->Set(kPrefInstallTime,
                       new base::StringValue(
                           base::Int64ToString(install_time.ToInternalValue())));
-  if (blacklisted_for_malware)
+  if (install_flags & kInstallFlagIsBlacklistedForMalware)
     extension_dict->Set(kPrefBlacklist, new base::FundamentalValue(true));
 
+  if (install_flags & kInstallFlagIsEphemeral)
+    extension_dict->Set(kPrefEphemeralApp, new base::FundamentalValue(true));
+  else
+    extension_dict->Remove(kPrefEphemeralApp, NULL);
+
   base::FilePath::StringType path = MakePathRelative(install_directory_,
                                                      extension->path());
   extension_dict->Set(kPrefPath, new base::StringValue(path));
@@ -2089,6 +2060,49 @@ void ExtensionPrefs::PopulateExtensionInfoPrefs(
     extension_dict->Set(kPrefManifest,
                         extension->manifest()->value()->DeepCopy());
   }
+
+  // Only writes kPrefDoNotSync when it is not the default.
+  if (install_flags & kInstallFlagDoNotSync)
+    extension_dict->Set(kPrefDoNotSync, new base::FundamentalValue(true));
+  else
+    extension_dict->Remove(kPrefDoNotSync, NULL);
+}
+
+void ExtensionPrefs::InitExtensionControlledPrefs(
+    ExtensionPrefValueMap* value_map) {
+  ExtensionIdList extension_ids;
+  GetExtensions(&extension_ids);
+
+  for (ExtensionIdList::iterator extension_id = extension_ids.begin();
+       extension_id != extension_ids.end();
+       ++extension_id) {
+    base::Time install_time = GetInstallTime(*extension_id);
+    bool is_enabled = !IsExtensionDisabled(*extension_id);
+    bool is_incognito_enabled = IsIncognitoEnabled(*extension_id);
+    value_map->RegisterExtension(
+        *extension_id, install_time, is_enabled, is_incognito_enabled);
+
+    FOR_EACH_OBSERVER(
+        ExtensionPrefsObserver,
+        observer_list_,
+        OnExtensionRegistered(*extension_id, install_time, is_enabled));
+
+    // Set regular extension controlled prefs.
+    LoadExtensionControlledPrefs(
+        this, value_map, *extension_id, kExtensionPrefsScopeRegular);
+    // Set incognito extension controlled prefs.
+    LoadExtensionControlledPrefs(this,
+                                 value_map,
+                                 *extension_id,
+                                 kExtensionPrefsScopeIncognitoPersistent);
+    // Set regular-only extension controlled prefs.
+    LoadExtensionControlledPrefs(
+        this, value_map, *extension_id, kExtensionPrefsScopeRegularOnly);
+
+    FOR_EACH_OBSERVER(ExtensionPrefsObserver,
+                      observer_list_,
+                      OnExtensionPrefsLoaded(*extension_id, this));
+  }
 }
 
 void ExtensionPrefs::FinishExtensionInfoPrefs(
@@ -2128,11 +2142,8 @@ void ExtensionPrefs::FinishExtensionInfoPrefs(
   // Clear state that may be registered from a previous install.
   extension_dict->Remove(EventRouter::kRegisteredEvents, NULL);
 
-  // When evicted ephemeral apps are re-installed, this flag must be reset.
-  extension_dict->Remove(kPrefEvictedEphemeralApp, NULL);
-
   // FYI, all code below here races on sudden shutdown because |extension_dict|,
-  // |app_sorting_|, |extension_pref_value_map_|, and |content_settings_store_|
+  // |app_sorting_|, |extension_pref_value_map_|, and (potentially) observers
   // are updated non-transactionally. This is probably not fixable without
   // nested transactional updates to pref dictionaries.
   if (needs_sort_ordinal)
@@ -2147,8 +2158,11 @@ void ExtensionPrefs::FinishExtensionInfoPrefs(
 
   extension_pref_value_map_->RegisterExtension(
       extension_id, install_time, is_enabled, is_incognito_enabled);
-  content_settings_store_->RegisterExtension(extension_id, install_time,
-                                             is_enabled);
+
+  FOR_EACH_OBSERVER(
+      ExtensionPrefsObserver,
+      observer_list_,
+      OnExtensionRegistered(extension_id, install_time, is_enabled));
 }
 
 }  // namespace extensions