summaryrefslogtreecommitdiffstats
path: root/chrome/browser/prefs
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-06-28 21:49:31 +0100
committerKristian Monsen <kristianm@google.com>2011-07-08 17:55:00 +0100
commitddb351dbec246cf1fab5ec20d2d5520909041de1 (patch)
tree158e3fb57bdcac07c7f1e767fde3c70687c9fbb1 /chrome/browser/prefs
parent6b92e04f5f151c896e3088e86f70db7081009308 (diff)
downloadexternal_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.zip
external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.tar.gz
external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.tar.bz2
Merge Chromium at r12.0.742.93: Initial merge by git
Change-Id: Ic5ee2fec31358bbee305f7e915442377bfa6cda6
Diffstat (limited to 'chrome/browser/prefs')
-rw-r--r--chrome/browser/prefs/browser_prefs.cc27
-rw-r--r--chrome/browser/prefs/command_line_pref_store.cc4
-rw-r--r--chrome/browser/prefs/command_line_pref_store.h4
-rw-r--r--chrome/browser/prefs/command_line_pref_store_unittest.cc17
-rw-r--r--chrome/browser/prefs/default_pref_store.cc2
-rw-r--r--chrome/browser/prefs/overlay_persistent_pref_store.cc32
-rw-r--r--chrome/browser/prefs/overlay_persistent_pref_store.h13
-rw-r--r--chrome/browser/prefs/overlay_persistent_pref_store_unittest.cc26
-rw-r--r--chrome/browser/prefs/pref_member.cc62
-rw-r--r--chrome/browser/prefs/pref_member.h36
-rw-r--r--chrome/browser/prefs/pref_member_unittest.cc55
-rw-r--r--chrome/browser/prefs/pref_notifier_impl.cc6
-rw-r--r--chrome/browser/prefs/pref_observer_mock.h8
-rw-r--r--chrome/browser/prefs/pref_service.cc170
-rw-r--r--chrome/browser/prefs/pref_service.h77
-rw-r--r--chrome/browser/prefs/pref_service_mock_builder.cc3
-rw-r--r--chrome/browser/prefs/pref_service_mock_builder.h2
-rw-r--r--chrome/browser/prefs/pref_service_uitest.cc24
-rw-r--r--chrome/browser/prefs/pref_service_unittest.cc2
-rw-r--r--chrome/browser/prefs/pref_set_observer.cc4
-rw-r--r--chrome/browser/prefs/pref_set_observer.h6
-rw-r--r--chrome/browser/prefs/pref_value_map.cc19
-rw-r--r--chrome/browser/prefs/pref_value_map.h3
-rw-r--r--chrome/browser/prefs/pref_value_map_unittest.cc4
-rw-r--r--chrome/browser/prefs/pref_value_store.cc6
-rw-r--r--chrome/browser/prefs/pref_value_store.h13
-rw-r--r--chrome/browser/prefs/pref_value_store_unittest.cc4
-rw-r--r--chrome/browser/prefs/proxy_config_dictionary.h2
-rw-r--r--chrome/browser/prefs/proxy_config_dictionary_unittest.cc2
-rw-r--r--chrome/browser/prefs/scoped_user_pref_update.cc34
-rw-r--r--chrome/browser/prefs/scoped_user_pref_update.h91
-rw-r--r--chrome/browser/prefs/scoped_user_pref_update_unittest.cc79
-rw-r--r--chrome/browser/prefs/session_startup_pref.cc7
-rw-r--r--chrome/browser/prefs/testing_pref_store.cc13
-rw-r--r--chrome/browser/prefs/testing_pref_store.h10
-rw-r--r--chrome/browser/prefs/value_map_pref_store.cc4
-rw-r--r--chrome/browser/prefs/value_map_pref_store.h3
37 files changed, 619 insertions, 255 deletions
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index b48945b..ed5e0b5 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/extensions/apps_promo.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_web_ui.h"
#include "chrome/browser/extensions/extensions_ui.h"
@@ -33,11 +34,9 @@
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/page_info_model.h"
#include "chrome/browser/password_manager/password_manager.h"
-#include "chrome/browser/policy/browser_policy_connector.h"
-#include "chrome/browser/policy/profile_policy_connector.h"
+#include "chrome/browser/policy/cloud_policy_subsystem.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/profile_impl.h"
-#include "chrome/browser/renderer_host/browser_render_process_host.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/search_engines/template_url_model.h"
@@ -54,8 +53,10 @@
#include "chrome/browser/ui/webui/new_tab_ui.h"
#include "chrome/browser/ui/webui/plugins_ui.h"
#include "chrome/browser/upgrade_detector.h"
+#include "chrome/browser/web_resource/promo_resource_service.h"
#include "chrome/common/pref_names.h"
#include "content/browser/host_zoom_map.h"
+#include "content/browser/renderer_host/browser_render_process_host.h"
#if defined(TOOLKIT_VIEWS) // TODO(port): whittle this down as we port
#include "chrome/browser/ui/views/browser_actions_container.h"
@@ -68,7 +69,7 @@
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/audio_mixer_alsa.h"
-#include "chrome/browser/chromeos/login/apply_services_customization.h"
+#include "chrome/browser/chromeos/customization_document.h"
#include "chrome/browser/chromeos/login/signed_settings_temp_storage.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
@@ -81,6 +82,7 @@ namespace browser {
void RegisterLocalState(PrefService* local_state) {
// Prefs in Local State
+ AppsPromo::RegisterPrefs(local_state);
Browser::RegisterPrefs(local_state);
FlagsUI::RegisterPrefs(local_state);
WebCacheManager::RegisterPrefs(local_state);
@@ -90,6 +92,7 @@ void RegisterLocalState(PrefService* local_state) {
KeywordEditorController::RegisterPrefs(local_state);
MetricsLog::RegisterPrefs(local_state);
MetricsService::RegisterPrefs(local_state);
+ PromoResourceService::RegisterPrefs(local_state);
SafeBrowsingService::RegisterPrefs(local_state);
browser_shutdown::RegisterPrefs(local_state);
#if defined(TOOLKIT_VIEWS)
@@ -99,23 +102,25 @@ void RegisterLocalState(PrefService* local_state) {
TaskManager::RegisterPrefs(local_state);
geolocation::RegisterPrefs(local_state);
AutofillManager::RegisterBrowserPrefs(local_state);
+ BackgroundModeManager::RegisterPrefs(local_state);
BackgroundPageTracker::RegisterPrefs(local_state);
NotificationUIManager::RegisterPrefs(local_state);
PrefProxyConfigService::RegisterPrefs(local_state);
- policy::BrowserPolicyConnector::RegisterPrefs(local_state);
+ policy::CloudPolicySubsystem::RegisterPrefs(local_state);
#if defined(OS_CHROMEOS)
chromeos::AudioMixerAlsa::RegisterPrefs(local_state);
chromeos::UserManager::RegisterPrefs(local_state);
chromeos::UserCrosSettingsProvider::RegisterPrefs(local_state);
WizardController::RegisterPrefs(local_state);
chromeos::InputMethodMenu::RegisterPrefs(local_state);
- chromeos::ApplyServicesCustomization::RegisterPrefs(local_state);
+ chromeos::ServicesCustomizationDocument::RegisterPrefs(local_state);
chromeos::SignedSettingsTempStorage::RegisterPrefs(local_state);
#endif
}
void RegisterUserPrefs(PrefService* user_prefs) {
// User prefs
+ AppsPromo::RegisterUserPrefs(user_prefs);
AutofillManager::RegisterUserPrefs(user_prefs);
SessionStartupPref::RegisterUserPrefs(user_prefs);
Browser::RegisterUserPrefs(user_prefs);
@@ -130,6 +135,7 @@ void RegisterUserPrefs(PrefService* user_prefs) {
NewTabUI::RegisterUserPrefs(user_prefs);
PluginsUI::RegisterUserPrefs(user_prefs);
ProfileImpl::RegisterUserPrefs(user_prefs);
+ PromoResourceService::RegisterUserPrefs(user_prefs);
HostContentSettingsMap::RegisterUserPrefs(user_prefs);
HostZoomMap::RegisterUserPrefs(user_prefs);
DevToolsManager::RegisterUserPrefs(user_prefs);
@@ -152,7 +158,7 @@ void RegisterUserPrefs(PrefService* user_prefs) {
TemplateURLModel::RegisterUserPrefs(user_prefs);
InstantController::RegisterUserPrefs(user_prefs);
NetPrefObserver::RegisterPrefs(user_prefs);
- policy::ProfilePolicyConnector::RegisterPrefs(user_prefs);
+ policy::CloudPolicySubsystem::RegisterPrefs(user_prefs);
ProtocolHandlerRegistry::RegisterPrefs(user_prefs);
}
@@ -176,9 +182,10 @@ void MigrateBrowserPrefs(PrefService* user_prefs, PrefService* local_state) {
local_state->RegisterDictionaryPref(prefs::kBrowserWindowPlacement);
DCHECK(user_prefs->FindPreference(prefs::kBrowserWindowPlacement));
if (local_state->HasPrefPath(prefs::kBrowserWindowPlacement)) {
- user_prefs->Set(prefs::kBrowserWindowPlacement,
- *(local_state->FindPreference(prefs::kBrowserWindowPlacement)->
- GetValue()));
+ const PrefService::Preference* pref =
+ local_state->FindPreference(prefs::kBrowserWindowPlacement);
+ DCHECK(pref);
+ user_prefs->Set(prefs::kBrowserWindowPlacement, *(pref->GetValue()));
}
local_state->ClearPref(prefs::kBrowserWindowPlacement);
diff --git a/chrome/browser/prefs/command_line_pref_store.cc b/chrome/browser/prefs/command_line_pref_store.cc
index 97e0d39..2f4c316 100644
--- a/chrome/browser/prefs/command_line_pref_store.cc
+++ b/chrome/browser/prefs/command_line_pref_store.cc
@@ -4,7 +4,6 @@
#include "chrome/browser/prefs/command_line_pref_store.h"
-#include "app/app_switches.h"
#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
@@ -31,6 +30,9 @@ const CommandLinePrefStore::BooleanSwitchToPreferenceMapEntry
{ switches::kDisable3DAPIs, prefs::kDisable3DAPIs, true },
{ switches::kEnableCloudPrintProxy, prefs::kCloudPrintProxyEnabled,
true },
+ { switches::kAllowOutdatedPlugins, prefs::kPluginsAllowOutdated, true },
+ { switches::kNoPings, prefs::kEnableHyperlinkAuditing, false },
+ { switches::kNoReferrers, prefs::kEnableReferrers, false },
};
CommandLinePrefStore::CommandLinePrefStore(const CommandLine* command_line)
diff --git a/chrome/browser/prefs/command_line_pref_store.h b/chrome/browser/prefs/command_line_pref_store.h
index 75d8b10..6a654e7 100644
--- a/chrome/browser/prefs/command_line_pref_store.h
+++ b/chrome/browser/prefs/command_line_pref_store.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,7 +8,7 @@
#include "base/basictypes.h"
#include "base/command_line.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/prefs/value_map_pref_store.h"
diff --git a/chrome/browser/prefs/command_line_pref_store_unittest.cc b/chrome/browser/prefs/command_line_pref_store_unittest.cc
index edc88d9..aa4eeb6 100644
--- a/chrome/browser/prefs/command_line_pref_store_unittest.cc
+++ b/chrome/browser/prefs/command_line_pref_store_unittest.cc
@@ -4,9 +4,8 @@
#include <gtest/gtest.h>
-#include "app/app_switches.h"
#include "base/command_line.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/browser/prefs/command_line_pref_store.h"
@@ -27,10 +26,10 @@ class TestCommandLinePrefStore : public CommandLinePrefStore {
}
void VerifyProxyMode(ProxyPrefs::ProxyMode expected_mode) {
- Value* value = NULL;
+ const Value* value = NULL;
ASSERT_EQ(PrefStore::READ_OK, GetValue(prefs::kProxy, &value));
ASSERT_EQ(Value::TYPE_DICTIONARY, value->GetType());
- ProxyConfigDictionary dict(static_cast<DictionaryValue*>(value));
+ ProxyConfigDictionary dict(static_cast<const DictionaryValue*>(value));
ProxyPrefs::ProxyMode actual_mode;
ASSERT_TRUE(dict.GetMode(&actual_mode));
EXPECT_EQ(expected_mode, actual_mode);
@@ -48,7 +47,7 @@ TEST(CommandLinePrefStoreTest, SimpleStringPref) {
cl.AppendSwitchASCII(switches::kLang, "hi-MOM");
scoped_refptr<CommandLinePrefStore> store = new CommandLinePrefStore(&cl);
- Value* actual = NULL;
+ const Value* actual = NULL;
EXPECT_EQ(PrefStore::READ_OK,
store->GetValue(prefs::kApplicationLocale, &actual));
std::string result;
@@ -73,7 +72,7 @@ TEST(CommandLinePrefStoreTest, NoPrefs) {
cl.AppendSwitchASCII(unknown_bool, "a value");
scoped_refptr<CommandLinePrefStore> store = new CommandLinePrefStore(&cl);
- Value* actual = NULL;
+ const Value* actual = NULL;
EXPECT_EQ(PrefStore::READ_NO_VALUE, store->GetValue(unknown_bool, &actual));
EXPECT_EQ(PrefStore::READ_NO_VALUE, store->GetValue(unknown_string, &actual));
}
@@ -88,16 +87,16 @@ TEST(CommandLinePrefStoreTest, MultipleSwitches) {
scoped_refptr<TestCommandLinePrefStore> store =
new TestCommandLinePrefStore(&cl);
- Value* actual = NULL;
+ const Value* actual = NULL;
EXPECT_EQ(PrefStore::READ_NO_VALUE, store->GetValue(unknown_bool, &actual));
EXPECT_EQ(PrefStore::READ_NO_VALUE, store->GetValue(unknown_string, &actual));
store->VerifyProxyMode(ProxyPrefs::MODE_FIXED_SERVERS);
- Value* value = NULL;
+ const Value* value = NULL;
ASSERT_EQ(PrefStore::READ_OK, store->GetValue(prefs::kProxy, &value));
ASSERT_EQ(Value::TYPE_DICTIONARY, value->GetType());
- ProxyConfigDictionary dict(static_cast<DictionaryValue*>(value));
+ ProxyConfigDictionary dict(static_cast<const DictionaryValue*>(value));
std::string string_result = "";
diff --git a/chrome/browser/prefs/default_pref_store.cc b/chrome/browser/prefs/default_pref_store.cc
index cacc833..8e43438 100644
--- a/chrome/browser/prefs/default_pref_store.cc
+++ b/chrome/browser/prefs/default_pref_store.cc
@@ -14,7 +14,7 @@ void DefaultPrefStore::SetDefaultValue(const std::string& key, Value* value) {
}
Value::ValueType DefaultPrefStore::GetType(const std::string& key) const {
- Value* value;
+ const Value* value;
return GetValue(key, &value) == READ_OK ? value->GetType()
: Value::TYPE_NULL;
}
diff --git a/chrome/browser/prefs/overlay_persistent_pref_store.cc b/chrome/browser/prefs/overlay_persistent_pref_store.cc
index 42fe389..e75fbc6 100644
--- a/chrome/browser/prefs/overlay_persistent_pref_store.cc
+++ b/chrome/browser/prefs/overlay_persistent_pref_store.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/prefs/overlay_persistent_pref_store.h"
+#include "base/values.h"
+
OverlayPersistentPrefStore::OverlayPersistentPrefStore(
PersistentPrefStore* underlay)
: underlay_(underlay) {
@@ -13,6 +15,10 @@ OverlayPersistentPrefStore::~OverlayPersistentPrefStore() {
underlay_->RemoveObserver(this);
}
+bool OverlayPersistentPrefStore::IsSetInOverlay(const std::string& key) const {
+ return overlay_.GetValue(key, NULL);
+}
+
void OverlayPersistentPrefStore::AddObserver(PrefStore::Observer* observer) {
observers_.AddObserver(observer);
}
@@ -26,12 +32,32 @@ bool OverlayPersistentPrefStore::IsInitializationComplete() const {
}
PrefStore::ReadResult OverlayPersistentPrefStore::GetValue(
- const std::string& key, Value** result) const {
+ const std::string& key,
+ const Value** result) const {
if (overlay_.GetValue(key, result))
return READ_OK;
return underlay_->GetValue(key, result);
}
+PrefStore::ReadResult OverlayPersistentPrefStore::GetMutableValue(
+ const std::string& key,
+ Value** result) {
+ if (overlay_.GetValue(key, result))
+ return READ_OK;
+
+ // Try to create copy of underlay if the overlay does not contain a value.
+ Value* underlay_value = NULL;
+ PrefStore::ReadResult read_result =
+ underlay_->GetMutableValue(key, &underlay_value);
+ if (read_result == READ_OK) {
+ *result = underlay_value->DeepCopy();
+ overlay_.SetValue(key, *result);
+ return READ_OK;
+ }
+ // Return read failure if underlay stores no value for |key|.
+ return read_result;
+}
+
void OverlayPersistentPrefStore::SetValue(const std::string& key,
Value* value) {
if (overlay_.SetValue(key, value))
@@ -66,6 +92,10 @@ void OverlayPersistentPrefStore::ScheduleWritePrefs() {
// We do not write intentionally.
}
+void OverlayPersistentPrefStore::CommitPendingWrite() {
+ // We do not write intentionally.
+}
+
void OverlayPersistentPrefStore::ReportValueChanged(const std::string& key) {
FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
}
diff --git a/chrome/browser/prefs/overlay_persistent_pref_store.h b/chrome/browser/prefs/overlay_persistent_pref_store.h
index 1b926ad..bbb85c3 100644
--- a/chrome/browser/prefs/overlay_persistent_pref_store.h
+++ b/chrome/browser/prefs/overlay_persistent_pref_store.h
@@ -9,8 +9,8 @@
#include <string>
#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
-#include "base/ref_counted.h"
#include "chrome/browser/prefs/pref_value_map.h"
#include "chrome/common/persistent_pref_store.h"
@@ -24,13 +24,20 @@ class OverlayPersistentPrefStore : public PersistentPrefStore,
explicit OverlayPersistentPrefStore(PersistentPrefStore* underlay);
virtual ~OverlayPersistentPrefStore();
+ // Returns true if a value has been set for the |key| in this
+ // OverlayPersistentPrefStore, i.e. if it potentially overrides a value
+ // from the |underlay_|.
+ virtual bool IsSetInOverlay(const std::string& key) const;
+
// Methods of PrefStore.
virtual void AddObserver(PrefStore::Observer* observer);
virtual void RemoveObserver(PrefStore::Observer* observer);
virtual bool IsInitializationComplete() const;
- virtual ReadResult GetValue(const std::string& key, Value** result) const;
+ virtual ReadResult GetValue(const std::string& key,
+ const Value** result) const;
// Methods of PersistentPrefStore.
+ virtual ReadResult GetMutableValue(const std::string& key, Value** result);
virtual void SetValue(const std::string& key, Value* value);
virtual void SetValueSilently(const std::string& key, Value* value);
virtual void RemoveValue(const std::string& key);
@@ -38,7 +45,7 @@ class OverlayPersistentPrefStore : public PersistentPrefStore,
virtual PrefReadError ReadPrefs();
virtual bool WritePrefs();
virtual void ScheduleWritePrefs();
- // TODO(battre) remove this function
+ virtual void CommitPendingWrite();
virtual void ReportValueChanged(const std::string& key);
private:
diff --git a/chrome/browser/prefs/overlay_persistent_pref_store_unittest.cc b/chrome/browser/prefs/overlay_persistent_pref_store_unittest.cc
index 7e2e0a2..11dcc05 100644
--- a/chrome/browser/prefs/overlay_persistent_pref_store_unittest.cc
+++ b/chrome/browser/prefs/overlay_persistent_pref_store_unittest.cc
@@ -74,7 +74,7 @@ TEST_F(OverlayPersistentPrefStoreTest, Observer) {
}
TEST_F(OverlayPersistentPrefStoreTest, GetAndSet) {
- Value* value = NULL;
+ const Value* value = NULL;
int i = -1;
EXPECT_EQ(PrefStore::READ_NO_VALUE, overlay_->GetValue(key, &value));
EXPECT_EQ(PrefStore::READ_NO_VALUE, underlay_->GetValue(key, &value));
@@ -117,3 +117,27 @@ TEST_F(OverlayPersistentPrefStoreTest, GetAndSet) {
EXPECT_TRUE(value->GetAsInteger(&i));
EXPECT_EQ(42, i);
}
+
+// Check that GetMutableValue does not return the dictionary of the underlay.
+TEST_F(OverlayPersistentPrefStoreTest, ModifyDictionaries) {
+ underlay_->SetValue(key, new DictionaryValue);
+
+ Value* modify = NULL;
+ EXPECT_EQ(PrefStore::READ_OK, overlay_->GetMutableValue(key, &modify));
+ ASSERT_TRUE(modify);
+ ASSERT_TRUE(modify->GetType() == Value::TYPE_DICTIONARY);
+ static_cast<DictionaryValue*>(modify)->SetInteger(key, 42);
+
+ Value* original_in_underlay = NULL;
+ EXPECT_EQ(PrefStore::READ_OK,
+ underlay_->GetMutableValue(key, &original_in_underlay));
+ ASSERT_TRUE(original_in_underlay);
+ ASSERT_TRUE(original_in_underlay->GetType() == Value::TYPE_DICTIONARY);
+ EXPECT_TRUE(static_cast<DictionaryValue*>(original_in_underlay)->empty());
+
+ Value* modified = NULL;
+ EXPECT_EQ(PrefStore::READ_OK, overlay_->GetMutableValue(key, &modified));
+ ASSERT_TRUE(modified);
+ ASSERT_TRUE(modified->GetType() == Value::TYPE_DICTIONARY);
+ EXPECT_TRUE(Value::Equals(modify, static_cast<DictionaryValue*>(modified)));
+}
diff --git a/chrome/browser/prefs/pref_member.cc b/chrome/browser/prefs/pref_member.cc
index db17123..90b369b 100644
--- a/chrome/browser/prefs/pref_member.cc
+++ b/chrome/browser/prefs/pref_member.cc
@@ -1,14 +1,13 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/prefs/pref_member.h"
#include "base/logging.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h"
+#include "base/value_conversions.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/common/notification_type.h"
+#include "content/common/notification_type.h"
namespace subtle {
@@ -19,8 +18,7 @@ PrefMemberBase::PrefMemberBase()
}
PrefMemberBase::~PrefMemberBase() {
- if (prefs_ && !pref_name_.empty())
- prefs_->RemovePrefObserver(pref_name_.c_str(), this);
+ Destroy();
}
@@ -39,19 +37,12 @@ void PrefMemberBase::Init(const char* pref_name, PrefService* prefs,
}
void PrefMemberBase::Destroy() {
- if (prefs_) {
+ if (prefs_ && !pref_name_.empty()) {
prefs_->RemovePrefObserver(pref_name_.c_str(), this);
prefs_ = NULL;
}
}
-bool PrefMemberBase::IsManaged() const {
- VerifyValuePrefName();
- const PrefService::Preference* pref =
- prefs_->FindPreference(pref_name_.c_str());
- return pref && pref->IsManaged();
-}
-
void PrefMemberBase::MoveToThread(BrowserThread::ID thread_id) {
VerifyValuePrefName();
// Load the value from preferences if it hasn't been loaded so far.
@@ -70,10 +61,6 @@ void PrefMemberBase::Observe(NotificationType type,
observer_->Observe(type, source, details);
}
-void PrefMemberBase::VerifyValuePrefName() const {
- DCHECK(!pref_name_.empty());
-}
-
void PrefMemberBase::UpdateValueFromPref() const {
VerifyValuePrefName();
const PrefService::Preference* pref =
@@ -81,7 +68,13 @@ void PrefMemberBase::UpdateValueFromPref() const {
DCHECK(pref);
if (!internal())
CreateInternal();
- internal()->UpdateValue(pref->GetValue()->DeepCopy());
+ internal()->UpdateValue(pref->GetValue()->DeepCopy(), pref->IsManaged());
+}
+
+void PrefMemberBase::VerifyPref() const {
+ VerifyValuePrefName();
+ if (!internal())
+ UpdateValueFromPref();
}
PrefMemberBase::Internal::Internal() : thread_id_(BrowserThread::UI) { }
@@ -94,17 +87,18 @@ bool PrefMemberBase::Internal::IsOnCorrectThread() const {
!BrowserThread::IsMessageLoopValid(BrowserThread::UI)));
}
-void PrefMemberBase::Internal::UpdateValue(Value* v) const {
+void PrefMemberBase::Internal::UpdateValue(Value* v, bool is_managed) const {
scoped_ptr<Value> value(v);
if (IsOnCorrectThread()) {
bool rv = UpdateValueInternal(*value);
DCHECK(rv);
+ is_managed_ = is_managed;
} else {
bool rv = BrowserThread::PostTask(
thread_id_, FROM_HERE,
NewRunnableMethod(this,
&PrefMemberBase::Internal::UpdateValue,
- value.release()));
+ value.release(), is_managed));
DCHECK(rv);
}
}
@@ -166,6 +160,30 @@ void PrefMember<FilePath>::UpdatePref(const FilePath& value) {
template <>
bool PrefMember<FilePath>::Internal::UpdateValueInternal(const Value& value)
const {
- return value.GetAsFilePath(&value_);
+ return base::GetValueAsFilePath(value, &value_);
+}
+
+template <>
+void PrefMember<ListValue*>::UpdatePref(ListValue*const& value) {
+ // prefs takes ownership of the value passed, so make a copy.
+ prefs()->SetList(pref_name().c_str(), value->DeepCopy());
+}
+
+template <>
+bool PrefMember<ListValue*>::Internal::UpdateValueInternal(const Value& value)
+ const {
+ // Verify the type before doing the DeepCopy to avoid leaking the copy.
+ if (value.GetType() != Value::TYPE_LIST)
+ return false;
+
+ // ListPrefMember keeps a copy of the ListValue and of its contents.
+ // GetAsList() assigns its |this| (the DeepCopy) to |value_|.
+ delete value_;
+ return value.DeepCopy()->GetAsList(&value_);
+}
+
+template <>
+PrefMember<ListValue*>::Internal::~Internal() {
+ delete value_;
}
diff --git a/chrome/browser/prefs/pref_member.h b/chrome/browser/prefs/pref_member.h
index c82e810..5fdd91d 100644
--- a/chrome/browser/prefs/pref_member.h
+++ b/chrome/browser/prefs/pref_member.h
@@ -29,10 +29,10 @@
#include "base/basictypes.h"
#include "base/file_path.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/values.h"
-#include "chrome/common/notification_observer.h"
#include "content/browser/browser_thread.h"
+#include "content/common/notification_observer.h"
class PrefService;
@@ -47,10 +47,15 @@ class PrefMemberBase : public NotificationObserver {
// Update the value, either by calling |UpdateValueInternal| directly
// or by dispatching to the right thread.
// Takes ownership of |value|.
- virtual void UpdateValue(Value* value) const;
+ virtual void UpdateValue(Value* value, bool is_managed) const;
void MoveToThread(BrowserThread::ID thread_id);
+ // See PrefMember<> for description.
+ bool IsManaged() const {
+ return is_managed_;
+ }
+
protected:
friend class base::RefCountedThreadSafe<Internal>;
virtual ~Internal();
@@ -67,6 +72,7 @@ class PrefMemberBase : public NotificationObserver {
bool IsOnCorrectThread() const;
BrowserThread::ID thread_id_;
+ mutable bool is_managed_;
DISALLOW_COPY_AND_ASSIGN(Internal);
};
@@ -83,9 +89,6 @@ class PrefMemberBase : public NotificationObserver {
// See PrefMember<> for description.
void Destroy();
- // See PrefMember<> for description.
- bool IsManaged() const;
-
void MoveToThread(BrowserThread::ID thread_id);
// NotificationObserver
@@ -93,13 +96,19 @@ class PrefMemberBase : public NotificationObserver {
const NotificationSource& source,
const NotificationDetails& details);
- void VerifyValuePrefName() const;
+ void VerifyValuePrefName() const {
+ DCHECK(!pref_name_.empty());
+ }
// This method is used to do the actual sync with the preference.
// Note: it is logically const, because it doesn't modify the state
// seen by the outside world. It is just doing a lazy load behind the scenes.
virtual void UpdateValueFromPref() const;
+ // Verifies the preference name, and lazily loads the preference value if
+ // it hasn't been loaded yet.
+ void VerifyPref() const;
+
const std::string& pref_name() const { return pref_name_; }
PrefService* prefs() { return prefs_; }
const PrefService* prefs() const { return prefs_; }
@@ -153,20 +162,18 @@ class PrefMember : public subtle::PrefMemberBase {
// Check whether the pref is managed, i.e. controlled externally through
// enterprise configuration management (e.g. windows group policy). Returns
// false for unknown prefs.
- // This method should only be called on the UI thread.
+ // This method should only be used from the thread the PrefMember is currently
+ // on, which is the UI thread unless changed by |MoveToThread|.
bool IsManaged() const {
- return subtle::PrefMemberBase::IsManaged();
+ VerifyPref();
+ return internal_->IsManaged();
}
// Retrieve the value of the member variable.
// This method should only be used from the thread the PrefMember is currently
// on, which is the UI thread unless changed by |MoveToThread|.
ValueType GetValue() const {
- VerifyValuePrefName();
- // We lazily fetch the value from the pref service the first time GetValue
- // is called.
- if (!internal_.get())
- UpdateValueFromPref();
+ VerifyPref();
return internal_->value();
}
@@ -237,5 +244,6 @@ typedef PrefMember<int> IntegerPrefMember;
typedef PrefMember<double> DoublePrefMember;
typedef PrefMember<std::string> StringPrefMember;
typedef PrefMember<FilePath> FilePathPrefMember;
+typedef PrefMember<ListValue*> ListPrefMember;
#endif // CHROME_BROWSER_PREFS_PREF_MEMBER_H_
diff --git a/chrome/browser/prefs/pref_member_unittest.cc b/chrome/browser/prefs/pref_member_unittest.cc
index b47a881..b8079dd 100644
--- a/chrome/browser/prefs/pref_member_unittest.cc
+++ b/chrome/browser/prefs/pref_member_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,11 +6,11 @@
#include "base/message_loop.h"
#include "chrome/browser/prefs/pref_value_store.h"
-#include "chrome/common/notification_details.h"
-#include "chrome/common/notification_source.h"
-#include "chrome/common/notification_type.h"
#include "chrome/test/testing_pref_service.h"
#include "content/browser/browser_thread.h"
+#include "content/common/notification_details.h"
+#include "content/common/notification_source.h"
+#include "content/common/notification_type.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -19,12 +19,14 @@ const char kBoolPref[] = "bool";
const char kIntPref[] = "int";
const char kDoublePref[] = "double";
const char kStringPref[] = "string";
+const char kListPref[] = "list";
void RegisterTestPrefs(PrefService* prefs) {
prefs->RegisterBooleanPref(kBoolPref, false);
prefs->RegisterIntegerPref(kIntPref, 0);
prefs->RegisterDoublePref(kDoublePref, 0.0);
prefs->RegisterStringPref(kStringPref, "default");
+ prefs->RegisterListPref(kListPref);
}
class GetPrefValueCallback
@@ -179,6 +181,42 @@ TEST(PrefMemberTest, BasicGetAndSet) {
EXPECT_EQ("bar", prefs.GetString(kStringPref));
EXPECT_EQ("bar", string.GetValue());
EXPECT_EQ("bar", *string);
+
+ // Test list
+ ListPrefMember list;
+ list.Init(kListPref, &prefs, NULL);
+
+ // Check the defaults
+ const ListValue* list_value = prefs.GetList(kListPref);
+ ASSERT_TRUE(list_value != NULL);
+ EXPECT_EQ(0u, list_value->GetSize());
+ EXPECT_TRUE(list_value->empty());
+ ASSERT_TRUE(list.GetValue() != NULL);
+ EXPECT_EQ(0u, list.GetValue()->GetSize());
+ EXPECT_TRUE(list.GetValue()->empty());
+ ASSERT_TRUE(*list != NULL);
+ EXPECT_EQ(0u, (*list)->GetSize());
+ EXPECT_TRUE((*list)->empty());
+
+ // Try changing through the member variable.
+ scoped_ptr<ListValue> list_value_numbers(new ListValue());
+ list_value_numbers->Append(new StringValue("one"));
+ list_value_numbers->Append(new StringValue("two"));
+ list_value_numbers->Append(new StringValue("three"));
+ list.SetValue(list_value_numbers.get());
+ EXPECT_TRUE(list_value_numbers->Equals(list.GetValue()));
+ EXPECT_TRUE(list_value_numbers->Equals(prefs.GetList(kListPref)));
+ EXPECT_TRUE(list_value_numbers->Equals(*list));
+
+ // Try changing back through the pref.
+ ListValue* list_value_ints = new ListValue();
+ list_value_ints->Append(new FundamentalValue(1));
+ list_value_ints->Append(new FundamentalValue(2));
+ list_value_ints->Append(new FundamentalValue(3));
+ prefs.SetList(kListPref, list_value_ints); // takes ownership
+ EXPECT_TRUE(list_value_ints->Equals(list.GetValue()));
+ EXPECT_TRUE(list_value_ints->Equals(prefs.GetList(kListPref)));
+ EXPECT_TRUE(list_value_ints->Equals(*list));
}
TEST(PrefMemberTest, TwoPrefs) {
@@ -234,16 +272,15 @@ TEST(PrefMemberTest, NoInit) {
IntegerPrefMember pref;
}
-// Flakily triggers an assertion, http://crbug.com/74386.
-TEST(PrefMemberTest, DISABLED_MoveToThread) {
+TEST(PrefMemberTest, MoveToThread) {
+ TestingPrefService prefs;
+ scoped_refptr<GetPrefValueCallback> callback =
+ make_scoped_refptr(new GetPrefValueCallback());
MessageLoop message_loop;
BrowserThread ui_thread(BrowserThread::UI, &message_loop);
BrowserThread io_thread(BrowserThread::IO);
ASSERT_TRUE(io_thread.Start());
- TestingPrefService prefs;
RegisterTestPrefs(&prefs);
- scoped_refptr<GetPrefValueCallback> callback =
- make_scoped_refptr(new GetPrefValueCallback());
callback->Init(kBoolPref, &prefs);
ASSERT_TRUE(callback->FetchValue());
diff --git a/chrome/browser/prefs/pref_notifier_impl.cc b/chrome/browser/prefs/pref_notifier_impl.cc
index d15f425..d5ad24c 100644
--- a/chrome/browser/prefs/pref_notifier_impl.cc
+++ b/chrome/browser/prefs/pref_notifier_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,8 +6,8 @@
#include "base/stl_util-inl.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_service.h"
+#include "content/common/notification_observer.h"
+#include "content/common/notification_service.h"
PrefNotifierImpl::PrefNotifierImpl(PrefService* service)
: pref_service_(service) {
diff --git a/chrome/browser/prefs/pref_observer_mock.h b/chrome/browser/prefs/pref_observer_mock.h
index 0c651ca..eac1c13 100644
--- a/chrome/browser/prefs/pref_observer_mock.h
+++ b/chrome/browser/prefs/pref_observer_mock.h
@@ -9,10 +9,10 @@
#include <string>
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/common/notification_details.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_source.h"
-#include "chrome/common/notification_type.h"
+#include "content/common/notification_details.h"
+#include "content/common/notification_observer.h"
+#include "content/common/notification_source.h"
+#include "content/common/notification_type.h"
#include "testing/gmock/include/gmock/gmock.h"
using testing::Pointee;
diff --git a/chrome/browser/prefs/pref_service.cc b/chrome/browser/prefs/pref_service.cc
index ac2b5ec..aa71108 100644
--- a/chrome/browser/prefs/pref_service.cc
+++ b/chrome/browser/prefs/pref_service.cc
@@ -16,8 +16,7 @@
#include "base/stl_util-inl.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h"
+#include "base/value_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_pref_store.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
@@ -26,9 +25,10 @@
#include "chrome/browser/prefs/overlay_persistent_pref_store.h"
#include "chrome/browser/prefs/pref_notifier_impl.h"
#include "chrome/browser/prefs/pref_value_store.h"
+#include "chrome/browser/ui/profile_error_dialog.h"
#include "chrome/common/json_pref_store.h"
-#include "chrome/common/notification_service.h"
#include "content/browser/browser_thread.h"
+#include "content/common/notification_service.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -78,9 +78,7 @@ Value* CreateLocaleDefaultValue(Value::ValueType type, int message_id) {
// Forwards a notification after a PostMessage so that we can wait for the
// MessageLoop to run.
void NotifyReadError(PrefService* pref, int message_id) {
- Source<PrefService> source(pref);
- NotificationService::current()->Notify(NotificationType::PROFILE_ERROR,
- source, Details<int>(&message_id));
+ ShowProfileErrorDialog(message_id);
}
} // namespace
@@ -89,6 +87,15 @@ void NotifyReadError(PrefService* pref, int message_id) {
PrefService* PrefService::CreatePrefService(const FilePath& pref_filename,
PrefStore* extension_prefs,
Profile* profile) {
+ return CreatePrefServiceAsync(pref_filename, extension_prefs, profile, NULL);
+}
+
+// static
+PrefService* PrefService::CreatePrefServiceAsync(
+ const FilePath& pref_filename,
+ PrefStore* extension_prefs,
+ Profile* profile,
+ PrefService::Delegate* delegate) {
using policy::ConfigurationPolicyPrefStore;
#if defined(OS_LINUX)
@@ -122,7 +129,7 @@ PrefService* PrefService::CreatePrefService(const FilePath& pref_filename,
return new PrefService(managed_platform, managed_cloud, extension_prefs,
command_line, user, recommended_platform,
- recommended_cloud, default_pref_store);
+ recommended_cloud, default_pref_store, delegate);
}
PrefService* PrefService::CreateIncognitoPrefService(
@@ -137,9 +144,11 @@ PrefService::PrefService(PrefStore* managed_platform_prefs,
PersistentPrefStore* user_prefs,
PrefStore* recommended_platform_prefs,
PrefStore* recommended_cloud_prefs,
- DefaultPrefStore* default_store)
+ DefaultPrefStore* default_store,
+ PrefService::Delegate* delegate)
: user_pref_store_(user_prefs),
- default_store_(default_store) {
+ default_store_(default_store),
+ delegate_(delegate) {
pref_notifier_.reset(new PrefNotifierImpl(this));
pref_value_store_.reset(
new PrefValueStore(managed_platform_prefs,
@@ -158,7 +167,8 @@ PrefService::PrefService(const PrefService& original,
PrefStore* incognito_extension_prefs)
: user_pref_store_(
new OverlayPersistentPrefStore(original.user_pref_store_.get())),
- default_store_(original.default_store_.get()){
+ default_store_(original.default_store_.get()),
+ delegate_(NULL) {
pref_notifier_.reset(new PrefNotifierImpl(this));
pref_value_store_.reset(original.pref_value_store_->CloneAndSpecialize(
NULL, // managed_platform_prefs
@@ -184,27 +194,48 @@ PrefService::~PrefService() {
default_store_ = NULL;
}
-void PrefService::InitFromStorage() {
- const PersistentPrefStore::PrefReadError error =
- user_pref_store_->ReadPrefs();
- if (error == PersistentPrefStore::PREF_READ_ERROR_NONE)
+void PrefService::OnPrefsRead(PersistentPrefStore::PrefReadError error,
+ bool no_dir) {
+ if (no_dir) {
+ // Bad news. When profile is created, the process that creates the directory
+ // is explicitly started. So if directory is missing it probably means that
+ // Chromium hasn't sufficient privileges.
+ CHECK(delegate_);
+ delegate_->OnPrefsLoaded(this, false);
return;
+ }
- // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
- // an example problem that this can cause.
- // Do some diagnosis and try to avoid losing data.
- int message_id = 0;
- if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
- message_id = IDS_PREFERENCES_CORRUPT_ERROR;
- } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
- message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
+ if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
+ // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
+ // an example problem that this can cause.
+ // Do some diagnosis and try to avoid losing data.
+ int message_id = 0;
+ if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
+ message_id = IDS_PREFERENCES_CORRUPT_ERROR;
+ } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
+ message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
+ }
+
+ if (message_id) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableFunction(&NotifyReadError, this, message_id));
+ }
+ UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20);
}
- if (message_id) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- NewRunnableFunction(&NotifyReadError, this, message_id));
+ if (delegate_)
+ delegate_->OnPrefsLoaded(this, true);
+}
+
+void PrefService::InitFromStorage() {
+ if (!delegate_) {
+ const PersistentPrefStore::PrefReadError error =
+ user_pref_store_->ReadPrefs();
+ OnPrefsRead(error, false);
+ } else {
+ // todo(altimofeev): move this method to PersistentPrefStore interface.
+ (static_cast<JsonPrefStore*>(user_pref_store_.get()))->ReadPrefs(this);
}
- UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20);
}
bool PrefService::ReloadPersistentPrefs() {
@@ -214,16 +245,19 @@ bool PrefService::ReloadPersistentPrefs() {
bool PrefService::SavePersistentPrefs() {
DCHECK(CalledOnValidThread());
-
return user_pref_store_->WritePrefs();
}
void PrefService::ScheduleSavePersistentPrefs() {
DCHECK(CalledOnValidThread());
-
user_pref_store_->ScheduleWritePrefs();
}
+void PrefService::CommitPendingWrite() {
+ DCHECK(CalledOnValidThread());
+ user_pref_store_->CommitPendingWrite();
+}
+
void PrefService::RegisterBooleanPref(const char* path,
bool default_value) {
RegisterPreference(path, Value::CreateBooleanValue(default_value));
@@ -362,7 +396,7 @@ FilePath PrefService::GetFilePath(const char* path) const {
NOTREACHED() << "Trying to read an unregistered pref: " << path;
return FilePath(result);
}
- bool rv = pref->GetValue()->GetAsFilePath(&result);
+ bool rv = base::GetValueAsFilePath(*pref->GetValue(), &result);
DCHECK(rv);
return result;
}
@@ -377,7 +411,10 @@ DictionaryValue* PrefService::GetPreferenceValues() const {
DictionaryValue* out = new DictionaryValue;
DefaultPrefStore::const_iterator i = default_store_->begin();
for (; i != default_store_->end(); ++i) {
- const Value* value = FindPreference(i->first.c_str())->GetValue();
+ const Preference* pref = FindPreference(i->first.c_str());
+ DCHECK(pref);
+ const Value* value = pref->GetValue();
+ DCHECK(value);
out->Set(i->first, value->DeepCopy());
}
return out;
@@ -402,10 +439,6 @@ bool PrefService::ReadOnly() const {
return user_pref_store_->ReadOnly();
}
-PrefNotifier* PrefService::pref_notifier() const {
- return pref_notifier_.get();
-}
-
bool PrefService::IsManagedPreference(const char* pref_name) const {
const Preference* pref = FindPreference(pref_name);
return pref && pref->IsManaged();
@@ -518,7 +551,11 @@ void PrefService::SetString(const char* path, const std::string& value) {
}
void PrefService::SetFilePath(const char* path, const FilePath& value) {
- SetUserPrefValue(path, Value::CreateFilePathValue(value));
+ SetUserPrefValue(path, base::CreateFilePathValue(value));
+}
+
+void PrefService::SetList(const char* path, ListValue* value) {
+ SetUserPrefValue(path, value);
}
void PrefService::SetInt64(const char* path, int64 value) {
@@ -547,7 +584,9 @@ void PrefService::RegisterInt64Pref(const char* path, int64 default_value) {
path, Value::CreateStringValue(base::Int64ToString(default_value)));
}
-DictionaryValue* PrefService::GetMutableDictionary(const char* path) {
+Value* PrefService::GetMutableUserPref(const char* path,
+ Value::ValueType type) {
+ CHECK(type == Value::TYPE_DICTIONARY || type == Value::TYPE_LIST);
DCHECK(CalledOnValidThread());
DLOG_IF(WARNING, IsManagedPreference(path)) <<
"Attempt to change managed preference " << path;
@@ -557,57 +596,30 @@ DictionaryValue* PrefService::GetMutableDictionary(const char* path) {
NOTREACHED() << "Trying to get an unregistered pref: " << path;
return NULL;
}
- if (pref->GetType() != Value::TYPE_DICTIONARY) {
- NOTREACHED() << "Wrong type for GetMutableDictionary: " << path;
+ if (pref->GetType() != type) {
+ NOTREACHED() << "Wrong type for GetMutableValue: " << path;
return NULL;
}
- DictionaryValue* dict = NULL;
- Value* tmp_value = NULL;
// Look for an existing preference in the user store. If it doesn't
// exist or isn't the correct type, create a new user preference.
- if (user_pref_store_->GetValue(path, &tmp_value)
+ Value* value = NULL;
+ if (user_pref_store_->GetMutableValue(path, &value)
!= PersistentPrefStore::READ_OK ||
- !tmp_value->IsType(Value::TYPE_DICTIONARY)) {
- dict = new DictionaryValue;
- user_pref_store_->SetValueSilently(path, dict);
- } else {
- dict = static_cast<DictionaryValue*>(tmp_value);
- }
- return dict;
-}
-
-ListValue* PrefService::GetMutableList(const char* path) {
- DCHECK(CalledOnValidThread());
- DLOG_IF(WARNING, IsManagedPreference(path)) <<
- "Attempt to change managed preference " << path;
-
- const Preference* pref = FindPreference(path);
- if (!pref) {
- NOTREACHED() << "Trying to get an unregistered pref: " << path;
- return NULL;
- }
- if (pref->GetType() != Value::TYPE_LIST) {
- NOTREACHED() << "Wrong type for GetMutableList: " << path;
- return NULL;
- }
-
- ListValue* list = NULL;
- Value* tmp_value = NULL;
- // Look for an existing preference in the user store. If it doesn't
- // exist or isn't the correct type, create a new user preference.
- if (user_pref_store_->GetValue(path, &tmp_value)
- != PersistentPrefStore::READ_OK ||
- !tmp_value->IsType(Value::TYPE_LIST)) {
- list = new ListValue;
- user_pref_store_->SetValueSilently(path, list);
- } else {
- list = static_cast<ListValue*>(tmp_value);
+ !value->IsType(type)) {
+ if (type == Value::TYPE_DICTIONARY) {
+ value = new DictionaryValue;
+ } else if (type == Value::TYPE_LIST) {
+ value = new ListValue;
+ } else {
+ NOTREACHED();
+ }
+ user_pref_store_->SetValueSilently(path, value);
}
- return list;
+ return value;
}
-void PrefService::ReportValueChanged(const std::string& key) {
+void PrefService::ReportUserPrefChanged(const std::string& key) {
user_pref_store_->ReportValueChanged(key);
}
@@ -652,7 +664,7 @@ const Value* PrefService::Preference::GetValue() const {
DCHECK(pref_service_->FindPreference(name_.c_str())) <<
"Must register pref before getting its value";
- Value* found_value = NULL;
+ const Value* found_value = NULL;
if (pref_value_store()->GetValue(name_, type_, &found_value)) {
DCHECK(found_value->IsType(type_));
return found_value;
diff --git a/chrome/browser/prefs/pref_service.h b/chrome/browser/prefs/pref_service.h
index 2ab7b96..9d360ba 100644
--- a/chrome/browser/prefs/pref_service.h
+++ b/chrome/browser/prefs/pref_service.h
@@ -11,10 +11,11 @@
#include <set>
#include <string>
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/values.h"
+#include "chrome/common/json_pref_store.h"
class DefaultPrefStore;
class FilePath;
@@ -29,9 +30,11 @@ class Profile;
namespace subtle {
class PrefMemberBase;
+class ScopedUserPrefUpdateBase;
};
-class PrefService : public base::NonThreadSafe {
+class PrefService : public base::NonThreadSafe,
+ public JsonPrefStore::Delegate {
public:
// A helper class to store all the information associated with a preference.
class Preference {
@@ -110,6 +113,15 @@ class PrefService : public base::NonThreadSafe {
DISALLOW_COPY_AND_ASSIGN(Preference);
};
+ class Delegate {
+ public:
+ virtual void OnPrefsLoaded(PrefService* prefs, bool success) = 0;
+ };
+
+ // JsonPrefStore::Delegate implementaion.
+ virtual void OnPrefsRead(PersistentPrefStore::PrefReadError error,
+ bool no_dir);
+
// Factory method that creates a new instance of a PrefService with the
// applicable PrefStores. The |pref_filename| points to the user preference
// file. The |profile| is the one to which these preferences apply; it may be
@@ -121,6 +133,12 @@ class PrefService : public base::NonThreadSafe {
PrefStore* extension_pref_store,
Profile* profile);
+ // Same as above, but with async initialization.
+ static PrefService* CreatePrefServiceAsync(const FilePath& pref_filename,
+ PrefStore* extension_pref_store,
+ Profile* profile,
+ Delegate* delegate);
+
// Creates an incognito copy of the pref service that shares most pref stores
// but uses a fresh non-persistent overlay for the user pref store and an
// individual extension pref store (to cache the effective extension prefs for
@@ -148,6 +166,9 @@ class PrefService : public base::NonThreadSafe {
// Serializes the data and schedules save using ImportantFileWriter.
void ScheduleSavePersistentPrefs();
+ // Lands pending writes to disk.
+ void CommitPendingWrite();
+
// Make the PrefService aware of a pref.
void RegisterBooleanPref(const char* path, bool default_value);
void RegisterIntegerPref(const char* path, int default_value);
@@ -189,15 +210,19 @@ class PrefService : public base::NonThreadSafe {
void ClearPref(const char* path);
// If the path is valid (i.e., registered), update the pref value in the user
- // prefs. Seting a null value on a preference of List or Dictionary type is
- // equivalent to removing the user value for that preference, allowing the
- // default value to take effect unless another value takes precedence.
+ // prefs.
+ // To set the value of dictionary or list values in the pref tree use
+ // Set(), but to modify the value of a dictionary or list use either
+ // ListPrefUpdate or DictionaryPrefUpdate from scoped_user_pref_update.h.
void Set(const char* path, const Value& value);
void SetBoolean(const char* path, bool value);
void SetInteger(const char* path, int value);
void SetDouble(const char* path, double value);
void SetString(const char* path, const std::string& value);
void SetFilePath(const char* path, const FilePath& value);
+ // SetList() takes ownership of |value|. Pass a copy of the ListValue to
+ // keep ownership of the original list, if necessary.
+ void SetList(const char* path, ListValue* value);
// Int64 helper methods that actually store the given value as a string.
// Note that if obtaining the named value via GetDictionary or GetList, the
@@ -206,20 +231,6 @@ class PrefService : public base::NonThreadSafe {
int64 GetInt64(const char* path) const;
void RegisterInt64Pref(const char* path, int64 default_value);
- // Used to set the value of dictionary or list values in the pref tree. This
- // will create a dictionary or list if one does not exist in the pref tree.
- // This method returns NULL only if you're requesting an unregistered pref or
- // a non-dict/non-list pref.
- // WARNING: Changes to the dictionary or list will not automatically notify
- // pref observers.
- // Use a ScopedUserPrefUpdate to update observers on changes.
- // These should really be GetUserMutable... since we will only ever get
- // a mutable from the user preferences store.
- DictionaryValue* GetMutableDictionary(const char* path);
- ListValue* GetMutableList(const char* path);
- // TODO(battre) remove this function (hack).
- void ReportValueChanged(const std::string& key);
-
// Returns true if a value has been set for the specified path.
// NOTE: this is NOT the same as FindPreference. In particular
// FindPreference returns whether RegisterXXX has been invoked, where as
@@ -247,7 +258,8 @@ class PrefService : public base::NonThreadSafe {
PersistentPrefStore* user_prefs,
PrefStore* recommended_platform_prefs,
PrefStore* recommended_cloud_prefs,
- DefaultPrefStore* default_store);
+ DefaultPrefStore* default_store,
+ Delegate* delegate);
// The PrefNotifier handles registering and notifying preference observers.
// It is created and owned by this PrefService. Subclasses may access it for
@@ -274,17 +286,17 @@ class PrefService : public base::NonThreadSafe {
friend class PrefChangeRegistrar;
friend class subtle::PrefMemberBase;
- // Give access to pref_notifier();
- friend class ScopedUserPrefUpdate;
+ // Give access to ReportUserPrefChanged() and GetMutableUserPref().
+ friend class subtle::ScopedUserPrefUpdateBase;
// Construct an incognito version of the pref service. Use
// CreateIncognitoPrefService() instead of calling this constructor directly.
PrefService(const PrefService& original,
PrefStore* incognito_extension_prefs);
- // Returns a PrefNotifier. If you desire access to this, you will probably
- // want to use a ScopedUserPrefUpdate.
- PrefNotifier* pref_notifier() const;
+ // Sends notification of a changed preference. This needs to be called by
+ // a ScopedUserPrefUpdate if a DictionaryValue or ListValue is changed.
+ void ReportUserPrefChanged(const std::string& key);
// If the pref at the given path changes, we call the observer's Observe
// method with PREF_CHANGED. Note that observers should not call these methods
@@ -307,6 +319,15 @@ class PrefService : public base::NonThreadSafe {
// This should only be called from the constructor.
void InitFromStorage();
+ // Used to set the value of dictionary or list values in the user pref store.
+ // This will create a dictionary or list if one does not exist in the user
+ // pref store. This method returns NULL only if you're requesting an
+ // unregistered pref or a non-dict/non-list pref.
+ // |type| may only be Values::TYPE_DICTIONARY or Values::TYPE_LIST and
+ // |path| must point to a registered preference of type |type|.
+ // Ownership of the returned value remains at the user pref store.
+ Value* GetMutableUserPref(const char* path, Value::ValueType type);
+
// The PrefValueStore provides prioritized preference values. It is created
// and owned by this PrefService. Subclasses may access it for unit testing.
scoped_ptr<PrefValueStore> pref_value_store_;
@@ -320,6 +341,10 @@ class PrefService : public base::NonThreadSafe {
// of registered preferences are.
mutable PreferenceSet prefs_;
+ // Holds delegator to be called after initialization, if async version
+ // is used.
+ Delegate* delegate_;
+
DISALLOW_COPY_AND_ASSIGN(PrefService);
};
diff --git a/chrome/browser/prefs/pref_service_mock_builder.cc b/chrome/browser/prefs/pref_service_mock_builder.cc
index 14012d1..1de0403 100644
--- a/chrome/browser/prefs/pref_service_mock_builder.cc
+++ b/chrome/browser/prefs/pref_service_mock_builder.cc
@@ -113,7 +113,8 @@ PrefService* PrefServiceMockBuilder::Create() {
user_prefs_.get(),
recommended_platform_prefs_.get(),
recommended_cloud_prefs_.get(),
- new DefaultPrefStore());
+ new DefaultPrefStore(),
+ NULL);
managed_platform_prefs_ = NULL;
managed_cloud_prefs_ = NULL;
extension_prefs_ = NULL;
diff --git a/chrome/browser/prefs/pref_service_mock_builder.h b/chrome/browser/prefs/pref_service_mock_builder.h
index 3e4d1e0..24fc671 100644
--- a/chrome/browser/prefs/pref_service_mock_builder.h
+++ b/chrome/browser/prefs/pref_service_mock_builder.h
@@ -7,7 +7,7 @@
#pragma once
#include "base/basictypes.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "chrome/common/persistent_pref_store.h"
#include "chrome/common/pref_store.h"
diff --git a/chrome/browser/prefs/pref_service_uitest.cc b/chrome/browser/prefs/pref_service_uitest.cc
index fe2a79a..af2b1a6 100644
--- a/chrome/browser/prefs/pref_service_uitest.cc
+++ b/chrome/browser/prefs/pref_service_uitest.cc
@@ -6,28 +6,26 @@
#include "base/command_line.h"
#include "base/file_util.h"
-#include "base/path_service.h"
#include "base/test/test_file_util.h"
#include "base/values.h"
+#include "base/memory/scoped_temp_dir.h"
#include "build/build_config.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/json_value_serializer.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
+#include "content/common/json_value_serializer.h"
#include "ui/gfx/rect.h"
class PreferenceServiceTest : public UITest {
public:
void SetUp() {
- PathService::Get(base::DIR_TEMP, &tmp_profile_);
- tmp_profile_ = tmp_profile_.AppendASCII("tmp_profile");
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ FilePath tmp_profile = temp_dir_.path().AppendASCII("tmp_profile");
- // Create a fresh, empty copy of this directory.
- file_util::Delete(tmp_profile_, true);
- file_util::CreateDirectory(tmp_profile_);
+ ASSERT_TRUE(file_util::CreateDirectory(tmp_profile));
FilePath reference_pref_file;
if (new_profile_) {
@@ -36,7 +34,7 @@ class PreferenceServiceTest : public UITest {
.AppendASCII("window_placement")
.AppendASCII("Default")
.Append(chrome::kPreferencesFilename);
- tmp_pref_file_ = tmp_profile_.AppendASCII("Default");
+ tmp_pref_file_ = tmp_profile.AppendASCII("Default");
ASSERT_TRUE(file_util::CreateDirectory(tmp_pref_file_));
tmp_pref_file_ = tmp_pref_file_.Append(chrome::kPreferencesFilename);
} else {
@@ -44,7 +42,7 @@ class PreferenceServiceTest : public UITest {
.AppendASCII("profiles")
.AppendASCII("window_placement")
.Append(chrome::kLocalStateFilename);
- tmp_pref_file_ = tmp_profile_.Append(chrome::kLocalStateFilename);
+ tmp_pref_file_ = tmp_profile.Append(chrome::kLocalStateFilename);
}
ASSERT_TRUE(file_util::PathExists(reference_pref_file));
@@ -59,7 +57,7 @@ class PreferenceServiceTest : public UITest {
FILE_ATTRIBUTE_NORMAL));
#endif
- launch_arguments_.AppendSwitchPath(switches::kUserDataDir, tmp_profile_);
+ launch_arguments_.AppendSwitchPath(switches::kUserDataDir, tmp_profile);
}
bool LaunchAppWithProfile() {
@@ -71,14 +69,14 @@ class PreferenceServiceTest : public UITest {
void TearDown() {
UITest::TearDown();
-
- EXPECT_TRUE(file_util::DieFileDie(tmp_profile_, true));
}
public:
bool new_profile_;
FilePath tmp_pref_file_;
- FilePath tmp_profile_;
+
+ private:
+ ScopedTempDir temp_dir_;
};
#if !defined(OS_LINUX)
diff --git a/chrome/browser/prefs/pref_service_unittest.cc b/chrome/browser/prefs/pref_service_unittest.cc
index 90a1882..496e9de 100644
--- a/chrome/browser/prefs/pref_service_unittest.cc
+++ b/chrome/browser/prefs/pref_service_unittest.cc
@@ -6,7 +6,7 @@
#include "app/test/data/resource.h"
#include "base/command_line.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
diff --git a/chrome/browser/prefs/pref_set_observer.cc b/chrome/browser/prefs/pref_set_observer.cc
index 117937e..916769e 100644
--- a/chrome/browser/prefs/pref_set_observer.cc
+++ b/chrome/browser/prefs/pref_set_observer.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/prefs/pref_set_observer.h"
-#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
+#include "content/common/notification_type.h"
PrefSetObserver::PrefSetObserver(PrefService* pref_service,
NotificationObserver* observer)
diff --git a/chrome/browser/prefs/pref_set_observer.h b/chrome/browser/prefs/pref_set_observer.h
index 568265c..40c38e5 100644
--- a/chrome/browser/prefs/pref_set_observer.h
+++ b/chrome/browser/prefs/pref_set_observer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,9 +9,9 @@
#include <set>
#include "base/basictypes.h"
-#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
-#include "chrome/common/notification_observer.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "content/common/notification_observer.h"
// Observes the state of a set of preferences and allows to query their combined
// managed bits.
diff --git a/chrome/browser/prefs/pref_value_map.cc b/chrome/browser/prefs/pref_value_map.cc
index 0857f6d..54967e1 100644
--- a/chrome/browser/prefs/pref_value_map.cc
+++ b/chrome/browser/prefs/pref_value_map.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/prefs/pref_value_map.h"
#include "base/logging.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/stl_util-inl.h"
#include "base/values.h"
@@ -15,7 +15,18 @@ PrefValueMap::~PrefValueMap() {
Clear();
}
-bool PrefValueMap::GetValue(const std::string& key, Value** value) const {
+bool PrefValueMap::GetValue(const std::string& key, const Value** value) const {
+ const Map::const_iterator entry = prefs_.find(key);
+ if (entry != prefs_.end()) {
+ if (value)
+ *value = entry->second;
+ return true;
+ }
+
+ return false;
+}
+
+bool PrefValueMap::GetValue(const std::string& key, Value** value) {
const Map::const_iterator entry = prefs_.find(key);
if (entry != prefs_.end()) {
if (value)
@@ -76,13 +87,13 @@ PrefValueMap::const_iterator PrefValueMap::end() const {
bool PrefValueMap::GetBoolean(const std::string& key,
bool* value) const {
- Value* stored_value = NULL;
+ const Value* stored_value = NULL;
return GetValue(key, &stored_value) && stored_value->GetAsBoolean(value);
}
bool PrefValueMap::GetString(const std::string& key,
std::string* value) const {
- Value* stored_value = NULL;
+ const Value* stored_value = NULL;
return GetValue(key, &stored_value) && stored_value->GetAsString(value);
}
diff --git a/chrome/browser/prefs/pref_value_map.h b/chrome/browser/prefs/pref_value_map.h
index 19aeb05..d4b9f4e 100644
--- a/chrome/browser/prefs/pref_value_map.h
+++ b/chrome/browser/prefs/pref_value_map.h
@@ -26,7 +26,8 @@ class PrefValueMap {
// Gets the value for |key| and stores it in |value|. Ownership remains with
// the map. Returns true if a value is present. If not, |value| is not
// touched.
- bool GetValue(const std::string& key, Value** value) const;
+ bool GetValue(const std::string& key, const Value** value) const;
+ bool GetValue(const std::string& key, Value** value);
// Sets a new |value| for |key|. Takes ownership of |value|, which must be
// non-NULL. Returns true if the value changed.
diff --git a/chrome/browser/prefs/pref_value_map_unittest.cc b/chrome/browser/prefs/pref_value_map_unittest.cc
index 5e248b0..cc47a85 100644
--- a/chrome/browser/prefs/pref_value_map_unittest.cc
+++ b/chrome/browser/prefs/pref_value_map_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,7 +11,7 @@ class PrefValueMapTest : public testing::Test {
TEST_F(PrefValueMapTest, SetValue) {
PrefValueMap map;
- Value* result = NULL;
+ const Value* result = NULL;
EXPECT_FALSE(map.GetValue("key", &result));
EXPECT_FALSE(result);
diff --git a/chrome/browser/prefs/pref_value_store.cc b/chrome/browser/prefs/pref_value_store.cc
index b97a4fb..3318a1d 100644
--- a/chrome/browser/prefs/pref_value_store.cc
+++ b/chrome/browser/prefs/pref_value_store.cc
@@ -102,7 +102,7 @@ PrefValueStore* PrefValueStore::CloneAndSpecialize(
bool PrefValueStore::GetValue(const std::string& name,
Value::ValueType type,
- Value** out_value) const {
+ const Value** out_value) const {
*out_value = NULL;
// Check the |PrefStore|s in order of their priority from highest to lowest
// to find the value of the preference described by the given preference name.
@@ -175,7 +175,7 @@ bool PrefValueStore::PrefValueInStore(
PrefValueStore::PrefStoreType store) const {
// Declare a temp Value* and call GetValueFromStore,
// ignoring the output value.
- Value* tmp_value = NULL;
+ const Value* tmp_value = NULL;
return GetValueFromStore(name, store, &tmp_value);
}
@@ -207,7 +207,7 @@ PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref(
bool PrefValueStore::GetValueFromStore(const char* name,
PrefValueStore::PrefStoreType store_type,
- Value** out_value) const {
+ const Value** out_value) const {
// Only return true if we find a value and it is the correct type, so stale
// values with the incorrect type will be ignored.
const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type));
diff --git a/chrome/browser/prefs/pref_value_store.h b/chrome/browser/prefs/pref_value_store.h
index bddbdaa..6a492ba 100644
--- a/chrome/browser/prefs/pref_value_store.h
+++ b/chrome/browser/prefs/pref_value_store.h
@@ -12,7 +12,7 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/values.h"
#include "chrome/common/pref_store.h"
#include "content/browser/browser_thread.h"
@@ -78,7 +78,7 @@ class PrefValueStore {
// Preference::GetValue() instead of calling this method directly.
bool GetValue(const std::string& name,
Value::ValueType type,
- Value** out_value) const;
+ const Value** out_value) const;
// These methods return true if a preference with the given name is in the
// indicated pref store, even if that value is currently being overridden by
@@ -107,12 +107,15 @@ class PrefValueStore {
// MANAGED_PLATFORM contains all managed preference values that are
// provided by a platform-specific policy mechanism (e.g. Windows
// Group Policy).
- // DEVICE_MANAGEMENT contains all managed preference values supplied
+ // MANAGED_CLOUD contains all managed preference values supplied
// by the device management server (cloud policy).
// EXTENSION contains preference values set by extensions.
// COMMAND_LINE contains preference values set by command-line switches.
// USER contains all user-set preference values.
- // RECOMMENDED contains all recommended (policy) preference values.
+ // RECOMMENDED_PLATFORM contains all recommended (policy) preference values
+ // that are provided by a platform-specific policy mechanism.
+ // RECOMMENDED_CLOUD contains all recommended (policy) preference values
+ // that are provided by the device management server (cloud policy).
// DEFAULT contains all application default preference values.
enum PrefStoreType {
// INVALID_STORE is not associated with an actual PrefStore but used as
@@ -195,7 +198,7 @@ class PrefValueStore {
// Get a value from the specified store type.
bool GetValueFromStore(const char* name,
PrefStoreType store,
- Value** out_value) const;
+ const Value** out_value) const;
// Called upon changes in individual pref stores in order to determine whether
// the user-visible pref value has changed. Triggers the change notification
diff --git a/chrome/browser/prefs/pref_value_store_unittest.cc b/chrome/browser/prefs/pref_value_store_unittest.cc
index 81c068c..6819e46 100644
--- a/chrome/browser/prefs/pref_value_store_unittest.cc
+++ b/chrome/browser/prefs/pref_value_store_unittest.cc
@@ -5,7 +5,7 @@
#include <set>
#include <string>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/dummy_configuration_policy_provider.h"
@@ -289,7 +289,7 @@ class PrefValueStoreTest : public testing::Test {
};
TEST_F(PrefValueStoreTest, GetValue) {
- Value* value;
+ const Value* value;
// The following tests read a value from the PrefService. The preferences are
// set in a way such that all lower-priority stores have a value and we can
diff --git a/chrome/browser/prefs/proxy_config_dictionary.h b/chrome/browser/prefs/proxy_config_dictionary.h
index 7af2e27..c05f182 100644
--- a/chrome/browser/prefs/proxy_config_dictionary.h
+++ b/chrome/browser/prefs/proxy_config_dictionary.h
@@ -9,7 +9,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "chrome/browser/prefs/proxy_prefs.h"
class DictionaryValue;
diff --git a/chrome/browser/prefs/proxy_config_dictionary_unittest.cc b/chrome/browser/prefs/proxy_config_dictionary_unittest.cc
index 07c6743..5575b66 100644
--- a/chrome/browser/prefs/proxy_config_dictionary_unittest.cc
+++ b/chrome/browser/prefs/proxy_config_dictionary_unittest.cc
@@ -4,7 +4,7 @@
#include <string>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/prefs/scoped_user_pref_update.cc b/chrome/browser/prefs/scoped_user_pref_update.cc
index 2c3c995..2188f9a 100644
--- a/chrome/browser/prefs/scoped_user_pref_update.cc
+++ b/chrome/browser/prefs/scoped_user_pref_update.cc
@@ -1,20 +1,36 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "base/logging.h"
#include "chrome/browser/prefs/pref_notifier.h"
#include "chrome/browser/prefs/pref_service.h"
-ScopedUserPrefUpdate::ScopedUserPrefUpdate(
- PrefService* service, const char* path)
+namespace subtle {
+
+ScopedUserPrefUpdateBase::ScopedUserPrefUpdateBase(PrefService* service,
+ const char* path)
: service_(service),
- path_(path) {}
+ path_(path),
+ value_(NULL) {}
+
+ScopedUserPrefUpdateBase::~ScopedUserPrefUpdateBase() {
+ Notify();
+}
-ScopedUserPrefUpdate::~ScopedUserPrefUpdate() {
- // TODO(mnissler, danno): This sends a notification unconditionally, which is
- // wrong. We should rather tell the PrefService that the user pref got
- // updated.
- service_->ReportValueChanged(path_);
+Value* ScopedUserPrefUpdateBase::Get(Value::ValueType type) {
+ if (!value_)
+ value_ = service_->GetMutableUserPref(path_.c_str(), type);
+ return value_;
}
+
+void ScopedUserPrefUpdateBase::Notify() {
+ if (value_) {
+ service_->ReportUserPrefChanged(path_);
+ value_ = NULL;
+ }
+}
+
+} // namespace subtle
diff --git a/chrome/browser/prefs/scoped_user_pref_update.h b/chrome/browser/prefs/scoped_user_pref_update.h
index 8992d09..9b99f30 100644
--- a/chrome/browser/prefs/scoped_user_pref_update.h
+++ b/chrome/browser/prefs/scoped_user_pref_update.h
@@ -1,24 +1,103 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// A helper class that assists preferences in firing notifications when lists
-// are changed.
+// or dictionaries are changed.
#ifndef CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_
#define CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_
#pragma once
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/threading/non_thread_safe.h"
+#include "base/values.h"
#include "chrome/browser/prefs/pref_service.h"
-class ScopedUserPrefUpdate {
- public:
- ScopedUserPrefUpdate(PrefService* service, const char* path);
- ~ScopedUserPrefUpdate();
+class DictionaryValue;
+class ListValue;
+class PrefService;
+
+namespace subtle {
+
+// Base class for ScopedUserPrefUpdateTemplate that contains the parts
+// that do not depend on ScopedUserPrefUpdateTemplate's template parameter.
+//
+// We need this base class mostly for making it a friend of PrefService
+// and getting access to PrefService::GetMutableUserPref and
+// PrefService::ReportUserPrefChanged.
+class ScopedUserPrefUpdateBase : public base::NonThreadSafe {
+ protected:
+ ScopedUserPrefUpdateBase(PrefService* service, const char* path);
+
+ // Calls Notify().
+ virtual ~ScopedUserPrefUpdateBase();
+
+ // Sets |value_| to |service_|->GetMutableUserPref and returns it.
+ Value* Get(Value::ValueType type);
private:
+ // If |value_| is not null, triggers a notification of PrefObservers and
+ // resets |value_|.
+ virtual void Notify();
+
+ // Weak pointer.
PrefService* service_;
+ // Path of the preference being updated.
std::string path_;
+ // Cache of value from user pref store (set between Get() and Notify() calls).
+ Value* value_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdateBase);
};
+} // namespace subtle
+
+// Class to support modifications to DictionaryValues and ListValues while
+// guaranteeing that PrefObservers are notified of changed values.
+//
+// This class may only be used on the UI thread as it requires access to the
+// PrefService.
+template <typename T, Value::ValueType type_enum_value>
+class ScopedUserPrefUpdate : public subtle::ScopedUserPrefUpdateBase {
+ public:
+ ScopedUserPrefUpdate(PrefService* service, const char* path)
+ : ScopedUserPrefUpdateBase(service, path) {}
+
+ // Triggers an update notification if Get() was called.
+ virtual ~ScopedUserPrefUpdate() {}
+
+ // Returns a mutable |T| instance that
+ // - is already in the user pref store, or
+ // - is (silently) created and written to the user pref store if none existed
+ // before.
+ //
+ // Calling Get() implies that an update notification is necessary at
+ // destruction time.
+ //
+ // The ownership of the return value remains with the user pref store.
+ virtual T* Get() {
+ return static_cast<T*>(
+ subtle::ScopedUserPrefUpdateBase::Get(type_enum_value));
+ }
+
+ T& operator*() {
+ return *Get();
+ }
+
+ T* operator->() {
+ return Get();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdate);
+};
+
+typedef ScopedUserPrefUpdate<DictionaryValue, Value::TYPE_DICTIONARY>
+ DictionaryPrefUpdate;
+typedef ScopedUserPrefUpdate<ListValue, Value::TYPE_LIST> ListPrefUpdate;
+
#endif // CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_
diff --git a/chrome/browser/prefs/scoped_user_pref_update_unittest.cc b/chrome/browser/prefs/scoped_user_pref_update_unittest.cc
new file mode 100644
index 0000000..88faebe
--- /dev/null
+++ b/chrome/browser/prefs/scoped_user_pref_update_unittest.cc
@@ -0,0 +1,79 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/prefs/pref_change_registrar.h"
+#include "chrome/browser/prefs/pref_observer_mock.h"
+#include "chrome/test/testing_pref_service.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Mock;
+
+class ScopedUserPrefUpdateTest : public testing::Test {
+ public:
+ ~ScopedUserPrefUpdateTest() {}
+
+ protected:
+ virtual void SetUp() {
+ prefs_.RegisterDictionaryPref(kPref);
+ registrar_.Init(&prefs_);
+ registrar_.Add(kPref, &observer_);
+ }
+
+ static const char kPref[];
+ static const char kKey[];
+ static const char kValue[];
+
+ TestingPrefService prefs_;
+ PrefObserverMock observer_;
+ PrefChangeRegistrar registrar_;
+};
+
+const char ScopedUserPrefUpdateTest::kPref[] = "name";
+const char ScopedUserPrefUpdateTest::kKey[] = "key";
+const char ScopedUserPrefUpdateTest::kValue[] = "value";
+
+TEST_F(ScopedUserPrefUpdateTest, RegularUse) {
+ // Dictionary that will be expected to be set at the end.
+ DictionaryValue expected_dictionary;
+ expected_dictionary.SetString(kKey, kValue);
+
+ {
+ EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
+ DictionaryPrefUpdate update(&prefs_, kPref);
+ DictionaryValue* value = update.Get();
+ ASSERT_TRUE(value);
+ value->SetString(kKey, kValue);
+
+ // The dictionary was created for us but the creation should have happened
+ // silently without notifications.
+ Mock::VerifyAndClearExpectations(&observer_);
+
+ // Modifications happen online and are instantly visible, though.
+ const DictionaryValue* current_value = prefs_.GetDictionary(kPref);
+ ASSERT_TRUE(current_value);
+ EXPECT_TRUE(expected_dictionary.Equals(current_value));
+
+ // Now we are leaving the scope of the update so we should be notified.
+ observer_.Expect(&prefs_, kPref, &expected_dictionary);
+ }
+ Mock::VerifyAndClearExpectations(&observer_);
+
+ const DictionaryValue* current_value = prefs_.GetDictionary(kPref);
+ ASSERT_TRUE(current_value);
+ EXPECT_TRUE(expected_dictionary.Equals(current_value));
+}
+
+TEST_F(ScopedUserPrefUpdateTest, NeverTouchAnything) {
+ const DictionaryValue* old_value = prefs_.GetDictionary(kPref);
+ EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
+ {
+ DictionaryPrefUpdate update(&prefs_, kPref);
+ }
+ const DictionaryValue* new_value = prefs_.GetDictionary(kPref);
+ EXPECT_EQ(old_value, new_value);
+ Mock::VerifyAndClearExpectations(&observer_);
+}
diff --git a/chrome/browser/prefs/session_startup_pref.cc b/chrome/browser/prefs/session_startup_pref.cc
index 8642018..de5cf76 100644
--- a/chrome/browser/prefs/session_startup_pref.cc
+++ b/chrome/browser/prefs/session_startup_pref.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -70,9 +70,8 @@ void SessionStartupPref::SetStartupPref(PrefService* prefs,
// Always save the URLs, that way the UI can remain consistent even if the
// user changes the startup type pref.
// Ownership of the ListValue retains with the pref service.
- ScopedUserPrefUpdate update(prefs, prefs::kURLsToRestoreOnStartup);
- ListValue* url_pref_list =
- prefs->GetMutableList(prefs::kURLsToRestoreOnStartup);
+ ListPrefUpdate update(prefs, prefs::kURLsToRestoreOnStartup);
+ ListValue* url_pref_list = update.Get();
DCHECK(url_pref_list);
url_pref_list->Clear();
for (size_t i = 0; i < pref.urls.size(); ++i) {
diff --git a/chrome/browser/prefs/testing_pref_store.cc b/chrome/browser/prefs/testing_pref_store.cc
index a3d33d8..e85a836 100644
--- a/chrome/browser/prefs/testing_pref_store.cc
+++ b/chrome/browser/prefs/testing_pref_store.cc
@@ -14,7 +14,12 @@ TestingPrefStore::TestingPrefStore()
TestingPrefStore::~TestingPrefStore() {}
PrefStore::ReadResult TestingPrefStore::GetValue(const std::string& key,
- Value** value) const {
+ const Value** value) const {
+ return prefs_.GetValue(key, value) ? READ_OK : READ_NO_VALUE;
+}
+
+PrefStore::ReadResult TestingPrefStore::GetMutableValue(const std::string& key,
+ Value** value) {
return prefs_.GetValue(key, value) ? READ_OK : READ_NO_VALUE;
}
@@ -90,7 +95,7 @@ void TestingPrefStore::SetBoolean(const std::string& key, bool value) {
bool TestingPrefStore::GetString(const std::string& key,
std::string* value) const {
- Value* stored_value;
+ const Value* stored_value;
if (!prefs_.GetValue(key, &stored_value) || !stored_value)
return false;
@@ -98,7 +103,7 @@ bool TestingPrefStore::GetString(const std::string& key,
}
bool TestingPrefStore::GetInteger(const std::string& key, int* value) const {
- Value* stored_value;
+ const Value* stored_value;
if (!prefs_.GetValue(key, &stored_value) || !stored_value)
return false;
@@ -106,7 +111,7 @@ bool TestingPrefStore::GetInteger(const std::string& key, int* value) const {
}
bool TestingPrefStore::GetBoolean(const std::string& key, bool* value) const {
- Value* stored_value;
+ const Value* stored_value;
if (!prefs_.GetValue(key, &stored_value) || !stored_value)
return false;
diff --git a/chrome/browser/prefs/testing_pref_store.h b/chrome/browser/prefs/testing_pref_store.h
index 79f1c59..048dcc7 100644
--- a/chrome/browser/prefs/testing_pref_store.h
+++ b/chrome/browser/prefs/testing_pref_store.h
@@ -7,8 +7,8 @@
#pragma once
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
-#include "base/scoped_ptr.h"
#include "chrome/browser/prefs/pref_value_map.h"
#include "chrome/common/persistent_pref_store.h"
@@ -23,12 +23,15 @@ class TestingPrefStore : public PersistentPrefStore {
virtual ~TestingPrefStore();
// Overriden from PrefStore.
- virtual ReadResult GetValue(const std::string& key, Value** result) const;
+ virtual ReadResult GetValue(const std::string& key,
+ const Value** result) const;
virtual void AddObserver(PrefStore::Observer* observer);
virtual void RemoveObserver(PrefStore::Observer* observer);
virtual bool IsInitializationComplete() const;
// PersistentPrefStore overrides:
+ virtual ReadResult GetMutableValue(const std::string& key, Value** result);
+ virtual void ReportValueChanged(const std::string& key);
virtual void SetValue(const std::string& key, Value* value);
virtual void SetValueSilently(const std::string& key, Value* value);
virtual void RemoveValue(const std::string& key);
@@ -36,8 +39,7 @@ class TestingPrefStore : public PersistentPrefStore {
virtual PersistentPrefStore::PrefReadError ReadPrefs();
virtual bool WritePrefs();
virtual void ScheduleWritePrefs() {}
- // TODO(battre) remove this function
- virtual void ReportValueChanged(const std::string& key);
+ virtual void CommitPendingWrite() {}
// Marks the store as having completed initialization.
void SetInitializationCompleted();
diff --git a/chrome/browser/prefs/value_map_pref_store.cc b/chrome/browser/prefs/value_map_pref_store.cc
index 58c4016..4d2c8ca 100644
--- a/chrome/browser/prefs/value_map_pref_store.cc
+++ b/chrome/browser/prefs/value_map_pref_store.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,7 @@ ValueMapPrefStore::ValueMapPrefStore() {}
ValueMapPrefStore::~ValueMapPrefStore() {}
PrefStore::ReadResult ValueMapPrefStore::GetValue(const std::string& key,
- Value** value) const {
+ const Value** value) const {
return prefs_.GetValue(key, value) ? READ_OK : READ_NO_VALUE;
}
diff --git a/chrome/browser/prefs/value_map_pref_store.h b/chrome/browser/prefs/value_map_pref_store.h
index a8b66c4..c713156 100644
--- a/chrome/browser/prefs/value_map_pref_store.h
+++ b/chrome/browser/prefs/value_map_pref_store.h
@@ -22,7 +22,8 @@ class ValueMapPrefStore : public PrefStore {
virtual ~ValueMapPrefStore();
// PrefStore overrides:
- virtual ReadResult GetValue(const std::string& key, Value** value) const;
+ virtual ReadResult GetValue(const std::string& key,
+ const Value** value) const;
virtual void AddObserver(PrefStore::Observer* observer);
virtual void RemoveObserver(PrefStore::Observer* observer);