From 75fee3776f2e159d8e52bb13bb4545ac46021512 Mon Sep 17 00:00:00 2001 From: "joi@chromium.org" Date: Wed, 6 Mar 2013 00:42:44 +0000 Subject: Introduce //components/user_prefs. The user_prefs component provides: a) The UserPrefs class, used to map PrefService objects to BrowserContext. This addresses a TODO to get rid of PrefServiceFromBrowserContext from base/prefs/pref_service.h, where clearly a mention of a content class did not belong. b) A place for PrefRegistrySyncable to live, where it can be used by components that need to register prefs. We also use (b) in this change to eliminate Autofill's dependency on chrome/browser/prefs. Work is ongoing to move Autofill to //components/autofill. TBR=ben@chromium.org BUG=155525,140037 Review URL: https://chromiumcodereview.appspot.com/12340111 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186301 0039d316-1c4b-4281-b951-d872f2087c98 --- components/user_prefs/DEPS | 4 + components/user_prefs/OWNERS | 4 + components/user_prefs/README | 8 + components/user_prefs/pref_registry_syncable.cc | 220 ++++++++++++++++++++++++ components/user_prefs/pref_registry_syncable.h | 119 +++++++++++++ components/user_prefs/user_prefs.cc | 44 +++++ components/user_prefs/user_prefs.h | 49 ++++++ components/user_prefs/user_prefs_export.h | 29 ++++ 8 files changed, 477 insertions(+) create mode 100644 components/user_prefs/DEPS create mode 100644 components/user_prefs/OWNERS create mode 100644 components/user_prefs/README create mode 100644 components/user_prefs/pref_registry_syncable.cc create mode 100644 components/user_prefs/pref_registry_syncable.h create mode 100644 components/user_prefs/user_prefs.cc create mode 100644 components/user_prefs/user_prefs.h create mode 100644 components/user_prefs/user_prefs_export.h (limited to 'components/user_prefs') diff --git a/components/user_prefs/DEPS b/components/user_prefs/DEPS new file mode 100644 index 0000000..c36190b --- /dev/null +++ b/components/user_prefs/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+content/public/browser", + "+ui/base", +] diff --git a/components/user_prefs/OWNERS b/components/user_prefs/OWNERS new file mode 100644 index 0000000..024da1c --- /dev/null +++ b/components/user_prefs/OWNERS @@ -0,0 +1,4 @@ +battre@chromium.org +bauerb@chromium.org +mnissler@chromium.org +pam@chromium.org diff --git a/components/user_prefs/README b/components/user_prefs/README new file mode 100644 index 0000000..a7ca509 --- /dev/null +++ b/components/user_prefs/README @@ -0,0 +1,8 @@ +The //components/user_pref component provides: + +a) The UserPrefs class, where components dependent on looking up +preferences associated with users can look them up by +content::BrowserContext. + +b) A place for PrefRegistrySyncable to live, where it can be used by +components that need to register preferences associated with users. diff --git a/components/user_prefs/pref_registry_syncable.cc b/components/user_prefs/pref_registry_syncable.cc new file mode 100644 index 0000000..874f8a6 --- /dev/null +++ b/components/user_prefs/pref_registry_syncable.cc @@ -0,0 +1,220 @@ +// Copyright (c) 2012 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 "components/user_prefs/pref_registry_syncable.h" + +#include "base/files/file_path.h" +#include "base/prefs/default_pref_store.h" +#include "base/string_number_conversions.h" +#include "base/values.h" +#include "ui/base/l10n/l10n_util.h" + +namespace { + +// A helper function for RegisterLocalized*Pref that creates a Value* +// based on a localized resource. Because we control the values in a +// locale dll, this should always return a Value of the appropriate +// type. +base::Value* CreateLocaleDefaultValue(base::Value::Type type, + int message_id) { + const std::string resource_string = l10n_util::GetStringUTF8(message_id); + DCHECK(!resource_string.empty()); + switch (type) { + case Value::TYPE_BOOLEAN: { + if ("true" == resource_string) + return Value::CreateBooleanValue(true); + if ("false" == resource_string) + return Value::CreateBooleanValue(false); + break; + } + + case Value::TYPE_INTEGER: { + int val; + base::StringToInt(resource_string, &val); + return Value::CreateIntegerValue(val); + } + + case Value::TYPE_DOUBLE: { + double val; + base::StringToDouble(resource_string, &val); + return Value::CreateDoubleValue(val); + } + + case Value::TYPE_STRING: { + return Value::CreateStringValue(resource_string); + } + + default: { + NOTREACHED() << + "list and dictionary types cannot have default locale values"; + } + } + NOTREACHED(); + return Value::CreateNullValue(); +} + +} // namespace + +PrefRegistrySyncable::PrefRegistrySyncable() { +} + +PrefRegistrySyncable::~PrefRegistrySyncable() { +} + +const std::set& +PrefRegistrySyncable::syncable_preferences() const { + return syncable_preferences_; +} + +void PrefRegistrySyncable::SetSyncableRegistrationCallback( + const SyncableRegistrationCallback& cb) { + callback_ = cb; +} + +void PrefRegistrySyncable::RegisterBooleanPref(const char* path, + bool default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, + Value::CreateBooleanValue(default_value), + sync_status); +} + +void PrefRegistrySyncable::RegisterIntegerPref(const char* path, + int default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, + Value::CreateIntegerValue(default_value), + sync_status); +} + +void PrefRegistrySyncable::RegisterDoublePref(const char* path, + double default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, + Value::CreateDoubleValue(default_value), + sync_status); +} + +void PrefRegistrySyncable::RegisterStringPref(const char* path, + const std::string& default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, + Value::CreateStringValue(default_value), + sync_status); +} + +void PrefRegistrySyncable::RegisterFilePathPref( + const char* path, + const base::FilePath& default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, + Value::CreateStringValue(default_value.value()), + sync_status); +} + +void PrefRegistrySyncable::RegisterListPref(const char* path, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, new ListValue(), sync_status); +} + +void PrefRegistrySyncable::RegisterListPref(const char* path, + ListValue* default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, default_value, sync_status); +} + +void PrefRegistrySyncable::RegisterDictionaryPref(const char* path, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, new DictionaryValue(), sync_status); +} + +void PrefRegistrySyncable::RegisterDictionaryPref( + const char* path, + DictionaryValue* default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference(path, default_value, sync_status); +} + +void PrefRegistrySyncable::RegisterLocalizedBooleanPref( + const char* path, + int locale_default_message_id, + PrefSyncStatus sync_status) { + RegisterSyncablePreference( + path, + CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id), + sync_status); +} + +void PrefRegistrySyncable::RegisterLocalizedIntegerPref( + const char* path, + int locale_default_message_id, + PrefSyncStatus sync_status) { + RegisterSyncablePreference( + path, + CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id), + sync_status); +} + +void PrefRegistrySyncable::RegisterLocalizedDoublePref( + const char* path, + int locale_default_message_id, + PrefSyncStatus sync_status) { + RegisterSyncablePreference( + path, + CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id), + sync_status); +} + +void PrefRegistrySyncable::RegisterLocalizedStringPref( + const char* path, + int locale_default_message_id, + PrefSyncStatus sync_status) { + RegisterSyncablePreference( + path, + CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id), + sync_status); +} + +void PrefRegistrySyncable::RegisterInt64Pref( + const char* path, + int64 default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference( + path, + Value::CreateStringValue(base::Int64ToString(default_value)), + sync_status); +} + +void PrefRegistrySyncable::RegisterUint64Pref( + const char* path, + uint64 default_value, + PrefSyncStatus sync_status) { + RegisterSyncablePreference( + path, + Value::CreateStringValue(base::Uint64ToString(default_value)), + sync_status); +} + +void PrefRegistrySyncable::RegisterSyncablePreference( + const char* path, + base::Value* default_value, + PrefSyncStatus sync_status) { + PrefRegistry::RegisterPreference(path, default_value); + + if (sync_status == SYNCABLE_PREF) { + syncable_preferences_.insert(path); + + if (!callback_.is_null()) + callback_.Run(path); + } +} + +scoped_refptr PrefRegistrySyncable::ForkForIncognito() { + // TODO(joi): We can directly reuse the same PrefRegistry once + // PrefService no longer registers for callbacks on registration and + // unregistration. + scoped_refptr registry(new PrefRegistrySyncable()); + registry->defaults_ = defaults_; + return registry; +} diff --git a/components/user_prefs/pref_registry_syncable.h b/components/user_prefs/pref_registry_syncable.h new file mode 100644 index 0000000..08477f2 --- /dev/null +++ b/components/user_prefs/pref_registry_syncable.h @@ -0,0 +1,119 @@ +// Copyright (c) 2012 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. + +#ifndef COMPONENTS_USER_PREFS_PREF_REGISTRY_SYNCABLE_H_ +#define COMPONENTS_USER_PREFS_PREF_REGISTRY_SYNCABLE_H_ + +#include +#include + +#include "base/prefs/pref_registry.h" +#include "components/user_prefs/user_prefs_export.h" + +namespace base { +class DictionaryValue; +class FilePath; +class ListValue; +class Value; +} + +// A PrefRegistry that forces users to choose whether each registered +// preference is syncable or not. +// +// Classes or components that want to register such preferences should +// define a static function named RegisterUserPrefs that takes a +// PrefRegistrySyncable*, and the top-level application using the +// class or embedding the component should call this function at an +// appropriate time before the PrefService for these preferences is +// constructed. See e.g. chrome/browser/prefs/browser_prefs.cc which +// does this for Chrome. +class USER_PREFS_EXPORT PrefRegistrySyncable : public PrefRegistry { + public: + typedef base::Callback SyncableRegistrationCallback; + + // Enum used when registering preferences to determine if it should + // be synced or not. + enum PrefSyncStatus { + UNSYNCABLE_PREF, + SYNCABLE_PREF + }; + + PrefRegistrySyncable(); + + // Retrieve the set of syncable preferences currently registered. + const std::set& syncable_preferences() const; + + // Exactly one callback can be set for the event of a syncable + // preference being registered. It will be fired after the + // registration has occurred. + // + // Calling this method after a callback has already been set will + // make the object forget the previous callback and use the new one + // instead. + void SetSyncableRegistrationCallback(const SyncableRegistrationCallback& cb); + + void RegisterBooleanPref(const char* path, + bool default_value, + PrefSyncStatus sync_status); + void RegisterIntegerPref(const char* path, + int default_value, + PrefSyncStatus sync_status); + void RegisterDoublePref(const char* path, + double default_value, + PrefSyncStatus sync_status); + void RegisterStringPref(const char* path, + const std::string& default_value, + PrefSyncStatus sync_status); + void RegisterFilePathPref(const char* path, + const base::FilePath& default_value, + PrefSyncStatus sync_status); + void RegisterListPref(const char* path, + PrefSyncStatus sync_status); + void RegisterDictionaryPref(const char* path, + PrefSyncStatus sync_status); + void RegisterListPref(const char* path, + base::ListValue* default_value, + PrefSyncStatus sync_status); + void RegisterDictionaryPref(const char* path, + base::DictionaryValue* default_value, + PrefSyncStatus sync_status); + void RegisterLocalizedBooleanPref(const char* path, + int locale_default_message_id, + PrefSyncStatus sync_status); + void RegisterLocalizedIntegerPref(const char* path, + int locale_default_message_id, + PrefSyncStatus sync_status); + void RegisterLocalizedDoublePref(const char* path, + int locale_default_message_id, + PrefSyncStatus sync_status); + void RegisterLocalizedStringPref(const char* path, + int locale_default_message_id, + PrefSyncStatus sync_status); + void RegisterInt64Pref(const char* path, + int64 default_value, + PrefSyncStatus sync_status); + void RegisterUint64Pref(const char* path, + uint64 default_value, + PrefSyncStatus sync_status); + + // Returns a new PrefRegistrySyncable that uses the same defaults + // store. + scoped_refptr ForkForIncognito(); + + private: + virtual ~PrefRegistrySyncable(); + + void RegisterSyncablePreference(const char* path, + base::Value* default_value, + PrefSyncStatus sync_status); + + SyncableRegistrationCallback callback_; + + // Contains the names of all registered preferences that are syncable. + std::set syncable_preferences_; + + DISALLOW_COPY_AND_ASSIGN(PrefRegistrySyncable); +}; + +#endif // COMPONENTS_USER_PREFS_PREF_REGISTRY_SYNCABLE_H_ diff --git a/components/user_prefs/user_prefs.cc b/components/user_prefs/user_prefs.cc new file mode 100644 index 0000000..0c920f0 --- /dev/null +++ b/components/user_prefs/user_prefs.cc @@ -0,0 +1,44 @@ +// Copyright 2013 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 "components/user_prefs/user_prefs.h" + +#include "base/logging.h" +#include "base/memory/singleton.h" +#include "base/prefs/pref_service.h" +#include "content/public/browser/browser_context.h" + +namespace components { + +namespace { + +void* UserDataKey() { + // We just need a unique constant. Use the address of this static member. + return reinterpret_cast(&UserPrefs::Get); +} + +} // namespace + +UserPrefs::UserPrefs(PrefService* prefs) : prefs_(prefs) { +} + +UserPrefs::~UserPrefs() { +} + +// static +PrefService* UserPrefs::Get(content::BrowserContext* context) { + DCHECK(context); + return static_cast( + context->GetUserData(UserDataKey()))->prefs_; +} + +// static +void UserPrefs::Set(content::BrowserContext* context, PrefService* prefs) { + DCHECK(context); + DCHECK(prefs); + DCHECK(!context->GetUserData(UserDataKey())); + context->SetUserData(UserDataKey(), new UserPrefs(prefs)); +} + +} // namespace components diff --git a/components/user_prefs/user_prefs.h b/components/user_prefs/user_prefs.h new file mode 100644 index 0000000..1919748 --- /dev/null +++ b/components/user_prefs/user_prefs.h @@ -0,0 +1,49 @@ +// Copyright 2013 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. + +#ifndef COMPONENTS_USER_PREFS_USER_PREFS_H_ +#define COMPONENTS_USER_PREFS_USER_PREFS_H_ + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/supports_user_data.h" +#include "components/user_prefs/user_prefs_export.h" + +class PrefService; + +namespace content { +class BrowserContext; +} + +namespace components { + +// Components may use preferences associated with a given user. These +// hang off of content::BrowserContext and can be retrieved using +// UserPrefs::Get(). +// +// It is up to the embedder tof create and own the PrefService and +// attach it to BrowserContext using the UserPrefs::Set() function. +class USER_PREFS_EXPORT UserPrefs : public base::SupportsUserData::Data { + public: + // Retrieves the PrefService for a given BrowserContext, or NULL if + // none is attached. + static PrefService* Get(content::BrowserContext* context); + + // Hangs the specified |prefs| off of |context|. Should be called + // only once per BrowserContext. + static void Set(content::BrowserContext* context, PrefService* prefs); + + private: + UserPrefs(PrefService* prefs); + virtual ~UserPrefs(); + + // Non-owning; owned by embedder. + PrefService* prefs_; + + DISALLOW_COPY_AND_ASSIGN(UserPrefs); +}; + +} // namespace components + +#endif // COMPONENTS_USER_PREFS_USER_PREFS_H_ diff --git a/components/user_prefs/user_prefs_export.h b/components/user_prefs/user_prefs_export.h new file mode 100644 index 0000000..3d20222 --- /dev/null +++ b/components/user_prefs/user_prefs_export.h @@ -0,0 +1,29 @@ +// Copyright 2013 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. + +#ifndef COMPONENTS_USER_PREFS_USER_PREFS_EXPORT_H_ +#define COMPONENTS_USER_PREFS_USER_PREFS_EXPORT_H_ + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(USER_PREFS_IMPLEMENTATION) +#define USER_PREFS_EXPORT __declspec(dllexport) +#else +#define USER_PREFS_EXPORT __declspec(dllimport) +#endif // defined(BASE_PREFS_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(USER_PREFS_IMPLEMENTATION) +#define USER_PREFS_EXPORT __attribute__((visibility("default"))) +#else +#define USER_PREFS_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define USER_PREFS_EXPORT +#endif + +#endif // COMPONENTS_USER_PREFS_USER_PREFS_EXPORT_H_ -- cgit v1.1