Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / extension_prefs.cc
index 53d800c..e9b4a76 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 "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/pref_names.h"
 #include "extensions/common/feature_switch.h"
 #include "extensions/common/manifest.h"
@@ -77,6 +77,7 @@ 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";
 
 // Indicates whether the external extension was installed during the first
 // run of this profile.
@@ -190,6 +191,15 @@ const char kPrefInstallParam[] = "install_parameter";
 // A list of installed ids and a signature.
 const char kInstallSignature[] = "extensions.install_signature";
 
+// A preference that stores the next threshold for displaying a notification
+// when an extension or app consumes excessive disk space. This will not be
+// set until the extension/app reaches the initial threshold.
+const char kPrefNextStorageThreshold[] = "next_storage_threshold";
+
+// If this preference is set to true, notifications will be suppressed when an
+// extension or app consumes excessive disk space.
+const char kPrefDisableStorageNotifications[] = "disable_storage_notifications";
+
 // Provider of write access to a dictionary storing extension prefs.
 class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate {
  public:
@@ -258,53 +268,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
 
 //
@@ -389,12 +352,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 +370,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() {
@@ -510,7 +477,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);
@@ -779,6 +748,19 @@ void ExtensionPrefs::SetSettingsApiBubbleBeenAcknowledged(
                       value ? base::Value::CreateBooleanValue(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 ? base::Value::CreateBooleanValue(value) : NULL);
+}
+
 bool ExtensionPrefs::SetAlertSystemFirstRun() {
   if (prefs_->GetBoolean(pref_names::kAlertsInitialized)) {
     return true;
@@ -857,7 +839,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,28 +896,45 @@ 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();
 }
 
@@ -1257,7 +1256,9 @@ 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) {
@@ -1276,7 +1277,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,
@@ -1775,11 +1778,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 +1829,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();
 }
@@ -1912,22 +1915,69 @@ void ExtensionPrefs::SetInstallParam(const std::string& extension_id,
                       new base::StringValue(install_parameter));
 }
 
+int64 ExtensionPrefs::GetNextStorageThreshold(
+    const std::string& extension_id) const {
+  int64 next_threshold;
+  if (ReadInt64(GetExtensionPref(extension_id),
+                kPrefNextStorageThreshold,
+                &next_threshold)) {
+    return next_threshold;
+  }
+
+  return 0;
+}
+
+void ExtensionPrefs::SetNextStorageThreshold(const std::string& extension_id,
+                                             int64 next_threshold) {
+  ScopedExtensionPrefUpdate update(prefs_, extension_id);
+  SaveInt64(update.Get(), kPrefNextStorageThreshold, next_threshold);
+}
+
+bool ExtensionPrefs::IsStorageNotificationEnabled(
+    const std::string& extension_id) const {
+  bool disable_notifications;
+  if (ReadPrefAsBoolean(extension_id,
+                        kPrefDisableStorageNotifications,
+                        &disable_notifications)) {
+    return !disable_notifications;
+  }
+
+  return true;
+}
+
+void ExtensionPrefs::SetStorageNotificationEnabled(
+    const std::string& extension_id, bool enable_notifications) {
+  UpdateExtensionPref(
+      extension_id,
+      kPrefDisableStorageNotifications,
+      enable_notifications ? NULL : new base::FundamentalValue(true));
+}
+
 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();
 }
 
@@ -2089,6 +2139,43 @@ void ExtensionPrefs::PopulateExtensionInfoPrefs(
   }
 }
 
+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(
     const std::string& extension_id,
     const base::Time install_time,
@@ -2130,7 +2217,7 @@ void ExtensionPrefs::FinishExtensionInfoPrefs(
   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)
@@ -2145,8 +2232,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