#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"
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.
// 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:
}
}
-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
//
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()));
}
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() {
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);
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;
new base::FundamentalValue(new_value));
}
- FOR_EACH_OBSERVER(Observer,
+ FOR_EACH_OBSERVER(ExtensionPrefsObserver,
observer_list_,
OnExtensionDisableReasonsChanged(extension_id, new_value));
}
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();
}
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) {
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,
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);
}
MigrateDisableReasons(extension_ids);
app_sorting_->Initialize(extension_ids);
- InitExtensionControlledPrefs(this, extension_pref_value_map_);
+ InitExtensionControlledPrefs(extension_pref_value_map_);
extension_pref_value_map_->NotifyInitializationCompleted();
}
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();
}
}
}
+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,
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)
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