diff options
author | mnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-23 12:39:01 +0000 |
---|---|---|
committer | mnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-23 12:39:01 +0000 |
commit | f00768e58f44e2343b1ed6c0456a07dad5ec66ed (patch) | |
tree | 16d9a46fc3076e44d4342a6e0f0643bff3b18f28 | |
parent | 7fd3fd82e83460bdc85da8ee4dd5ad06ce8426db (diff) | |
download | chromium_src-f00768e58f44e2343b1ed6c0456a07dad5ec66ed.zip chromium_src-f00768e58f44e2343b1ed6c0456a07dad5ec66ed.tar.gz chromium_src-f00768e58f44e2343b1ed6c0456a07dad5ec66ed.tar.bz2 |
Handle policy refresh internally in ConfigurationPolicyPrefStore.
This removes the final bits of thread-switching madness from PrefValueStore and also makes sure only the PrefStores and PrefService instances that are actually affected by a policy change get reconfigured.
BUG=67715
TEST=unit tests in configuration_policy_provider_unittest.cc
Review URL: http://codereview.chromium.org/6074003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70050 0039d316-1c4b-4281-b951-d872f2087c98
28 files changed, 1124 insertions, 1458 deletions
diff --git a/base/values.cc b/base/values.cc index b06df12..4553e68 100644 --- a/base/values.cc +++ b/base/values.cc @@ -685,114 +685,6 @@ void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) { } } -bool DictionaryValue::GetDifferingPathsHelper( - const std::string& path_prefix, - const DictionaryValue* other, - std::vector<std::string>* different_paths) const { - bool added_path = false; - std::map<std::string, Value*>::const_iterator current_this; - std::map<std::string, Value*>::const_iterator end_this; - current_this = dictionary_.begin(); - end_this = dictionary_.end(); - if (!other) { - // Recursively add all paths from the |this| dictionary, since they are - // not in |other|. - for (; current_this != end_this; ++current_this) { - std::string full_path_for_key(path_prefix.empty() ? current_this->first : - path_prefix + "." + current_this->first); - different_paths->push_back(full_path_for_key); - added_path = true; - if (current_this->second->IsType(Value::TYPE_DICTIONARY)) { - const DictionaryValue* dictionary_this = - static_cast<const DictionaryValue*>(current_this->second); - dictionary_this->GetDifferingPathsHelper(full_path_for_key, - NULL, - different_paths); - } - } - } else { - // Both the |this| and |other| dictionaries have entries. Iterate over - // both simultaneously. Paths that are in one but not the other are - // added to |different_paths| and DictionaryValues are processed - // recursively. - std::map<std::string, Value*>::const_iterator current_other = - other->dictionary_.begin(); - std::map<std::string, Value*>::const_iterator end_other = - other->dictionary_.end(); - while (current_this != end_this || current_other != end_other) { - const Value* recursion_this = NULL; - const Value* recursion_other = NULL; - const std::string* key_name = NULL; - bool current_value_known_equal = false; - if (current_this == end_this || - (current_other != end_other && - (current_other->first < current_this->first))) { - key_name = ¤t_other->first; - if (current_other->second->IsType(Value::TYPE_DICTIONARY)) - recursion_this = current_other->second; - ++current_other; - } else { - key_name = ¤t_this->first; - if (current_other == end_other || - current_this->first < current_other->first) { - if (current_this->second->IsType(Value::TYPE_DICTIONARY)) - recursion_this = current_this->second; - ++current_this; - } else { - DCHECK(current_this->first == current_other->first); - if (current_this->second->IsType(Value::TYPE_DICTIONARY)) { - recursion_this = current_this->second; - if (current_other->second->IsType(Value::TYPE_DICTIONARY)) { - recursion_other = current_other->second; - } - } else { - if (current_other->second->IsType(Value::TYPE_DICTIONARY)) { - recursion_this = current_other->second; - } else { - current_value_known_equal = - current_this->second->Equals(current_other->second); - } - } - ++current_this; - ++current_other; - } - } - const std::string& full_path_for_key(path_prefix.empty() ? - *key_name : path_prefix + "." + *key_name); - if (!current_value_known_equal) - different_paths->push_back(full_path_for_key); - if (recursion_this) { - const DictionaryValue* dictionary_this = - static_cast<const DictionaryValue*>(recursion_this); - bool subtree_changed = dictionary_this->GetDifferingPathsHelper( - full_path_for_key, - static_cast<const DictionaryValue*>(recursion_other), - different_paths); - if (subtree_changed) { - added_path = true; - } else { - // In order to maintain lexicographical sorting order, directory - // paths are pushed "optimistically" assuming that their subtree will - // contain differences. If in retrospect there were no differences - // in the subtree, the assumption was false and the dictionary path - // must be removed. - different_paths->pop_back(); - } - } else { - added_path |= !current_value_known_equal; - } - } - } - return added_path; -} - -void DictionaryValue::GetDifferingPaths( - const DictionaryValue* other, - std::vector<std::string>* different_paths) const { - different_paths->clear(); - GetDifferingPathsHelper("", other, different_paths); -} - ///////////////////// ListValue //////////////////// ListValue::ListValue() : Value(TYPE_LIST) { diff --git a/base/values.h b/base/values.h index 68b8f00..2719d27 100644 --- a/base/values.h +++ b/base/values.h @@ -308,16 +308,6 @@ class DictionaryValue : public Value { // replaced. void MergeDictionary(const DictionaryValue* dictionary); - // Builds a vector containing all of the paths that are different between - // the dictionary and a second specified dictionary. These are paths of - // values that are either in one dictionary or the other but not both, OR - // paths that are present in both dictionaries but differ in value. - // Path strings are in ascending lexicographical order in the generated - // vector. |different_paths| is cleared before added any paths. - void GetDifferingPaths( - const DictionaryValue* other, - std::vector<std::string>* different_paths) const; - // This class provides an iterator for the keys in the dictionary. // It can't be used to modify the dictionary. // @@ -344,17 +334,6 @@ class DictionaryValue : public Value { key_iterator end_keys() const { return key_iterator(dictionary_.end()); } private: - // Does the actual heavy lifting for GetDifferingPaths. - // Returns true if a path is added to different_paths, otherwise false. - // The difference compuation is calculated recursively. The keys for - // dictionaries that are handled by recursive calls more shallow than - // the current one are concatenated and passed through to deeper calls in - // |path_prefix|. - bool GetDifferingPathsHelper( - const std::string& path_prefix, - const DictionaryValue* other, - std::vector<std::string>* different_paths) const; - ValueMap dictionary_; DISALLOW_COPY_AND_ASSIGN(DictionaryValue); diff --git a/base/values_unittest.cc b/base/values_unittest.cc index 13f0f19..adcd07e 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc @@ -10,27 +10,7 @@ #include "base/values.h" #include "testing/gtest/include/gtest/gtest.h" -class ValuesTest: public testing::Test { - protected: - void CompareDictionariesAndCheckResult( - const DictionaryValue* dict1, - const DictionaryValue* dict2, - const char* expected_paths[], - size_t expected_paths_count) { - std::vector<std::string> differing_paths; - std::vector<std::string> expected_paths_vector(expected_paths, - expected_paths+expected_paths_count); - // All comparisons should be commutative, check dict1 against dict2 - // and vice-versa. - dict1->GetDifferingPaths(dict2, &differing_paths); - ASSERT_EQ(expected_paths_count, differing_paths.size()); - EXPECT_TRUE(equal(differing_paths.begin(), differing_paths.end(), - expected_paths_vector.begin())); - dict2->GetDifferingPaths(dict1, &differing_paths); - ASSERT_EQ(expected_paths_count, differing_paths.size()); - EXPECT_TRUE(equal(differing_paths.begin(), differing_paths.end(), - expected_paths_vector.begin())); - } +class ValuesTest : public testing::Test { }; TEST_F(ValuesTest, Basic) { @@ -650,114 +630,3 @@ TEST_F(ValuesTest, MergeDictionary) { EXPECT_TRUE(res_sub_dict->GetString("sub_merge_key", &sub_merge_key_value)); EXPECT_EQ("sub_merge_key_value_merge", sub_merge_key_value); // Merged in. } - -TEST_F(ValuesTest, GetDifferingPaths) { - scoped_ptr<DictionaryValue> dict1(new DictionaryValue()); - scoped_ptr<DictionaryValue> dict2(new DictionaryValue()); - std::vector<std::string> differing_paths; - - // Test comparing empty dictionaries. - dict1->GetDifferingPaths(dict2.get(), &differing_paths); - EXPECT_EQ(differing_paths.size(), 0UL); - - // Compare an empty dictionary with various non-empty dictionaries. - static const char* expected_paths1[] = { - "segment1" - }; - dict1->SetString("segment1", "value1"); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths1, - arraysize(expected_paths1)); - - static const char* expected_paths2[] = { - "segment1", - "segment2", - "segment2.segment3" - }; - dict1->SetString("segment2.segment3", "value2"); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths2, - arraysize(expected_paths2)); - - static const char* expected_paths3[] = { - "segment1", - "segment2", - "segment2.segment3", - "segment4", - "segment4.segment5" - }; - dict1->SetString("segment4.segment5", "value3"); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths3, - arraysize(expected_paths3)); - - // Now various tests with two populated dictionaries. - static const char* expected_paths4[] = { - "segment1", - "segment2", - "segment2.segment3", - "segment4", - "segment4.segment5" - }; - dict2->Set("segment2", new DictionaryValue()); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths4, - arraysize(expected_paths4)); - - static const char* expected_paths5[] = { - "segment1", - "segment4", - "segment4.segment5" - }; - dict2->SetString("segment2.segment3", "value2"); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths5, - arraysize(expected_paths5)); - - dict2->SetBoolean("segment2.segment3", true); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths4, - arraysize(expected_paths4)); - - // Test two identical dictionaries. - dict2.reset(static_cast<DictionaryValue*>(dict1->DeepCopy())); - dict2->GetDifferingPaths(dict1.get(), &differing_paths); - EXPECT_EQ(differing_paths.size(), 0UL); - - // Test a deep dictionary structure. - static const char* expected_paths6[] = { - "s1", - "s1.s2", - "s1.s2.s3", - "s1.s2.s3.s4", - "s1.s2.s3.s4.s5" - }; - dict1.reset(new DictionaryValue()); - dict2.reset(new DictionaryValue()); - dict1->Set("s1.s2.s3.s4.s5", new DictionaryValue()); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths6, - arraysize(expected_paths6)); - - // Make sure disjoint dictionaries generate the right differing path list. - static const char* expected_paths7[] = { - "a", - "b", - "c", - "d" - }; - dict1.reset(new DictionaryValue()); - dict1->SetBoolean("a", true); - dict1->SetBoolean("c", true); - dict2.reset(new DictionaryValue()); - dict1->SetBoolean("b", true); - dict1->SetBoolean("d", true); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths7, - arraysize(expected_paths7)); - - // For code coverage completeness. Make sure that all branches - // that were not covered are executed. - static const char* expected_paths8[] = { - "s1", - "s1.s2" - }; - dict1.reset(new DictionaryValue()); - dict1->Set("s1.s2", new DictionaryValue()); - dict2.reset(new DictionaryValue()); - dict2->SetInteger("s1", 1); - CompareDictionariesAndCheckResult(dict1.get(), dict2.get(), expected_paths8, - arraysize(expected_paths8)); -} diff --git a/chrome/browser/policy/config_dir_policy_provider.cc b/chrome/browser/policy/config_dir_policy_provider.cc index be6f586..fb2f6eb 100644 --- a/chrome/browser/policy/config_dir_policy_provider.cc +++ b/chrome/browser/policy/config_dir_policy_provider.cc @@ -69,7 +69,7 @@ base::Time ConfigDirPolicyProviderDelegate::GetLastModification() { config_file = file_enumerator.Next()) { if (file_util::GetFileInfo(config_file, &file_info) && !file_info.is_directory) { - last_modification = std::min(last_modification, file_info.last_modified); + last_modification = std::max(last_modification, file_info.last_modified); } } diff --git a/chrome/browser/policy/configuration_policy_pref_store.cc b/chrome/browser/policy/configuration_policy_pref_store.cc index 3c7ea6a..7717ac5 100644 --- a/chrome/browser/policy/configuration_policy_pref_store.cc +++ b/chrome/browser/policy/configuration_policy_pref_store.cc @@ -4,6 +4,10 @@ #include "chrome/browser/policy/configuration_policy_pref_store.h" +#include <set> +#include <string> +#include <vector> + #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/logging.h" @@ -13,8 +17,6 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/prefs/proxy_prefs.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/policy/configuration_policy_provider.h" #if defined(OS_WIN) #include "chrome/browser/policy/configuration_policy_provider_win.h" @@ -26,101 +28,137 @@ #include "chrome/browser/policy/device_management_policy_provider.h" #include "chrome/browser/policy/dummy_configuration_policy_provider.h" #include "chrome/browser/policy/profile_policy_context.h" +#include "chrome/browser/prefs/pref_value_map.h" +#include "chrome/browser/prefs/proxy_prefs.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/search_terms_data.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/notification_service.h" #include "chrome/common/policy_constants.h" #include "chrome/common/pref_names.h" namespace policy { -// Manages the lifecycle of the shared platform-specific policy providers for -// managed platform, device management and recommended policy. Instantiated as a -// Singleton. -class ConfigurationPolicyProviderKeeper { +// Accepts policy settings from a ConfigurationPolicyProvider, converts them +// to preferences and caches the result. +class ConfigurationPolicyPrefKeeper + : private ConfigurationPolicyStoreInterface { public: - ConfigurationPolicyProviderKeeper() - : managed_platform_provider_(CreateManagedPlatformProvider()), - device_management_provider_(CreateDeviceManagementProvider()), - recommended_provider_(CreateRecommendedProvider()) {} - virtual ~ConfigurationPolicyProviderKeeper() {} + explicit ConfigurationPolicyPrefKeeper(ConfigurationPolicyProvider* provider); + virtual ~ConfigurationPolicyPrefKeeper(); - ConfigurationPolicyProvider* managed_platform_provider() const { - return managed_platform_provider_.get(); - } - - ConfigurationPolicyProvider* device_management_provider() const { - return device_management_provider_.get(); - } + // Get a preference value. + PrefStore::ReadResult GetValue(const std::string& key, Value** result) const; - ConfigurationPolicyProvider* recommended_provider() const { - return recommended_provider_.get(); - } + // Compute the set of preference names that are different in |keeper|. This + // includes preferences that are missing in either one. + void GetDifferingPrefPaths(const ConfigurationPolicyPrefKeeper* other, + std::vector<std::string>* differing_prefs) const; private: - scoped_ptr<ConfigurationPolicyProvider> managed_platform_provider_; - scoped_ptr<ConfigurationPolicyProvider> device_management_provider_; - scoped_ptr<ConfigurationPolicyProvider> recommended_provider_; - - static ConfigurationPolicyProvider* CreateManagedPlatformProvider(); - static ConfigurationPolicyProvider* CreateDeviceManagementProvider(); - static ConfigurationPolicyProvider* CreateRecommendedProvider(); + // ConfigurationPolicyStore methods: + virtual void Apply(ConfigurationPolicyType setting, Value* value); + + // Policies that map to a single preference are handled + // by an automated converter. Each one of these policies + // has an entry in |simple_policy_map_| with the following type. + struct PolicyToPreferenceMapEntry { + Value::ValueType value_type; + ConfigurationPolicyType policy_type; + const char* preference_path; // A DictionaryValue path, not a file path. + }; - DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProviderKeeper); + typedef std::set<const char*> ProxyPreferenceSet; + + // Returns the map entry that corresponds to |policy| in the map. + const PolicyToPreferenceMapEntry* FindPolicyInMap( + ConfigurationPolicyType policy, + const PolicyToPreferenceMapEntry* map, + int size) const; + + // Remove the preferences found in the map from |prefs_|. Returns true if any + // such preferences were found and removed. + bool RemovePreferencesOfMap(const PolicyToPreferenceMapEntry* map, + int table_size); + + bool ApplyPolicyFromMap(ConfigurationPolicyType policy, + Value* value, + const PolicyToPreferenceMapEntry* map, + int size); + + // Processes proxy-specific policies. Returns true if the specified policy + // is a proxy-related policy. ApplyProxyPolicy assumes the ownership + // of |value| in the case that the policy is proxy-specific. + bool ApplyProxyPolicy(ConfigurationPolicyType policy, Value* value); + + // Handles sync-related policies. Returns true if the policy was handled. + // Assumes ownership of |value| in that case. + bool ApplySyncPolicy(ConfigurationPolicyType policy, Value* value); + + // Handles policies that affect AutoFill. Returns true if the policy was + // handled and assumes ownership of |value| in that case. + bool ApplyAutoFillPolicy(ConfigurationPolicyType policy, Value* value); + + // Make sure that the |path| if present in |prefs_|. If not, set it to + // a blank string. + void EnsureStringPrefExists(const std::string& path); + + // If the required entries for default search are specified and valid, + // finalizes the policy-specified configuration by initializing the + // unspecified map entries. Otherwise wipes all default search related + // map entries from |prefs_|. + void FinalizeDefaultSearchPolicySettings(); + + // If the required entries for the proxy settings are specified and valid, + // finalizes the policy-specified configuration by initializing the + // respective values in |prefs_|. + void FinalizeProxyPolicySettings(); + + // Returns true if the policy values stored in proxy_* represent a valid + // proxy configuration. + bool CheckProxySettings(); + + // Assumes CheckProxySettings returns true and applies the values stored + // in proxy_*. + void ApplyProxySettings(); + + bool HasProxyPolicy(ConfigurationPolicyType policy) const; + + // Temporary cache that stores values until FinalizeProxyPolicySettings() + // is called. + std::map<ConfigurationPolicyType, Value*> proxy_policies_; + + // Set to false until the first proxy-relevant policy is applied. At that + // time, default values are provided for all proxy-relevant prefs + // to override any values set from stores with a lower priority. + bool lower_priority_proxy_settings_overridden_; + + // The following are used to track what proxy-relevant policy has been applied + // accross calls to Apply to provide a warning if a policy specifies a + // contradictory proxy configuration. |proxy_disabled_| is set to true if and + // only if the kPolicyNoProxyServer has been applied, + // |proxy_configuration_specified_| is set to true if and only if any other + // proxy policy other than kPolicyNoProxyServer has been applied. + bool proxy_disabled_; + bool proxy_configuration_specified_; + + // Set to true if a the proxy mode policy has been set to force Chrome + // to use the system proxy. + bool use_system_proxy_; + + PrefValueMap prefs_; + + static const PolicyToPreferenceMapEntry kSimplePolicyMap[]; + static const PolicyToPreferenceMapEntry kProxyPolicyMap[]; + static const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[]; + + DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyPrefKeeper); }; -static base::LazyInstance<ConfigurationPolicyProviderKeeper> - g_configuration_policy_provider_keeper(base::LINKER_INITIALIZED); - -ConfigurationPolicyProvider* - ConfigurationPolicyProviderKeeper::CreateManagedPlatformProvider() { - const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list = - ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); -#if defined(OS_WIN) - return new ConfigurationPolicyProviderWin(policy_list); -#elif defined(OS_MACOSX) - return new ConfigurationPolicyProviderMac(policy_list); -#elif defined(OS_POSIX) - FilePath config_dir_path; - if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) { - return new ConfigDirPolicyProvider( - policy_list, - config_dir_path.Append(FILE_PATH_LITERAL("managed"))); - } else { - return new DummyConfigurationPolicyProvider(policy_list); - } -#else - return new DummyConfigurationPolicyProvider(policy_list); -#endif -} - -ConfigurationPolicyProvider* - ConfigurationPolicyProviderKeeper::CreateDeviceManagementProvider() { - return new DummyConfigurationPolicyProvider( - ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()); -} - -ConfigurationPolicyProvider* - ConfigurationPolicyProviderKeeper::CreateRecommendedProvider() { - const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list = - ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); -#if defined(OS_POSIX) && !defined(OS_MACOSX) - FilePath config_dir_path; - if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) { - return new ConfigDirPolicyProvider( - policy_list, - config_dir_path.Append(FILE_PATH_LITERAL("recommended"))); - } else { - return new DummyConfigurationPolicyProvider(policy_list); - } -#else - return new DummyConfigurationPolicyProvider(policy_list); -#endif -} - -const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry - ConfigurationPolicyPrefStore::kSimplePolicyMap[] = { +const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry + ConfigurationPolicyPrefKeeper::kSimplePolicyMap[] = { { Value::TYPE_STRING, kPolicyHomePage, prefs::kHomePage }, { Value::TYPE_BOOLEAN, kPolicyHomepageIsNewTabPage, prefs::kHomePageIsNewTabPage }, @@ -201,8 +239,8 @@ const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry #endif }; -const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry - ConfigurationPolicyPrefStore::kDefaultSearchPolicyMap[] = { +const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry + ConfigurationPolicyPrefKeeper::kDefaultSearchPolicyMap[] = { { Value::TYPE_BOOLEAN, kPolicyDefaultSearchProviderEnabled, prefs::kDefaultSearchProviderEnabled }, { Value::TYPE_STRING, kPolicyDefaultSearchProviderName, @@ -219,153 +257,53 @@ const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry prefs::kDefaultSearchProviderEncodings }, }; -const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry - ConfigurationPolicyPrefStore::kProxyPolicyMap[] = { +const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry + ConfigurationPolicyPrefKeeper::kProxyPolicyMap[] = { { Value::TYPE_STRING, kPolicyProxyServer, prefs::kProxyServer }, { Value::TYPE_STRING, kPolicyProxyPacUrl, prefs::kProxyPacUrl }, { Value::TYPE_STRING, kPolicyProxyBypassList, prefs::kProxyBypassList } }; -/* static */ -const ConfigurationPolicyProvider::PolicyDefinitionList* -ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() { - static ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[] = { - { kPolicyHomePage, Value::TYPE_STRING, key::kHomepageLocation }, - { kPolicyHomepageIsNewTabPage, Value::TYPE_BOOLEAN, - key::kHomepageIsNewTabPage }, - { kPolicyRestoreOnStartup, Value::TYPE_INTEGER, key::kRestoreOnStartup }, - { kPolicyURLsToRestoreOnStartup, Value::TYPE_LIST, - key::kURLsToRestoreOnStartup }, - { kPolicyDefaultSearchProviderEnabled, Value::TYPE_BOOLEAN, - key::kDefaultSearchProviderEnabled }, - { kPolicyDefaultSearchProviderName, Value::TYPE_STRING, - key::kDefaultSearchProviderName }, - { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING, - key::kDefaultSearchProviderKeyword }, - { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING, - key::kDefaultSearchProviderSearchURL }, - { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING, - key::kDefaultSearchProviderSuggestURL }, - { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING, - key::kDefaultSearchProviderIconURL }, - { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING, - key::kDefaultSearchProviderEncodings }, - { kPolicyProxyMode, Value::TYPE_INTEGER, key::kProxyMode }, - { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer }, - { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl }, - { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList }, - { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN, - key::kAlternateErrorPagesEnabled }, - { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN, - key::kSearchSuggestEnabled }, - { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN, - key::kDnsPrefetchingEnabled }, - { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy }, - { kPolicySafeBrowsingEnabled, Value::TYPE_BOOLEAN, - key::kSafeBrowsingEnabled }, - { kPolicyMetricsReportingEnabled, Value::TYPE_BOOLEAN, - key::kMetricsReportingEnabled }, - { kPolicyPasswordManagerEnabled, Value::TYPE_BOOLEAN, - key::kPasswordManagerEnabled }, - { kPolicyPasswordManagerAllowShowPasswords, Value::TYPE_BOOLEAN, - key::kPasswordManagerAllowShowPasswords }, - { kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled }, - { kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins }, - { kPolicyApplicationLocale, Value::TYPE_STRING, - key::kApplicationLocaleValue }, - { kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled }, - { kPolicyExtensionInstallAllowList, Value::TYPE_LIST, - key::kExtensionInstallAllowList }, - { kPolicyExtensionInstallDenyList, Value::TYPE_LIST, - key::kExtensionInstallDenyList }, - { kPolicyExtensionInstallForceList, Value::TYPE_LIST, - key::kExtensionInstallForceList }, - { kPolicyShowHomeButton, Value::TYPE_BOOLEAN, key::kShowHomeButton }, - { kPolicyPrintingEnabled, Value::TYPE_BOOLEAN, key::kPrintingEnabled }, - { kPolicyJavascriptEnabled, Value::TYPE_BOOLEAN, key::kJavascriptEnabled }, - { kPolicySavingBrowserHistoryDisabled, Value::TYPE_BOOLEAN, - key::kSavingBrowserHistoryDisabled }, - { kPolicyDeveloperToolsDisabled, Value::TYPE_BOOLEAN, - key::kDeveloperToolsDisabled }, - { kPolicyBlockThirdPartyCookies, Value::TYPE_BOOLEAN, - key::kBlockThirdPartyCookies }, - { kPolicyDefaultCookiesSetting, Value::TYPE_INTEGER, - key::kDefaultCookiesSetting }, - { kPolicyDefaultImagesSetting, Value::TYPE_INTEGER, - key::kDefaultImagesSetting }, - { kPolicyDefaultJavaScriptSetting, Value::TYPE_INTEGER, - key::kDefaultJavaScriptSetting }, - { kPolicyDefaultPluginsSetting, Value::TYPE_INTEGER, - key::kDefaultPluginsSetting }, - { kPolicyDefaultPopupsSetting, Value::TYPE_INTEGER, - key::kDefaultPopupsSetting }, - { kPolicyDefaultNotificationSetting, Value::TYPE_INTEGER, - key::kDefaultNotificationSetting }, - { kPolicyDefaultGeolocationSetting, Value::TYPE_INTEGER, - key::kDefaultGeolocationSetting }, - { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes }, - { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN, - key::kDisableAuthNegotiateCnameLookup }, - { kPolicyEnableAuthNegotiatePort, Value::TYPE_BOOLEAN, - key::kEnableAuthNegotiatePort }, - { kPolicyAuthServerWhitelist, Value::TYPE_STRING, - key::kAuthServerWhitelist }, - { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING, - key::kAuthNegotiateDelegateWhitelist }, - { kPolicyGSSAPILibraryName, Value::TYPE_STRING, - key::kGSSAPILibraryName }, - { kPolicyDisable3DAPIs, Value::TYPE_BOOLEAN, - key::kDisable3DAPIs }, - -#if defined(OS_CHROMEOS) - { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN, - key::kChromeOsLockOnIdleSuspend }, -#endif - }; - - static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = { - entries, - entries + arraysize(entries), - }; - return &policy_list; -} - -ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( +ConfigurationPolicyPrefKeeper::ConfigurationPolicyPrefKeeper( ConfigurationPolicyProvider* provider) - : provider_(provider), - prefs_(new DictionaryValue()) { - if (!provider_->Provide(this)) + : lower_priority_proxy_settings_overridden_(false), + proxy_disabled_(false), + proxy_configuration_specified_(false), + use_system_proxy_(false) { + if (!provider->Provide(this)) LOG(WARNING) << "Failed to get policy from provider."; FinalizeProxyPolicySettings(); FinalizeDefaultSearchPolicySettings(); } -ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() { +ConfigurationPolicyPrefKeeper::~ConfigurationPolicyPrefKeeper() { DCHECK(proxy_policies_.empty()); } -PrefStore::ReadResult ConfigurationPolicyPrefStore::GetValue( - const std::string& key, - Value** value) const { - Value* configured_value = NULL; - if (!prefs_->Get(key, &configured_value) || !configured_value) - return READ_NO_VALUE; +PrefStore::ReadResult +ConfigurationPolicyPrefKeeper::GetValue(const std::string& key, + Value** result) const { + Value* stored_value = NULL; + if (!prefs_.GetValue(key, &stored_value)) + return PrefStore::READ_NO_VALUE; // Check whether there's a default value, which indicates READ_USE_DEFAULT // should be returned. - if (configured_value->IsType(Value::TYPE_NULL)) - return READ_USE_DEFAULT; + if (stored_value->IsType(Value::TYPE_NULL)) + return PrefStore::READ_USE_DEFAULT; - *value = configured_value; - return READ_OK; + *result = stored_value; + return PrefStore::READ_OK; } -DictionaryValue* ConfigurationPolicyPrefStore::prefs() const { - return prefs_.get(); +void ConfigurationPolicyPrefKeeper::GetDifferingPrefPaths( + const ConfigurationPolicyPrefKeeper* other, + std::vector<std::string>* differing_prefs) const { + prefs_.GetDifferingKeys(&other->prefs_, differing_prefs); } -void ConfigurationPolicyPrefStore::Apply(ConfigurationPolicyType policy, - Value* value) { +void ConfigurationPolicyPrefKeeper::Apply(ConfigurationPolicyType policy, + Value* value) { if (ApplyProxyPolicy(policy, value)) return; @@ -388,36 +326,8 @@ void ConfigurationPolicyPrefStore::Apply(ConfigurationPolicyType policy, delete value; } -// static -ConfigurationPolicyPrefStore* -ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore() { - return new ConfigurationPolicyPrefStore( - g_configuration_policy_provider_keeper.Get().managed_platform_provider()); -} - -// static -ConfigurationPolicyPrefStore* -ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( - Profile* profile) { - ConfigurationPolicyProviderKeeper* keeper = - g_configuration_policy_provider_keeper.Pointer(); - ConfigurationPolicyProvider* provider = NULL; - if (profile) - provider = profile->GetPolicyContext()->GetDeviceManagementPolicyProvider(); - if (!provider) - provider = keeper->device_management_provider(); - return new ConfigurationPolicyPrefStore(provider); -} - -// static -ConfigurationPolicyPrefStore* -ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() { - return new ConfigurationPolicyPrefStore( - g_configuration_policy_provider_keeper.Get().recommended_provider()); -} - -const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry* -ConfigurationPolicyPrefStore::FindPolicyInMap( +const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry* +ConfigurationPolicyPrefKeeper::FindPolicyInMap( ConfigurationPolicyType policy, const PolicyToPreferenceMapEntry* map, int table_size) const { @@ -428,17 +338,17 @@ ConfigurationPolicyPrefStore::FindPolicyInMap( return NULL; } -bool ConfigurationPolicyPrefStore::RemovePreferencesOfMap( +bool ConfigurationPolicyPrefKeeper::RemovePreferencesOfMap( const PolicyToPreferenceMapEntry* map, int table_size) { bool found_any = false; for (int i = 0; i < table_size; ++i) { - if (prefs_->Remove(map[i].preference_path, NULL)) + if (prefs_.RemoveValue(map[i].preference_path)) found_any = true; } return found_any; } -bool ConfigurationPolicyPrefStore::ApplyPolicyFromMap( +bool ConfigurationPolicyPrefKeeper::ApplyPolicyFromMap( ConfigurationPolicyType policy, Value* value, const PolicyToPreferenceMapEntry* map, @@ -449,14 +359,14 @@ bool ConfigurationPolicyPrefStore::ApplyPolicyFromMap( << "mismatch in provided and expected policy value for preferences" << map[current].preference_path << ". expected = " << map[current].value_type << ", actual = "<< value->GetType(); - prefs_->Set(map[current].preference_path, value); + prefs_.SetValue(map[current].preference_path, value); return true; } } return false; } -bool ConfigurationPolicyPrefStore::ApplyProxyPolicy( +bool ConfigurationPolicyPrefKeeper::ApplyProxyPolicy( ConfigurationPolicyType policy, Value* value) { // We only collect the values until we have sufficient information when @@ -474,7 +384,112 @@ bool ConfigurationPolicyPrefStore::ApplyProxyPolicy( return false; } -void ConfigurationPolicyPrefStore::FinalizeProxyPolicySettings() { +bool ConfigurationPolicyPrefKeeper::ApplySyncPolicy( + ConfigurationPolicyType policy, Value* value) { + if (policy == kPolicySyncDisabled) { + bool disable_sync; + if (value->GetAsBoolean(&disable_sync) && disable_sync) + prefs_.SetValue(prefs::kSyncManaged, value); + else + delete value; + return true; + } + return false; +} + +bool ConfigurationPolicyPrefKeeper::ApplyAutoFillPolicy( + ConfigurationPolicyType policy, Value* value) { + if (policy == kPolicyAutoFillEnabled) { + bool auto_fill_enabled; + if (value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled) + prefs_.SetValue(prefs::kAutoFillEnabled, + Value::CreateBooleanValue(false)); + delete value; + return true; + } + return false; +} + +void ConfigurationPolicyPrefKeeper::EnsureStringPrefExists( + const std::string& path) { + std::string value; + if (!prefs_.GetString(path, &value)) + prefs_.SetString(path, value); +} + +namespace { + +// Implementation of SearchTermsData just for validation. +class SearchTermsDataForValidation : public SearchTermsData { + public: + SearchTermsDataForValidation() {} + + // Implementation of SearchTermsData. + virtual std::string GoogleBaseURLValue() const { + return "http://www.google.com/"; + } + virtual std::string GetApplicationLocale() const { + return "en"; + } +#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) + virtual std::wstring GetRlzParameterValue() const { + return std::wstring(); + } +#endif + private: + DISALLOW_COPY_AND_ASSIGN(SearchTermsDataForValidation); +}; + +} // namepsace + +void ConfigurationPolicyPrefKeeper::FinalizeDefaultSearchPolicySettings() { + bool enabled = true; + if (prefs_.GetBoolean(prefs::kDefaultSearchProviderEnabled, &enabled) && + !enabled) { + // If default search is disabled, we ignore the other fields. + prefs_.SetString(prefs::kDefaultSearchProviderName, std::string()); + prefs_.SetString(prefs::kDefaultSearchProviderSearchURL, std::string()); + prefs_.SetString(prefs::kDefaultSearchProviderSuggestURL, std::string()); + prefs_.SetString(prefs::kDefaultSearchProviderIconURL, std::string()); + prefs_.SetString(prefs::kDefaultSearchProviderEncodings, std::string()); + prefs_.SetString(prefs::kDefaultSearchProviderKeyword, std::string()); + return; + } + std::string search_url; + // The search URL is required. + if (prefs_.GetString(prefs::kDefaultSearchProviderSearchURL, &search_url) && + !search_url.empty()) { + SearchTermsDataForValidation search_terms_data; + const TemplateURLRef search_url_ref(search_url, 0, 0); + // It must support replacement (which implies it is valid). + if (search_url_ref.SupportsReplacementUsingTermsData(search_terms_data)) { + // The other entries are optional. Just make sure that they are all + // specified via policy, so that we don't use regular prefs. + EnsureStringPrefExists(prefs::kDefaultSearchProviderSuggestURL); + EnsureStringPrefExists(prefs::kDefaultSearchProviderIconURL); + EnsureStringPrefExists(prefs::kDefaultSearchProviderEncodings); + EnsureStringPrefExists(prefs::kDefaultSearchProviderKeyword); + + // For the name, default to the host if not specified. + std::string name; + if (!prefs_.GetString(prefs::kDefaultSearchProviderName, &name) || + name.empty()) + prefs_.SetString(prefs::kDefaultSearchProviderName, + GURL(search_url).host()); + + // And clear the IDs since these are not specified via policy. + prefs_.SetString(prefs::kDefaultSearchProviderID, std::string()); + prefs_.SetString(prefs::kDefaultSearchProviderPrepopulateID, + std::string()); + return; + } + } + // Required entries are not there. Remove any related entries. + RemovePreferencesOfMap(kDefaultSearchPolicyMap, + arraysize(kDefaultSearchPolicyMap)); +} + +void ConfigurationPolicyPrefKeeper::FinalizeProxyPolicySettings() { if (CheckProxySettings()) ApplyProxySettings(); @@ -483,15 +498,7 @@ void ConfigurationPolicyPrefStore::FinalizeProxyPolicySettings() { proxy_policies_.clear(); } -bool ConfigurationPolicyPrefStore::HasProxyPolicy( - ConfigurationPolicyType policy) const { - std::map<ConfigurationPolicyType, Value*>::const_iterator iter; - iter = proxy_policies_.find(policy); - return iter != proxy_policies_.end() && - iter->second && !iter->second->IsType(Value::TYPE_NULL); -} - -bool ConfigurationPolicyPrefStore::CheckProxySettings() { +bool ConfigurationPolicyPrefKeeper::CheckProxySettings() { bool mode = HasProxyPolicy(kPolicyProxyMode); bool server = HasProxyPolicy(kPolicyProxyServer); bool pac_url = HasProxyPolicy(kPolicyProxyPacUrl); @@ -558,7 +565,7 @@ bool ConfigurationPolicyPrefStore::CheckProxySettings() { return true; } -void ConfigurationPolicyPrefStore::ApplyProxySettings() { +void ConfigurationPolicyPrefKeeper::ApplyProxySettings() { if (!HasProxyPolicy(kPolicyProxyMode)) return; @@ -584,131 +591,322 @@ void ConfigurationPolicyPrefStore::ApplyProxySettings() { mode = ProxyPrefs::MODE_DIRECT; NOTREACHED(); } - prefs_->Set(prefs::kProxyMode, Value::CreateIntegerValue(mode)); + prefs_.SetValue(prefs::kProxyMode, Value::CreateIntegerValue(mode)); if (HasProxyPolicy(kPolicyProxyServer)) { - prefs_->Set(prefs::kProxyServer, proxy_policies_[kPolicyProxyServer]); + prefs_.SetValue(prefs::kProxyServer, proxy_policies_[kPolicyProxyServer]); proxy_policies_[kPolicyProxyServer] = NULL; } else { - prefs_->Set(prefs::kProxyServer, Value::CreateNullValue()); + prefs_.SetValue(prefs::kProxyServer, Value::CreateNullValue()); } if (HasProxyPolicy(kPolicyProxyPacUrl)) { - prefs_->Set(prefs::kProxyPacUrl, proxy_policies_[kPolicyProxyPacUrl]); + prefs_.SetValue(prefs::kProxyPacUrl, proxy_policies_[kPolicyProxyPacUrl]); proxy_policies_[kPolicyProxyPacUrl] = NULL; } else { - prefs_->Set(prefs::kProxyPacUrl, Value::CreateNullValue()); + prefs_.SetValue(prefs::kProxyPacUrl, Value::CreateNullValue()); } if (HasProxyPolicy(kPolicyProxyBypassList)) { - prefs_->Set(prefs::kProxyBypassList, + prefs_.SetValue(prefs::kProxyBypassList, proxy_policies_[kPolicyProxyBypassList]); proxy_policies_[kPolicyProxyBypassList] = NULL; } else { - prefs_->Set(prefs::kProxyBypassList, Value::CreateNullValue()); - } -} - -bool ConfigurationPolicyPrefStore::ApplySyncPolicy( - ConfigurationPolicyType policy, Value* value) { - if (policy == kPolicySyncDisabled) { - bool disable_sync; - if (value->GetAsBoolean(&disable_sync) && disable_sync) - prefs_->Set(prefs::kSyncManaged, value); - else - delete value; - return true; - } - return false; -} - -bool ConfigurationPolicyPrefStore::ApplyAutoFillPolicy( - ConfigurationPolicyType policy, Value* value) { - if (policy == kPolicyAutoFillEnabled) { - bool auto_fill_enabled; - if (value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled) - prefs_->Set(prefs::kAutoFillEnabled, Value::CreateBooleanValue(false)); - delete value; - return true; + prefs_.SetValue(prefs::kProxyBypassList, Value::CreateNullValue()); } - return false; } -void ConfigurationPolicyPrefStore::EnsureStringPrefExists( - const std::string& path) { - std::string value; - if (!prefs_->GetString(path, &value)) - prefs_->SetString(path, value); +bool ConfigurationPolicyPrefKeeper::HasProxyPolicy( + ConfigurationPolicyType policy) const { + std::map<ConfigurationPolicyType, Value*>::const_iterator iter; + iter = proxy_policies_.find(policy); + return iter != proxy_policies_.end() && + iter->second && !iter->second->IsType(Value::TYPE_NULL); } namespace { -// Implementation of SearchTermsData just for validation. -class SearchTermsDataForValidation : public SearchTermsData { +// Manages the lifecycle of the shared platform-specific policy providers for +// managed platform, device management and recommended policy. Instantiated as a +// Singleton. +class ConfigurationPolicyProviderKeeper { public: - SearchTermsDataForValidation() {} + ConfigurationPolicyProviderKeeper() + : managed_platform_provider_(CreateManagedPlatformProvider()), + device_management_provider_(CreateDeviceManagementProvider()), + recommended_provider_(CreateRecommendedProvider()) {} + virtual ~ConfigurationPolicyProviderKeeper() {} - // Implementation of SearchTermsData. - virtual std::string GoogleBaseURLValue() const { - return "http://www.google.com/"; + ConfigurationPolicyProvider* managed_platform_provider() const { + return managed_platform_provider_.get(); } - virtual std::string GetApplicationLocale() const { - return "en"; + + ConfigurationPolicyProvider* device_management_provider() const { + return device_management_provider_.get(); } -#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) - virtual std::wstring GetRlzParameterValue() const { - return std::wstring(); + + ConfigurationPolicyProvider* recommended_provider() const { + return recommended_provider_.get(); } -#endif + private: - DISALLOW_COPY_AND_ASSIGN(SearchTermsDataForValidation); + scoped_ptr<ConfigurationPolicyProvider> managed_platform_provider_; + scoped_ptr<ConfigurationPolicyProvider> device_management_provider_; + scoped_ptr<ConfigurationPolicyProvider> recommended_provider_; + + static ConfigurationPolicyProvider* CreateManagedPlatformProvider(); + static ConfigurationPolicyProvider* CreateDeviceManagementProvider(); + static ConfigurationPolicyProvider* CreateRecommendedProvider(); + + DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProviderKeeper); }; -} // namepsace +static base::LazyInstance<ConfigurationPolicyProviderKeeper> + g_configuration_policy_provider_keeper(base::LINKER_INITIALIZED); -void ConfigurationPolicyPrefStore::FinalizeDefaultSearchPolicySettings() { - bool enabled = true; - if (prefs_->GetBoolean(prefs::kDefaultSearchProviderEnabled, &enabled) && - !enabled) { - // If default search is disabled, we ignore the other fields. - prefs_->SetString(prefs::kDefaultSearchProviderName, std::string()); - prefs_->SetString(prefs::kDefaultSearchProviderSearchURL, std::string()); - prefs_->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string()); - prefs_->SetString(prefs::kDefaultSearchProviderIconURL, std::string()); - prefs_->SetString(prefs::kDefaultSearchProviderEncodings, std::string()); - prefs_->SetString(prefs::kDefaultSearchProviderKeyword, std::string()); - return; +ConfigurationPolicyProvider* +ConfigurationPolicyProviderKeeper::CreateManagedPlatformProvider() { + const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list = + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); +#if defined(OS_WIN) + return new ConfigurationPolicyProviderWin(policy_list); +#elif defined(OS_MACOSX) + return new ConfigurationPolicyProviderMac(policy_list); +#elif defined(OS_POSIX) + FilePath config_dir_path; + if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) { + return new ConfigDirPolicyProvider( + policy_list, + config_dir_path.Append(FILE_PATH_LITERAL("managed"))); + } else { + return new DummyConfigurationPolicyProvider(policy_list); } - std::string search_url; - // The search URL is required. - if (prefs_->GetString(prefs::kDefaultSearchProviderSearchURL, &search_url) && - !search_url.empty()) { - SearchTermsDataForValidation search_terms_data; - const TemplateURLRef search_url_ref(search_url, 0, 0); - // It must support replacement (which implies it is valid). - if (search_url_ref.SupportsReplacementUsingTermsData(search_terms_data)) { - // The other entries are optional. Just make sure that they are all - // specified via policy, so that we don't use regular prefs. - EnsureStringPrefExists(prefs::kDefaultSearchProviderSuggestURL); - EnsureStringPrefExists(prefs::kDefaultSearchProviderIconURL); - EnsureStringPrefExists(prefs::kDefaultSearchProviderEncodings); - EnsureStringPrefExists(prefs::kDefaultSearchProviderKeyword); +#else + return new DummyConfigurationPolicyProvider(policy_list); +#endif +} - // For the name, default to the host if not specified. - std::string name; - if (!prefs_->GetString(prefs::kDefaultSearchProviderName, &name) || - name.empty()) - prefs_->SetString(prefs::kDefaultSearchProviderName, - GURL(search_url).host()); +ConfigurationPolicyProvider* +ConfigurationPolicyProviderKeeper::CreateDeviceManagementProvider() { + return new DummyConfigurationPolicyProvider( + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()); +} - // And clear the IDs since these are not specified via policy. - prefs_->SetString(prefs::kDefaultSearchProviderID, std::string()); - prefs_->SetString(prefs::kDefaultSearchProviderPrepopulateID, - std::string()); - return; - } +ConfigurationPolicyProvider* +ConfigurationPolicyProviderKeeper::CreateRecommendedProvider() { + const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list = + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); +#if defined(OS_POSIX) && !defined(OS_MACOSX) + FilePath config_dir_path; + if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) { + return new ConfigDirPolicyProvider( + policy_list, + config_dir_path.Append(FILE_PATH_LITERAL("recommended"))); + } else { + return new DummyConfigurationPolicyProvider(policy_list); + } +#else + return new DummyConfigurationPolicyProvider(policy_list); +#endif +} + +} + +ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( + ConfigurationPolicyProvider* provider) + : provider_(provider), + initialization_complete_(provider->IsInitializationComplete()) { + // Read initial policy. + policy_keeper_.reset(new ConfigurationPolicyPrefKeeper(provider)); + + // TODO(mnissler): Remove after provider has proper observer interface. + registrar_.Add(this, + NotificationType(NotificationType::POLICY_CHANGED), + NotificationService::AllSources()); +} + +ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() { +} + +void ConfigurationPolicyPrefStore::AddObserver(PrefStore::Observer* observer) { + observers_.AddObserver(observer); +} + +void ConfigurationPolicyPrefStore::RemoveObserver( + PrefStore::Observer* observer) { + observers_.RemoveObserver(observer); +} + +bool ConfigurationPolicyPrefStore::IsInitializationComplete() const { + return initialization_complete_; +} + +PrefStore::ReadResult +ConfigurationPolicyPrefStore::GetValue(const std::string& key, + Value** value) const { + return policy_keeper_->GetValue(key, value); +} + +// static +ConfigurationPolicyPrefStore* +ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore() { + return new ConfigurationPolicyPrefStore( + g_configuration_policy_provider_keeper.Get().managed_platform_provider()); +} + +// static +ConfigurationPolicyPrefStore* +ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( + Profile* profile) { + ConfigurationPolicyProviderKeeper* keeper = + g_configuration_policy_provider_keeper.Pointer(); + ConfigurationPolicyProvider* provider = NULL; + if (profile) + provider = profile->GetPolicyContext()->GetDeviceManagementPolicyProvider(); + if (!provider) + provider = keeper->device_management_provider(); + return new ConfigurationPolicyPrefStore(provider); +} + +// static +ConfigurationPolicyPrefStore* +ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() { + return new ConfigurationPolicyPrefStore( + g_configuration_policy_provider_keeper.Get().recommended_provider()); +} + +/* static */ +const ConfigurationPolicyProvider::PolicyDefinitionList* +ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() { + static ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[] = { + { kPolicyHomePage, Value::TYPE_STRING, key::kHomepageLocation }, + { kPolicyHomepageIsNewTabPage, Value::TYPE_BOOLEAN, + key::kHomepageIsNewTabPage }, + { kPolicyRestoreOnStartup, Value::TYPE_INTEGER, key::kRestoreOnStartup }, + { kPolicyURLsToRestoreOnStartup, Value::TYPE_LIST, + key::kURLsToRestoreOnStartup }, + { kPolicyDefaultSearchProviderEnabled, Value::TYPE_BOOLEAN, + key::kDefaultSearchProviderEnabled }, + { kPolicyDefaultSearchProviderName, Value::TYPE_STRING, + key::kDefaultSearchProviderName }, + { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING, + key::kDefaultSearchProviderKeyword }, + { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING, + key::kDefaultSearchProviderSearchURL }, + { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING, + key::kDefaultSearchProviderSuggestURL }, + { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING, + key::kDefaultSearchProviderIconURL }, + { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING, + key::kDefaultSearchProviderEncodings }, + { kPolicyProxyMode, Value::TYPE_INTEGER, key::kProxyMode }, + { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer }, + { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl }, + { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList }, + { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN, + key::kAlternateErrorPagesEnabled }, + { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN, + key::kSearchSuggestEnabled }, + { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN, + key::kDnsPrefetchingEnabled }, + { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy }, + { kPolicySafeBrowsingEnabled, Value::TYPE_BOOLEAN, + key::kSafeBrowsingEnabled }, + { kPolicyMetricsReportingEnabled, Value::TYPE_BOOLEAN, + key::kMetricsReportingEnabled }, + { kPolicyPasswordManagerEnabled, Value::TYPE_BOOLEAN, + key::kPasswordManagerEnabled }, + { kPolicyPasswordManagerAllowShowPasswords, Value::TYPE_BOOLEAN, + key::kPasswordManagerAllowShowPasswords }, + { kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled }, + { kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins }, + { kPolicyApplicationLocale, Value::TYPE_STRING, + key::kApplicationLocaleValue }, + { kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled }, + { kPolicyExtensionInstallAllowList, Value::TYPE_LIST, + key::kExtensionInstallAllowList }, + { kPolicyExtensionInstallDenyList, Value::TYPE_LIST, + key::kExtensionInstallDenyList }, + { kPolicyExtensionInstallForceList, Value::TYPE_LIST, + key::kExtensionInstallForceList }, + { kPolicyShowHomeButton, Value::TYPE_BOOLEAN, key::kShowHomeButton }, + { kPolicyPrintingEnabled, Value::TYPE_BOOLEAN, key::kPrintingEnabled }, + { kPolicyJavascriptEnabled, Value::TYPE_BOOLEAN, key::kJavascriptEnabled }, + { kPolicySavingBrowserHistoryDisabled, Value::TYPE_BOOLEAN, + key::kSavingBrowserHistoryDisabled }, + { kPolicyDeveloperToolsDisabled, Value::TYPE_BOOLEAN, + key::kDeveloperToolsDisabled }, + { kPolicyBlockThirdPartyCookies, Value::TYPE_BOOLEAN, + key::kBlockThirdPartyCookies }, + { kPolicyDefaultCookiesSetting, Value::TYPE_INTEGER, + key::kDefaultCookiesSetting }, + { kPolicyDefaultImagesSetting, Value::TYPE_INTEGER, + key::kDefaultImagesSetting }, + { kPolicyDefaultJavaScriptSetting, Value::TYPE_INTEGER, + key::kDefaultJavaScriptSetting }, + { kPolicyDefaultPluginsSetting, Value::TYPE_INTEGER, + key::kDefaultPluginsSetting }, + { kPolicyDefaultPopupsSetting, Value::TYPE_INTEGER, + key::kDefaultPopupsSetting }, + { kPolicyDefaultNotificationSetting, Value::TYPE_INTEGER, + key::kDefaultNotificationSetting }, + { kPolicyDefaultGeolocationSetting, Value::TYPE_INTEGER, + key::kDefaultGeolocationSetting }, + { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes }, + { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN, + key::kDisableAuthNegotiateCnameLookup }, + { kPolicyEnableAuthNegotiatePort, Value::TYPE_BOOLEAN, + key::kEnableAuthNegotiatePort }, + { kPolicyAuthServerWhitelist, Value::TYPE_STRING, + key::kAuthServerWhitelist }, + { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING, + key::kAuthNegotiateDelegateWhitelist }, + { kPolicyGSSAPILibraryName, Value::TYPE_STRING, + key::kGSSAPILibraryName }, + { kPolicyDisable3DAPIs, Value::TYPE_BOOLEAN, + key::kDisable3DAPIs }, + +#if defined(OS_CHROMEOS) + { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN, + key::kChromeOsLockOnIdleSuspend }, +#endif + }; + + static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = { + entries, + entries + arraysize(entries), + }; + return &policy_list; +} + +void ConfigurationPolicyPrefStore::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::POLICY_CHANGED) + Refresh(); +} + +void ConfigurationPolicyPrefStore::Refresh() { + // Construct a new keeper, determine what changed and swap the keeper in. + scoped_ptr<ConfigurationPolicyPrefKeeper> new_keeper( + new ConfigurationPolicyPrefKeeper(provider_)); + std::vector<std::string> changed_prefs; + new_keeper->GetDifferingPrefPaths(policy_keeper_.get(), &changed_prefs); + policy_keeper_.reset(new_keeper.release()); + + // Send out change notifications. + for (std::vector<std::string>::const_iterator pref(changed_prefs.begin()); + pref != changed_prefs.end(); + ++pref) { + FOR_EACH_OBSERVER(PrefStore::Observer, observers_, + OnPrefValueChanged(*pref)); + } + + // Update the initialization flag. + if (!initialization_complete_ && + provider_->IsInitializationComplete()) { + initialization_complete_ = true; + FOR_EACH_OBSERVER(PrefStore::Observer, observers_, + OnInitializationCompleted()); } - // Required entries are not there. Remove any related entries. - RemovePreferencesOfMap(kDefaultSearchPolicyMap, - arraysize(kDefaultSearchPolicyMap)); } } // namespace policy diff --git a/chrome/browser/policy/configuration_policy_pref_store.h b/chrome/browser/policy/configuration_policy_pref_store.h index 6d0ae15..26ba190 100644 --- a/chrome/browser/policy/configuration_policy_pref_store.h +++ b/chrome/browser/policy/configuration_policy_pref_store.h @@ -10,37 +10,37 @@ #include <string> #include "base/basictypes.h" -#include "base/gtest_prod_util.h" +#include "base/observer_list.h" #include "base/scoped_ptr.h" #include "base/values.h" #include "chrome/browser/policy/configuration_policy_provider.h" #include "chrome/browser/policy/configuration_policy_store_interface.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" #include "chrome/common/pref_store.h" class Profile; namespace policy { -// An implementation of the |PrefStore| that holds a Dictionary -// created through applied policy. +class ConfigurationPolicyPrefKeeper; + +// An implementation of PrefStore that bridges policy settings as read from a +// ConfigurationPolicyProvider to preferences. class ConfigurationPolicyPrefStore : public PrefStore, - public ConfigurationPolicyStoreInterface { + public NotificationObserver { public: - typedef std::set<const char*> ProxyPreferenceSet; - // The ConfigurationPolicyPrefStore does not take ownership of the // passed-in |provider|. explicit ConfigurationPolicyPrefStore(ConfigurationPolicyProvider* provider); virtual ~ConfigurationPolicyPrefStore(); // PrefStore methods: + virtual void AddObserver(Observer* observer); + virtual void RemoveObserver(Observer* observer); + virtual bool IsInitializationComplete() const; virtual ReadResult GetValue(const std::string& key, Value** result) const; - virtual DictionaryValue* prefs() const; - - // ConfigurationPolicyStore methods: - virtual void Apply(ConfigurationPolicyType setting, Value* value); - // Creates a ConfigurationPolicyPrefStore that reads managed platform policy. static ConfigurationPolicyPrefStore* CreateManagedPlatformPolicyPrefStore(); @@ -57,81 +57,33 @@ class ConfigurationPolicyPrefStore : public PrefStore, GetChromePolicyDefinitionList(); private: - // Policies that map to a single preference are handled - // by an automated converter. Each one of these policies - // has an entry in |simple_policy_map_| with the following type. - struct PolicyToPreferenceMapEntry { - Value::ValueType value_type; - ConfigurationPolicyType policy_type; - const char* preference_path; // A DictionaryValue path, not a file path. - }; - - static const PolicyToPreferenceMapEntry kSimplePolicyMap[]; - static const PolicyToPreferenceMapEntry kProxyPolicyMap[]; - static const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[]; + // TODO(mnissler): Remove after provider has proper observer interface. + // NotificationObserver overrides: + void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Refreshes policy information, rereading policy from the provider and + // sending out change notifications as appropriate. + void Refresh(); + static const ConfigurationPolicyProvider::PolicyDefinitionList kPolicyDefinitionList; + // The policy provider from which policy settings are read. ConfigurationPolicyProvider* provider_; - scoped_ptr<DictionaryValue> prefs_; - - // Temporary cache that stores values until FinalizeProxyPolicySettings() - // is called. - std::map<ConfigurationPolicyType, Value*> proxy_policies_; - - bool HasProxyPolicy(ConfigurationPolicyType policy) const; - - // Returns the map entry that corresponds to |policy| in the map. - const PolicyToPreferenceMapEntry* FindPolicyInMap( - ConfigurationPolicyType policy, - const PolicyToPreferenceMapEntry* map, - int size) const; - - // Remove the preferences found in the map from |prefs_|. Returns true if - // any such preferences were found and removed. - bool RemovePreferencesOfMap(const PolicyToPreferenceMapEntry* map, - int table_size); - - bool ApplyPolicyFromMap(ConfigurationPolicyType policy, - Value* value, - const PolicyToPreferenceMapEntry* map, - int size); - - // Processes proxy-specific policies. Returns true if the specified policy - // is a proxy-related policy. ApplyProxyPolicy assumes the ownership - // of |value| in the case that the policy is proxy-specific. - bool ApplyProxyPolicy(ConfigurationPolicyType policy, Value* value); - - // Handles sync-related policies. Returns true if the policy was handled. - // Assumes ownership of |value| in that case. - bool ApplySyncPolicy(ConfigurationPolicyType policy, Value* value); - - // Handles policies that affect AutoFill. Returns true if the policy was - // handled and assumes ownership of |value| in that case. - bool ApplyAutoFillPolicy(ConfigurationPolicyType policy, Value* value); - - // Make sure that the |path| if present in |prefs_|. If not, set it to - // a blank string. - void EnsureStringPrefExists(const std::string& path); - - // If the required entries for default search are specified and valid, - // finalizes the policy-specified configuration by initializing the - // unspecified map entries. Otherwise wipes all default search related - // map entries from |prefs_|. - void FinalizeDefaultSearchPolicySettings(); - - // If the required entries for the proxy settings are specified and valid, - // finalizes the policy-specified configuration by initializing the - // respective values in |prefs_|. - void FinalizeProxyPolicySettings(); - - // Returns true if the policy values stored in proxy_* represent a valid - // proxy configuration. - bool CheckProxySettings(); - - // Assumes CheckProxySettings returns true and applies the values stored - // in proxy_*. - void ApplyProxySettings(); + + // Initialization status as reported by the policy provider the last time we + // queried it. + bool initialization_complete_; + + // Current policy preferences. + scoped_ptr<ConfigurationPolicyPrefKeeper> policy_keeper_; + + // TODO(mnissler): Remove after provider has proper observer interface. + NotificationRegistrar registrar_; + + ObserverList<Observer, true> observers_; DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyPrefStore); }; diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc index 5dad5dc..895363c 100644 --- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc +++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc @@ -2,14 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <gtest/gtest.h> - #include "base/file_path.h" #include "chrome/browser/policy/configuration_policy_pref_store.h" #include "chrome/browser/policy/mock_configuration_policy_provider.h" #include "chrome/browser/prefs/proxy_prefs.h" -#include "chrome/common/pref_names.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_store_observer_mock.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::Mock; namespace policy { @@ -35,6 +40,13 @@ class ConfigurationPolicyPrefStoreTestBase : public TESTBASE { : provider_(), store_(&provider_) {} + void RefreshPolicy() { + NotificationService::current()->Notify( + NotificationType::POLICY_CHANGED, + Source<ConfigurationPolicyProvider>(&provider_), + NotificationService::NoDetails()); + } + MockConfigurationPolicyProvider provider_; ConfigurationPolicyPrefStore store_; }; @@ -46,29 +58,20 @@ class ConfigurationPolicyPrefStoreListTest }; TEST_P(ConfigurationPolicyPrefStoreListTest, GetDefault) { - ListValue* list = NULL; - EXPECT_FALSE(store_.prefs()->GetList(GetParam().pref_name(), &list)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(GetParam().pref_name(), NULL)); } TEST_P(ConfigurationPolicyPrefStoreListTest, SetValue) { ListValue* in_value = new ListValue(); in_value->Append(Value::CreateStringValue("test1")); in_value->Append(Value::CreateStringValue("test2,")); - store_.Apply(GetParam().type(), in_value); - ListValue* list = NULL; - EXPECT_TRUE(store_.prefs()->GetList(GetParam().pref_name(), &list)); - ListValue::const_iterator current(list->begin()); - const ListValue::const_iterator end(list->end()); - ASSERT_TRUE(current != end); - std::string value; - (*current)->GetAsString(&value); - EXPECT_EQ("test1", value); - ++current; - ASSERT_TRUE(current != end); - (*current)->GetAsString(&value); - EXPECT_EQ("test2,", value); - ++current; - EXPECT_TRUE(current == end); + provider_.AddPolicy(GetParam().type(), in_value); + RefreshPolicy(); + Value* value; + EXPECT_EQ(PrefStore::READ_OK, + store_.GetValue(GetParam().pref_name(), &value)); + EXPECT_TRUE(in_value->Equals(value)); } INSTANTIATE_TEST_CASE_P( @@ -91,16 +94,18 @@ class ConfigurationPolicyPrefStoreStringTest }; TEST_P(ConfigurationPolicyPrefStoreStringTest, GetDefault) { - std::string result; - EXPECT_FALSE(store_.prefs()->GetString(GetParam().pref_name(), &result)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(GetParam().pref_name(), NULL)); } TEST_P(ConfigurationPolicyPrefStoreStringTest, SetValue) { - store_.Apply(GetParam().type(), - Value::CreateStringValue("http://chromium.org")); - std::string result; - EXPECT_TRUE(store_.prefs()->GetString(GetParam().pref_name(), &result)); - EXPECT_EQ(result, "http://chromium.org"); + provider_.AddPolicy(GetParam().type(), + Value::CreateStringValue("http://chromium.org")); + RefreshPolicy(); + Value* value; + EXPECT_EQ(PrefStore::READ_OK, + store_.GetValue(GetParam().pref_name(), &value)); + EXPECT_TRUE(StringValue("http://chromium.org").Equals(value)); } INSTANTIATE_TEST_CASE_P( @@ -129,20 +134,25 @@ class ConfigurationPolicyPrefStoreBooleanTest }; TEST_P(ConfigurationPolicyPrefStoreBooleanTest, GetDefault) { - bool result = false; - EXPECT_FALSE(store_.prefs()->GetBoolean(GetParam().pref_name(), &result)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(GetParam().pref_name(), NULL)); } TEST_P(ConfigurationPolicyPrefStoreBooleanTest, SetValue) { - store_.Apply(GetParam().type(), Value::CreateBooleanValue(false)); + provider_.AddPolicy(GetParam().type(), Value::CreateBooleanValue(false)); + RefreshPolicy(); + Value* value; bool result = true; - EXPECT_TRUE(store_.prefs()->GetBoolean(GetParam().pref_name(), &result)); - EXPECT_FALSE(result); + EXPECT_EQ(PrefStore::READ_OK, + store_.GetValue(GetParam().pref_name(), &value)); + EXPECT_TRUE(FundamentalValue(false).Equals(value)); - store_.Apply(GetParam().type(), Value::CreateBooleanValue(true)); + provider_.AddPolicy(GetParam().type(), Value::CreateBooleanValue(true)); + RefreshPolicy(); result = false; - EXPECT_TRUE(store_.prefs()->GetBoolean(GetParam().pref_name(), &result)); - EXPECT_TRUE(result); + EXPECT_EQ(PrefStore::READ_OK, + store_.GetValue(GetParam().pref_name(), &value)); + EXPECT_TRUE(FundamentalValue(true).Equals(value)); } INSTANTIATE_TEST_CASE_P( @@ -200,15 +210,17 @@ class ConfigurationPolicyPrefStoreIntegerTest }; TEST_P(ConfigurationPolicyPrefStoreIntegerTest, GetDefault) { - int result = 0; - EXPECT_FALSE(store_.prefs()->GetInteger(GetParam().pref_name(), &result)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(GetParam().pref_name(), NULL)); } TEST_P(ConfigurationPolicyPrefStoreIntegerTest, SetValue) { - store_.Apply(GetParam().type(), Value::CreateIntegerValue(2)); - int result = 0; - EXPECT_TRUE(store_.prefs()->GetInteger(GetParam().pref_name(), &result)); - EXPECT_EQ(result, 2); + provider_.AddPolicy(GetParam().type(), Value::CreateIntegerValue(2)); + RefreshPolicy(); + Value* value = NULL; + EXPECT_EQ(PrefStore::READ_OK, + store_.GetValue(GetParam().pref_name(), &value)); + EXPECT_TRUE(FundamentalValue(2).Equals(value)); } INSTANTIATE_TEST_CASE_P( @@ -228,131 +240,124 @@ class ConfigurationPolicyPrefStoreProxyTest : public testing::Test { const std::string& expected_proxy_pac_url, const std::string& expected_proxy_bypass_list, const ProxyPrefs::ProxyMode& expected_proxy_mode) { - std::string string_result; + Value* value = NULL; if (expected_proxy_server.empty()) { - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, - &string_result)); + EXPECT_EQ(PrefStore::READ_USE_DEFAULT, + store.GetValue(prefs::kProxyServer, NULL)); } else { - EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyServer, - &string_result)); - EXPECT_EQ(expected_proxy_server, string_result); + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kProxyServer, &value)); + EXPECT_TRUE(StringValue(expected_proxy_server).Equals(value)); } if (expected_proxy_pac_url.empty()) { - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, - &string_result)); + EXPECT_EQ(PrefStore::READ_USE_DEFAULT, + store.GetValue(prefs::kProxyPacUrl, NULL)); } else { - EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyPacUrl, - &string_result)); - EXPECT_EQ(expected_proxy_pac_url, string_result); + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kProxyPacUrl, &value)); + EXPECT_TRUE(StringValue(expected_proxy_pac_url).Equals(value)); } if (expected_proxy_bypass_list.empty()) { - EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); + EXPECT_EQ(PrefStore::READ_USE_DEFAULT, + store.GetValue(prefs::kProxyBypassList, NULL)); } else { - EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); - EXPECT_EQ(expected_proxy_bypass_list, string_result); + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kProxyBypassList, &value)); + EXPECT_TRUE(StringValue(expected_proxy_bypass_list).Equals(value)); } - int int_result = -1; - EXPECT_TRUE(store.prefs()->GetInteger(prefs::kProxyMode, &int_result)); - EXPECT_EQ(expected_proxy_mode, int_result); + EXPECT_EQ(PrefStore::READ_OK, store.GetValue(prefs::kProxyMode, &value)); + EXPECT_TRUE(FundamentalValue(expected_proxy_mode).Equals(value)); } }; TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptions) { - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyBypassList, - Value::CreateStringValue("http://chromium.org/override")); - provider->AddPolicy(kPolicyProxyServer, - Value::CreateStringValue("chromium.org")); - provider->AddPolicy(kPolicyProxyMode, - Value::CreateIntegerValue( - kPolicyManuallyConfiguredProxyMode)); - - ConfigurationPolicyPrefStore store(provider.get()); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyProxyBypassList, + Value::CreateStringValue("http://chromium.org/override")); + provider.AddPolicy(kPolicyProxyServer, + Value::CreateStringValue("chromium.org")); + provider.AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue( + kPolicyManuallyConfiguredProxyMode)); + + ConfigurationPolicyPrefStore store(&provider); VerifyProxyPrefs( store, "chromium.org", "", "http://chromium.org/override", ProxyPrefs::MODE_FIXED_SERVERS); } TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptionsReversedApplyOrder) { - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyMode, - Value::CreateIntegerValue( - kPolicyManuallyConfiguredProxyMode)); - provider->AddPolicy(kPolicyProxyBypassList, - Value::CreateStringValue("http://chromium.org/override")); - provider->AddPolicy(kPolicyProxyServer, - Value::CreateStringValue("chromium.org")); - - ConfigurationPolicyPrefStore store(provider.get()); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue( + kPolicyManuallyConfiguredProxyMode)); + provider.AddPolicy(kPolicyProxyBypassList, + Value::CreateStringValue("http://chromium.org/override")); + provider.AddPolicy(kPolicyProxyServer, + Value::CreateStringValue("chromium.org")); + + ConfigurationPolicyPrefStore store(&provider); VerifyProxyPrefs( store, "chromium.org", "", "http://chromium.org/override", ProxyPrefs::MODE_FIXED_SERVERS); } TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxy) { - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyMode, - Value::CreateIntegerValue(kPolicyNoProxyServerMode)); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue(kPolicyNoProxyServerMode)); - ConfigurationPolicyPrefStore store(provider.get()); + ConfigurationPolicyPrefStore store(&provider); VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_DIRECT); } TEST_F(ConfigurationPolicyPrefStoreProxyTest, AutoDetect) { - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyMode, - Value::CreateIntegerValue(kPolicyAutoDetectProxyMode)); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue(kPolicyAutoDetectProxyMode)); - ConfigurationPolicyPrefStore store(provider.get()); + ConfigurationPolicyPrefStore store(&provider); VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_AUTO_DETECT); } TEST_F(ConfigurationPolicyPrefStoreProxyTest, AutoDetectPac) { - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyPacUrl, - Value::CreateStringValue("http://short.org/proxy.pac")); - provider->AddPolicy(kPolicyProxyMode, - Value::CreateIntegerValue(kPolicyAutoDetectProxyMode)); - - ConfigurationPolicyPrefStore store(provider.get()); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyProxyPacUrl, + Value::CreateStringValue("http://short.org/proxy.pac")); + provider.AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue(kPolicyAutoDetectProxyMode)); + + ConfigurationPolicyPrefStore store(&provider); VerifyProxyPrefs( store, "", "http://short.org/proxy.pac", "", ProxyPrefs::MODE_PAC_SCRIPT); } TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystem) { - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyMode, - Value::CreateIntegerValue(kPolicyUseSystemProxyMode)); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyProxyMode, + Value::CreateIntegerValue(kPolicyUseSystemProxyMode)); - ConfigurationPolicyPrefStore store(provider.get()); + ConfigurationPolicyPrefStore store(&provider); VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_SYSTEM); } TEST_F(ConfigurationPolicyPrefStoreProxyTest, ProxyInvalid) { for (int i = 0; i < MODE_COUNT; ++i) { - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy(kPolicyProxyMode, Value::CreateIntegerValue(i)); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyProxyMode, Value::CreateIntegerValue(i)); // No mode expects all three parameters being set. - provider->AddPolicy(kPolicyProxyPacUrl, - Value::CreateStringValue("http://short.org/proxy.pac")); - provider->AddPolicy(kPolicyProxyBypassList, - Value::CreateStringValue( - "http://chromium.org/override")); - provider->AddPolicy(kPolicyProxyServer, - Value::CreateStringValue("chromium.org")); - - ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_FALSE(store.prefs()->HasKey(prefs::kProxyMode)); + provider.AddPolicy(kPolicyProxyPacUrl, + Value::CreateStringValue("http://short.org/proxy.pac")); + provider.AddPolicy(kPolicyProxyBypassList, + Value::CreateStringValue( + "http://chromium.org/override")); + provider.AddPolicy(kPolicyProxyServer, + Value::CreateStringValue("chromium.org")); + + ConfigurationPolicyPrefStore store(&provider); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kProxyMode, NULL)); } } @@ -363,42 +368,38 @@ class ConfigurationPolicyPrefStoreDefaultSearchTest : public testing::Test { // search URL, that all the elements have been given proper defaults. TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, MinimallyDefined) { const char* const search_url = "http://test.com/search?t={searchTerms}"; - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy( - kPolicyDefaultSearchProviderEnabled, - Value::CreateBooleanValue(true)); - provider->AddPolicy( - kPolicyDefaultSearchProviderSearchURL, - Value::CreateStringValue(search_url)); - - ConfigurationPolicyPrefStore store(provider.get()); - const DictionaryValue* prefs = store.prefs(); - - std::string string_result; - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderSearchURL, - &string_result)); - EXPECT_EQ(string_result, search_url); - - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderName, - &string_result)); - EXPECT_EQ(string_result, "test.com"); - - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderKeyword, - &string_result)); - EXPECT_EQ(string_result, std::string()); - - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderSuggestURL, - &string_result)); - EXPECT_EQ(string_result, std::string()); - - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderIconURL, - &string_result)); - EXPECT_EQ(string_result, std::string()); - - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderEncodings, - &string_result)); - EXPECT_EQ(string_result, std::string()); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyDefaultSearchProviderEnabled, + Value::CreateBooleanValue(true)); + provider.AddPolicy(kPolicyDefaultSearchProviderSearchURL, + Value::CreateStringValue(search_url)); + + ConfigurationPolicyPrefStore store(&provider); + + Value* value = NULL; + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderSearchURL, &value)); + EXPECT_TRUE(StringValue(search_url).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderName, &value)); + EXPECT_TRUE(StringValue("test.com").Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderKeyword, &value)); + EXPECT_TRUE(StringValue(std::string()).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderSuggestURL, &value)); + EXPECT_TRUE(StringValue(std::string()).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderIconURL, &value)); + EXPECT_TRUE(StringValue(std::string()).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderEncodings, &value)); + EXPECT_TRUE(StringValue(std::string()).Equals(value)); } // Checks that for a fully defined search policy, all elements have been @@ -410,62 +411,48 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, FullyDefined) { const char* const name = "MyName"; const char* const keyword = "MyKeyword"; const char* const encodings = "UTF-16;UTF-8"; - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy( - kPolicyDefaultSearchProviderEnabled, - Value::CreateBooleanValue(true)); - provider->AddPolicy( - kPolicyDefaultSearchProviderSearchURL, - Value::CreateStringValue(search_url)); - provider->AddPolicy( - kPolicyDefaultSearchProviderName, - Value::CreateStringValue(name)); - provider->AddPolicy( - kPolicyDefaultSearchProviderKeyword, - Value::CreateStringValue(keyword)); - provider->AddPolicy( - kPolicyDefaultSearchProviderSuggestURL, - Value::CreateStringValue(suggest_url)); - provider->AddPolicy( - kPolicyDefaultSearchProviderIconURL, - Value::CreateStringValue(icon_url)); - provider->AddPolicy( - kPolicyDefaultSearchProviderEncodings, - Value::CreateStringValue(encodings)); - - ConfigurationPolicyPrefStore store(provider.get()); - const DictionaryValue* prefs = store.prefs(); - - std::string result_search_url; - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderSearchURL, - &result_search_url)); - EXPECT_EQ(result_search_url, search_url); - - std::string result_name; - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderName, - &result_name)); - EXPECT_EQ(result_name, name); - - std::string result_keyword; - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderKeyword, - &result_keyword)); - EXPECT_EQ(result_keyword, keyword); - - std::string result_suggest_url; - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderSuggestURL, - &result_suggest_url)); - EXPECT_EQ(result_suggest_url, suggest_url); - - std::string result_icon_url; - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderIconURL, - &result_icon_url)); - EXPECT_EQ(result_icon_url, icon_url); - - std::string result_encodings; - EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderEncodings, - &result_encodings)); - EXPECT_EQ(result_encodings, encodings); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyDefaultSearchProviderEnabled, + Value::CreateBooleanValue(true)); + provider.AddPolicy(kPolicyDefaultSearchProviderSearchURL, + Value::CreateStringValue(search_url)); + provider.AddPolicy(kPolicyDefaultSearchProviderName, + Value::CreateStringValue(name)); + provider.AddPolicy(kPolicyDefaultSearchProviderKeyword, + Value::CreateStringValue(keyword)); + provider.AddPolicy(kPolicyDefaultSearchProviderSuggestURL, + Value::CreateStringValue(suggest_url)); + provider.AddPolicy(kPolicyDefaultSearchProviderIconURL, + Value::CreateStringValue(icon_url)); + provider.AddPolicy(kPolicyDefaultSearchProviderEncodings, + Value::CreateStringValue(encodings)); + + ConfigurationPolicyPrefStore store(&provider); + + Value* value = NULL; + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderSearchURL, &value)); + EXPECT_TRUE(StringValue(search_url).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderName, &value)); + EXPECT_TRUE(StringValue(name).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderKeyword, &value)); + EXPECT_TRUE(StringValue(keyword).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderSuggestURL, &value)); + EXPECT_TRUE(StringValue(suggest_url).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderIconURL, &value)); + EXPECT_TRUE(StringValue(icon_url).Equals(value)); + + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kDefaultSearchProviderEncodings, &value)); + EXPECT_TRUE(StringValue(encodings).Equals(value)); } // Checks that if the default search policy is missing, that no elements of the @@ -476,43 +463,34 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, MissingUrl) { const char* const name = "MyName"; const char* const keyword = "MyKeyword"; const char* const encodings = "UTF-16;UTF-8"; - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy( - kPolicyDefaultSearchProviderEnabled, - Value::CreateBooleanValue(true)); - provider->AddPolicy( - kPolicyDefaultSearchProviderName, - Value::CreateStringValue(name)); - provider->AddPolicy( - kPolicyDefaultSearchProviderKeyword, - Value::CreateStringValue(keyword)); - provider->AddPolicy( - kPolicyDefaultSearchProviderSuggestURL, - Value::CreateStringValue(suggest_url)); - provider->AddPolicy( - kPolicyDefaultSearchProviderIconURL, - Value::CreateStringValue(icon_url)); - provider->AddPolicy( - kPolicyDefaultSearchProviderEncodings, - Value::CreateStringValue(encodings)); - - ConfigurationPolicyPrefStore store(provider.get()); - const DictionaryValue* prefs = store.prefs(); - - std::string string_result; - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderSearchURL, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderName, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderKeyword, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderSuggestURL, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderIconURL, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderEncodings, - &string_result)); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyDefaultSearchProviderEnabled, + Value::CreateBooleanValue(true)); + provider.AddPolicy(kPolicyDefaultSearchProviderName, + Value::CreateStringValue(name)); + provider.AddPolicy(kPolicyDefaultSearchProviderKeyword, + Value::CreateStringValue(keyword)); + provider.AddPolicy(kPolicyDefaultSearchProviderSuggestURL, + Value::CreateStringValue(suggest_url)); + provider.AddPolicy(kPolicyDefaultSearchProviderIconURL, + Value::CreateStringValue(icon_url)); + provider.AddPolicy(kPolicyDefaultSearchProviderEncodings, + Value::CreateStringValue(encodings)); + + ConfigurationPolicyPrefStore store(&provider); + + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderSearchURL, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderName, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderKeyword, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderSuggestURL, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderIconURL, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderEncodings, NULL)); } // Checks that if the default search policy is invalid, that no elements of the @@ -524,48 +502,36 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, Invalid) { const char* const name = "MyName"; const char* const keyword = "MyKeyword"; const char* const encodings = "UTF-16;UTF-8"; - scoped_ptr<MockConfigurationPolicyProvider> provider( - new MockConfigurationPolicyProvider()); - provider->AddPolicy( - kPolicyDefaultSearchProviderEnabled, - Value::CreateBooleanValue(true)); - provider->AddPolicy( - kPolicyDefaultSearchProviderSearchURL, - Value::CreateStringValue(bad_search_url)); - provider->AddPolicy( - kPolicyDefaultSearchProviderName, - Value::CreateStringValue(name)); - provider->AddPolicy( - kPolicyDefaultSearchProviderKeyword, - Value::CreateStringValue(keyword)); - provider->AddPolicy( - kPolicyDefaultSearchProviderSuggestURL, - Value::CreateStringValue(suggest_url)); - provider->AddPolicy( - kPolicyDefaultSearchProviderIconURL, - Value::CreateStringValue(icon_url)); - provider->AddPolicy( - kPolicyDefaultSearchProviderEncodings, - Value::CreateStringValue(encodings)); - - ConfigurationPolicyPrefStore store(provider.get()); - const DictionaryValue* const prefs = store.prefs(); - - std::string string_result; - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderEnabled, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderSearchURL, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderName, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderKeyword, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderSuggestURL, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderIconURL, - &string_result)); - EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderEncodings, - &string_result)); + MockConfigurationPolicyProvider provider; + provider.AddPolicy(kPolicyDefaultSearchProviderEnabled, + Value::CreateBooleanValue(true)); + provider.AddPolicy(kPolicyDefaultSearchProviderSearchURL, + Value::CreateStringValue(bad_search_url)); + provider.AddPolicy(kPolicyDefaultSearchProviderName, + Value::CreateStringValue(name)); + provider.AddPolicy(kPolicyDefaultSearchProviderKeyword, + Value::CreateStringValue(keyword)); + provider.AddPolicy(kPolicyDefaultSearchProviderSuggestURL, + Value::CreateStringValue(suggest_url)); + provider.AddPolicy(kPolicyDefaultSearchProviderIconURL, + Value::CreateStringValue(icon_url)); + provider.AddPolicy(kPolicyDefaultSearchProviderEncodings, + Value::CreateStringValue(encodings)); + + ConfigurationPolicyPrefStore store(&provider); + + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderSearchURL, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderName, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderKeyword, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderSuggestURL, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderIconURL, NULL)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store.GetValue(prefs::kDefaultSearchProviderEncodings, NULL)); } // Test cases for the Sync policy setting. @@ -574,23 +540,25 @@ class ConfigurationPolicyPrefStoreSyncTest }; TEST_F(ConfigurationPolicyPrefStoreSyncTest, Default) { - bool result = false; - EXPECT_FALSE(store_.prefs()->GetBoolean(prefs::kSyncManaged, &result)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(prefs::kSyncManaged, NULL)); } TEST_F(ConfigurationPolicyPrefStoreSyncTest, Enabled) { - store_.Apply(kPolicySyncDisabled, Value::CreateBooleanValue(false)); + provider_.AddPolicy(kPolicySyncDisabled, Value::CreateBooleanValue(false)); + RefreshPolicy(); // Enabling Sync should not set the pref. - bool result = false; - EXPECT_FALSE(store_.prefs()->GetBoolean(prefs::kSyncManaged, &result)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(prefs::kSyncManaged, NULL)); } TEST_F(ConfigurationPolicyPrefStoreSyncTest, Disabled) { - store_.Apply(kPolicySyncDisabled, Value::CreateBooleanValue(true)); + provider_.AddPolicy(kPolicySyncDisabled, Value::CreateBooleanValue(true)); + RefreshPolicy(); // Sync should be flagged as managed. - bool result = false; - EXPECT_TRUE(store_.prefs()->GetBoolean(prefs::kSyncManaged, &result)); - EXPECT_TRUE(result); + Value* value = NULL; + EXPECT_EQ(PrefStore::READ_OK, store_.GetValue(prefs::kSyncManaged, &value)); + EXPECT_TRUE(FundamentalValue(true).Equals(value)); } // Test cases for the AutoFill policy setting. @@ -599,23 +567,80 @@ class ConfigurationPolicyPrefStoreAutoFillTest }; TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Default) { - bool result = false; - EXPECT_FALSE(store_.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(prefs::kSyncManaged, NULL)); } TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Enabled) { - store_.Apply(kPolicyAutoFillEnabled, Value::CreateBooleanValue(true)); + provider_.AddPolicy(kPolicyAutoFillEnabled, Value::CreateBooleanValue(true)); + RefreshPolicy(); // Enabling AutoFill should not set the pref. - bool result = false; - EXPECT_FALSE(store_.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(prefs::kSyncManaged, NULL)); } TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Disabled) { - store_.Apply(kPolicyAutoFillEnabled, Value::CreateBooleanValue(false)); + provider_.AddPolicy(kPolicyAutoFillEnabled, Value::CreateBooleanValue(false)); + RefreshPolicy(); // Disabling AutoFill should switch the pref to managed. - bool result = true; - EXPECT_TRUE(store_.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); - EXPECT_FALSE(result); + Value* value = NULL; + EXPECT_EQ(PrefStore::READ_OK, + store_.GetValue(prefs::kAutoFillEnabled, &value)); + EXPECT_TRUE(FundamentalValue(false).Equals(value)); +} + +// Exercises the policy refresh mechanism. +class ConfigurationPolicyPrefStoreRefreshTest + : public ConfigurationPolicyPrefStoreTestBase<testing::Test> { + protected: + virtual void SetUp() { + store_.AddObserver(&observer_); + } + + virtual void TearDown() { + store_.RemoveObserver(&observer_); + } + + PrefStoreObserverMock observer_; +}; + +TEST_F(ConfigurationPolicyPrefStoreRefreshTest, Refresh) { + Value* value = NULL; + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(prefs::kHomePage, NULL)); + + EXPECT_CALL(observer_, OnPrefValueChanged(prefs::kHomePage)).Times(1); + provider_.AddPolicy(kPolicyHomePage, + Value::CreateStringValue("http://www.chromium.org")); + RefreshPolicy(); + Mock::VerifyAndClearExpectations(&observer_); + EXPECT_EQ(PrefStore::READ_OK, + store_.GetValue(prefs::kHomePage, &value)); + EXPECT_TRUE(StringValue("http://www.chromium.org").Equals(value)); + + EXPECT_CALL(observer_, OnPrefValueChanged(_)).Times(0); + RefreshPolicy(); + Mock::VerifyAndClearExpectations(&observer_); + + EXPECT_CALL(observer_, OnPrefValueChanged(prefs::kHomePage)).Times(1); + provider_.RemovePolicy(kPolicyHomePage); + RefreshPolicy(); + Mock::VerifyAndClearExpectations(&observer_); + EXPECT_EQ(PrefStore::READ_NO_VALUE, + store_.GetValue(prefs::kHomePage, NULL)); +} + +TEST_F(ConfigurationPolicyPrefStoreRefreshTest, Initialization) { + EXPECT_FALSE(store_.IsInitializationComplete()); + + EXPECT_CALL(observer_, OnInitializationCompleted()).Times(1); + + provider_.SetInitializationComplete(true); + EXPECT_FALSE(store_.IsInitializationComplete()); + + RefreshPolicy(); + Mock::VerifyAndClearExpectations(&observer_); + EXPECT_TRUE(store_.IsInitializationComplete()); } } // namespace policy diff --git a/chrome/browser/policy/configuration_policy_provider.h b/chrome/browser/policy/configuration_policy_provider.h index 6d5cc7c..b036eb3 100644 --- a/chrome/browser/policy/configuration_policy_provider.h +++ b/chrome/browser/policy/configuration_policy_provider.h @@ -38,24 +38,29 @@ class ConfigurationPolicyProvider { virtual ~ConfigurationPolicyProvider(); - // Must be implemented by provider subclasses to specify the - // provider-specific policy decisions. The preference service - // invokes this |Provide| method when it needs a policy - // provider to specify its policy choices. In |Provide|, - // the |ConfigurationPolicyProvider| must make calls to the - // |Apply| method of |store| to apply specific policies. - // Returns true if the policy could be provided, otherwise false. + // Must be implemented by provider subclasses to specify the provider-specific + // policy decisions. The preference service invokes this |Provide| method when + // it needs a policy provider to specify its policy choices. In |Provide|, the + // |ConfigurationPolicyProvider| must make calls to the |Apply| method of + // |store| to apply specific policies. Returns true if the policy could be + // provided, otherwise false. virtual bool Provide(ConfigurationPolicyStoreInterface* store) = 0; + // Check whether this provider has completed initialization. This is used to + // detect whether initialization is done in case providers implementations + // need to do asynchronous operations for initialization. + virtual bool IsInitializationComplete() const { return true; } + // Called by the subclass provider at any time to indicate that the currently // applied policy is not longer current. A policy refresh will be initiated as // soon as possible. virtual void NotifyStoreOfPolicyChange(); + protected: // Decodes the value tree and writes the configuration to the given |store|. void DecodePolicyValueTree(const DictionaryValue* policies, ConfigurationPolicyStoreInterface* store); - protected: + const PolicyDefinitionList* policy_definition_list() const { return policy_definition_list_; } diff --git a/chrome/browser/policy/device_management_policy_provider.cc b/chrome/browser/policy/device_management_policy_provider.cc index 9d2d727..d3d07b2 100644 --- a/chrome/browser/policy/device_management_policy_provider.cc +++ b/chrome/browser/policy/device_management_policy_provider.cc @@ -10,10 +10,10 @@ #include "base/rand_util.h" #include "base/task.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/policy/device_management_backend.h" #include "chrome/browser/policy/device_management_policy_cache.h" #include "chrome/browser/policy/proto/device_management_constants.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/notification_service.h" @@ -117,6 +117,10 @@ bool DeviceManagementPolicyProvider::Provide( return true; } +bool DeviceManagementPolicyProvider::IsInitializationComplete() const { + return !waiting_for_initial_policies_; +} + void DeviceManagementPolicyProvider::HandlePolicyResponse( const em::DevicePolicyResponse& response) { if (cache_->SetPolicy(response)) @@ -320,7 +324,7 @@ void DeviceManagementPolicyProvider::StopWaitingForInitialPolicies() { } void DeviceManagementPolicyProvider::NotifyCloudPolicyUpdate() const { - NotificationService::current()->Notify( + NotificationService::current()->Notify( NotificationType::CLOUD_POLICY_UPDATE, Source<DeviceManagementPolicyProvider>(this), NotificationService::NoDetails()); diff --git a/chrome/browser/policy/device_management_policy_provider.h b/chrome/browser/policy/device_management_policy_provider.h index a3a61d1..369d874 100644 --- a/chrome/browser/policy/device_management_policy_provider.h +++ b/chrome/browser/policy/device_management_policy_provider.h @@ -41,6 +41,7 @@ class DeviceManagementPolicyProvider // ConfigurationPolicyProvider implementation: virtual bool Provide(ConfigurationPolicyStoreInterface* store); + virtual bool IsInitializationComplete() const; // DevicePolicyResponseDelegate implementation: virtual void HandlePolicyResponse( @@ -52,14 +53,6 @@ class DeviceManagementPolicyProvider virtual void OnTokenError(); virtual void OnNotManaged(); - // True if a policy request has been sent to the device management backend - // server and no response or error has yet been received. - bool IsPolicyRequestPending() const { return policy_request_pending_; } - - bool waiting_for_initial_policies() const { - return waiting_for_initial_policies_; - } - // Tells the provider that the passed in token service reference is about to // become invalid. void Shutdown(); diff --git a/chrome/browser/policy/device_management_policy_provider_unittest.cc b/chrome/browser/policy/device_management_policy_provider_unittest.cc index 3d85397..a4127b7 100644 --- a/chrome/browser/policy/device_management_policy_provider_unittest.cc +++ b/chrome/browser/policy/device_management_policy_provider_unittest.cc @@ -39,7 +39,7 @@ class DeviceManagementPolicyProviderTest : public testing::Test { virtual void SetUp() { profile_.reset(new TestingProfile); CreateNewProvider(); - EXPECT_TRUE(provider_->waiting_for_initial_policies()); + EXPECT_TRUE(waiting_for_initial_policies()); loop_.RunAllPending(); } @@ -99,7 +99,7 @@ class DeviceManagementPolicyProviderTest : public testing::Test { MockDeviceManagementBackendSucceedBooleanPolicy( key::kDisableSpdy, true)); SimulateSuccessfulLoginAndRunPending(); - EXPECT_FALSE(provider_->waiting_for_initial_policies()); + EXPECT_FALSE(waiting_for_initial_policies()); EXPECT_CALL(store, Apply(kPolicyDisableSpdy, _)).Times(1); provider_->Provide(&store); ASSERT_EQ(1U, store.policy_map().size()); @@ -111,6 +111,10 @@ class DeviceManagementPolicyProviderTest : public testing::Test { loop_.RunAllPending(); } + bool waiting_for_initial_policies() const { + return provider_->waiting_for_initial_policies_; + } + MockDeviceManagementBackend* backend_; // weak scoped_ptr<DeviceManagementPolicyProvider> provider_; @@ -136,14 +140,14 @@ TEST_F(DeviceManagementPolicyProviderTest, InitialProvideNoLogin) { EXPECT_CALL(store, Apply(_, _)).Times(0); provider_->Provide(&store); EXPECT_TRUE(store.policy_map().empty()); - EXPECT_TRUE(provider_->waiting_for_initial_policies()); + EXPECT_TRUE(waiting_for_initial_policies()); } // If the login is successful and there's no previously-fetched policy, the // policy should be fetched from the server and should be available the first // time the Provide method is called. TEST_F(DeviceManagementPolicyProviderTest, InitialProvideWithLogin) { - EXPECT_TRUE(provider_->waiting_for_initial_policies()); + EXPECT_TRUE(waiting_for_initial_policies()); SimulateSuccessfulInitialPolicyFetch(); } @@ -305,7 +309,7 @@ TEST_F(DeviceManagementPolicyProviderTest, UnmanagedDevice) { // (2) On restart, the provider should detect that this is not the first // login. CreateNewProvider(1000*1000, 0, 0, 0, 0); - EXPECT_FALSE(provider_->waiting_for_initial_policies()); + EXPECT_FALSE(waiting_for_initial_policies()); EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( diff --git a/chrome/browser/policy/mock_configuration_policy_provider.cc b/chrome/browser/policy/mock_configuration_policy_provider.cc index 9c2db8d..a2566b0 100644 --- a/chrome/browser/policy/mock_configuration_policy_provider.cc +++ b/chrome/browser/policy/mock_configuration_policy_provider.cc @@ -11,7 +11,8 @@ namespace policy { MockConfigurationPolicyProvider::MockConfigurationPolicyProvider() : ConfigurationPolicyProvider( - ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()) { + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()), + initialization_complete_(false) { } MockConfigurationPolicyProvider::~MockConfigurationPolicyProvider() { @@ -24,6 +25,20 @@ void MockConfigurationPolicyProvider::AddPolicy(ConfigurationPolicyType policy, delete value; } +void MockConfigurationPolicyProvider::RemovePolicy( + ConfigurationPolicyType policy) { + const PolicyMap::iterator entry = policy_map_.find(policy); + if (entry != policy_map_.end()) { + delete entry->second; + policy_map_.erase(entry); + } +} + +void MockConfigurationPolicyProvider::SetInitializationComplete( + bool initialization_complete) { + initialization_complete_ = initialization_complete; +} + bool MockConfigurationPolicyProvider::Provide( ConfigurationPolicyStoreInterface* store) { for (PolicyMap::const_iterator current = policy_map_.begin(); @@ -33,4 +48,8 @@ bool MockConfigurationPolicyProvider::Provide( return true; } +bool MockConfigurationPolicyProvider::IsInitializationComplete() const { + return initialization_complete_; +} + } diff --git a/chrome/browser/policy/mock_configuration_policy_provider.h b/chrome/browser/policy/mock_configuration_policy_provider.h index 731256e..aa2969e 100644 --- a/chrome/browser/policy/mock_configuration_policy_provider.h +++ b/chrome/browser/policy/mock_configuration_policy_provider.h @@ -22,9 +22,13 @@ class MockConfigurationPolicyProvider : public ConfigurationPolicyProvider { virtual ~MockConfigurationPolicyProvider(); void AddPolicy(ConfigurationPolicyType policy, Value* value); + void RemovePolicy(ConfigurationPolicyType policy); + + void SetInitializationComplete(bool initialization_complete); // ConfigurationPolicyProvider method overrides. virtual bool Provide(ConfigurationPolicyStoreInterface* store); + virtual bool IsInitializationComplete() const; MOCK_METHOD0(NotifyStoreOfPolicyChange, void()); @@ -32,6 +36,7 @@ class MockConfigurationPolicyProvider : public ConfigurationPolicyProvider { typedef std::map<ConfigurationPolicyType, Value*> PolicyMap; PolicyMap policy_map_; + bool initialization_complete_; }; } // namespace policy diff --git a/chrome/browser/prefs/pref_member_unittest.cc b/chrome/browser/prefs/pref_member_unittest.cc index bf9204e..3f786afb 100644 --- a/chrome/browser/prefs/pref_member_unittest.cc +++ b/chrome/browser/prefs/pref_member_unittest.cc @@ -6,6 +6,7 @@ #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 "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/prefs/pref_notifier_impl_unittest.cc b/chrome/browser/prefs/pref_notifier_impl_unittest.cc index 8f3be3c..a410884 100644 --- a/chrome/browser/prefs/pref_notifier_impl_unittest.cc +++ b/chrome/browser/prefs/pref_notifier_impl_unittest.cc @@ -7,6 +7,7 @@ #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/pref_value_store.h" #include "chrome/common/notification_observer_mock.h" +#include "chrome/common/notification_registrar.h" #include "chrome/common/notification_service.h" #include "chrome/test/testing_pref_service.h" #include "testing/gmock/include/gmock/gmock.h" diff --git a/chrome/browser/prefs/pref_service.cc b/chrome/browser/prefs/pref_service.cc index 4a3110c..809a8ac 100644 --- a/chrome/browser/prefs/pref_service.cc +++ b/chrome/browser/prefs/pref_service.cc @@ -26,7 +26,6 @@ #include "chrome/browser/prefs/default_pref_store.h" #include "chrome/browser/prefs/pref_notifier_impl.h" #include "chrome/browser/prefs/pref_value_store.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/common/json_pref_store.h" #include "chrome/common/notification_service.h" #include "grit/chromium_strings.h" @@ -117,7 +116,7 @@ PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore(); return new PrefService(managed, device_management, extension_prefs, - command_line, user, recommended, profile); + command_line, user, recommended); } PrefService::PrefService(PrefStore* managed_platform_prefs, @@ -125,8 +124,7 @@ PrefService::PrefService(PrefStore* managed_platform_prefs, PrefStore* extension_prefs, PrefStore* command_line_prefs, PersistentPrefStore* user_prefs, - PrefStore* recommended_prefs, - Profile* profile) + PrefStore* recommended_prefs) : user_pref_store_(user_prefs) { pref_notifier_.reset(new PrefNotifierImpl(this)); default_store_ = new DefaultPrefStore(); @@ -138,8 +136,7 @@ PrefService::PrefService(PrefStore* managed_platform_prefs, user_pref_store_, recommended_prefs, default_store_, - pref_notifier_.get(), - profile); + pref_notifier_.get()); InitFromStorage(); } diff --git a/chrome/browser/prefs/pref_service.h b/chrome/browser/prefs/pref_service.h index 2e0623b..5485292 100644 --- a/chrome/browser/prefs/pref_service.h +++ b/chrome/browser/prefs/pref_service.h @@ -230,8 +230,7 @@ class PrefService : public NonThreadSafe { PrefStore* extension_prefs, PrefStore* command_line_prefs, PersistentPrefStore* user_prefs, - PrefStore* recommended_prefs, - Profile* profile); + PrefStore* recommended_prefs); // The PrefNotifier handles registering and notifying preference observers. // It is created and owned by this PrefService. Subclasses may access it for diff --git a/chrome/browser/prefs/pref_service_mock_builder.cc b/chrome/browser/prefs/pref_service_mock_builder.cc index 3060948..005b700 100644 --- a/chrome/browser/prefs/pref_service_mock_builder.cc +++ b/chrome/browser/prefs/pref_service_mock_builder.cc @@ -12,8 +12,7 @@ #include "chrome/common/json_pref_store.h" PrefServiceMockBuilder::PrefServiceMockBuilder() - : user_prefs_(new TestingPrefStore), - profile_(NULL) { + : user_prefs_(new TestingPrefStore) { } PrefServiceMockBuilder& @@ -98,10 +97,7 @@ PrefService* PrefServiceMockBuilder::Create() { extension_prefs_.release(), command_line_prefs_.release(), user_prefs_.release(), - recommended_prefs_.release(), - profile_); + recommended_prefs_.release()); user_prefs_.reset(new TestingPrefStore); - profile_ = NULL; - return pref_service; } diff --git a/chrome/browser/prefs/pref_service_mock_builder.h b/chrome/browser/prefs/pref_service_mock_builder.h index c17040e..b8e32755 100644 --- a/chrome/browser/prefs/pref_service_mock_builder.h +++ b/chrome/browser/prefs/pref_service_mock_builder.h @@ -61,7 +61,6 @@ class PrefServiceMockBuilder { scoped_ptr<PrefStore> command_line_prefs_; scoped_ptr<PersistentPrefStore> user_prefs_; scoped_ptr<PrefStore> recommended_prefs_; - Profile* profile_; DISALLOW_COPY_AND_ASSIGN(PrefServiceMockBuilder); }; diff --git a/chrome/browser/prefs/pref_value_map.cc b/chrome/browser/prefs/pref_value_map.cc index ff27049..6e7bf79 100644 --- a/chrome/browser/prefs/pref_value_map.cc +++ b/chrome/browser/prefs/pref_value_map.cc @@ -57,3 +57,51 @@ void PrefValueMap::Clear() { STLDeleteValues(&prefs_); prefs_.clear(); } + +bool PrefValueMap::GetBoolean(const std::string& key, + bool* value) 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; + return GetValue(key, &stored_value) && stored_value->GetAsString(value); +} + +void PrefValueMap::SetString(const std::string& key, + const std::string& value) { + SetValue(key, Value::CreateStringValue(value)); +} + +void PrefValueMap::GetDifferingKeys( + const PrefValueMap* other, + std::vector<std::string>* differing_keys) const { + differing_keys->clear(); + + // Walk over the maps in lockstep, adding everything that is different. + Map::const_iterator this_pref(prefs_.begin()); + Map::const_iterator other_pref(other->prefs_.begin()); + while (this_pref != prefs_.end() && other_pref != other->prefs_.end()) { + const int diff = this_pref->first.compare(other_pref->first); + if (diff == 0) { + if (!this_pref->second->Equals(other_pref->second)) + differing_keys->push_back(this_pref->first); + ++this_pref; + ++other_pref; + } else if (diff < 0) { + differing_keys->push_back(this_pref->first); + ++this_pref; + } else if (diff > 0) { + differing_keys->push_back(other_pref->first); + ++other_pref; + } + } + + // Add the remaining entries. + for ( ; this_pref != prefs_.end(); ++this_pref) + differing_keys->push_back(this_pref->first); + for ( ; other_pref != other->prefs_.end(); ++other_pref) + differing_keys->push_back(other_pref->first); +} diff --git a/chrome/browser/prefs/pref_value_map.h b/chrome/browser/prefs/pref_value_map.h index ddcddf2..0e99920 100644 --- a/chrome/browser/prefs/pref_value_map.h +++ b/chrome/browser/prefs/pref_value_map.h @@ -8,6 +8,7 @@ #include <map> #include <string> +#include <vector> #include "base/basictypes.h" @@ -35,6 +36,23 @@ class PrefValueMap { // Clears the map. void Clear(); + // Gets a boolean value for |key| and stores it in |value|. Returns true if + // the value was found and of the proper type. + bool GetBoolean(const std::string& key, bool* value) const; + + // Gets a string value for |key| and stores it in |value|. Returns true if + // the value was found and of the proper type. + bool GetString(const std::string& key, std::string* value) const; + + // Sets the value for |key| to the string |value|. + void SetString(const std::string& key, const std::string& value); + + // Compares this value map against |other| and stores all key names that have + // different values in |differing_keys|. This includes keys that are present + // only in one of the maps. + void GetDifferingKeys(const PrefValueMap* other, + std::vector<std::string>* differing_keys) const; + private: typedef std::map<std::string, Value*> Map; diff --git a/chrome/browser/prefs/pref_value_map_unittest.cc b/chrome/browser/prefs/pref_value_map_unittest.cc new file mode 100644 index 0000000..5e248b0 --- /dev/null +++ b/chrome/browser/prefs/pref_value_map_unittest.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2010 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 "base/values.h" +#include "chrome/browser/prefs/pref_value_map.h" +#include "testing/gtest/include/gtest/gtest.h" + +class PrefValueMapTest : public testing::Test { +}; + +TEST_F(PrefValueMapTest, SetValue) { + PrefValueMap map; + Value* result = NULL; + EXPECT_FALSE(map.GetValue("key", &result)); + EXPECT_FALSE(result); + + EXPECT_TRUE(map.SetValue("key", Value::CreateStringValue("test"))); + EXPECT_FALSE(map.SetValue("key", Value::CreateStringValue("test"))); + EXPECT_TRUE(map.SetValue("key", Value::CreateStringValue("hi mom!"))); + + EXPECT_TRUE(map.GetValue("key", &result)); + EXPECT_TRUE(StringValue("hi mom!").Equals(result)); +} + +TEST_F(PrefValueMapTest, RemoveValue) { + PrefValueMap map; + EXPECT_FALSE(map.RemoveValue("key")); + + EXPECT_TRUE(map.SetValue("key", Value::CreateStringValue("test"))); + EXPECT_TRUE(map.GetValue("key", NULL)); + + EXPECT_TRUE(map.RemoveValue("key")); + EXPECT_FALSE(map.GetValue("key", NULL)); + + EXPECT_FALSE(map.RemoveValue("key")); +} + +TEST_F(PrefValueMapTest, Clear) { + PrefValueMap map; + EXPECT_TRUE(map.SetValue("key", Value::CreateStringValue("test"))); + EXPECT_TRUE(map.GetValue("key", NULL)); + + map.Clear(); + + EXPECT_FALSE(map.GetValue("key", NULL)); +} + +TEST_F(PrefValueMapTest, GetDifferingKeys) { + PrefValueMap reference; + EXPECT_TRUE(reference.SetValue("b", Value::CreateStringValue("test"))); + EXPECT_TRUE(reference.SetValue("c", Value::CreateStringValue("test"))); + EXPECT_TRUE(reference.SetValue("e", Value::CreateStringValue("test"))); + + PrefValueMap check; + std::vector<std::string> differing_paths; + std::vector<std::string> expected_differing_paths; + + reference.GetDifferingKeys(&check, &differing_paths); + expected_differing_paths.push_back("b"); + expected_differing_paths.push_back("c"); + expected_differing_paths.push_back("e"); + EXPECT_EQ(expected_differing_paths, differing_paths); + + EXPECT_TRUE(check.SetValue("a", Value::CreateStringValue("test"))); + EXPECT_TRUE(check.SetValue("c", Value::CreateStringValue("test"))); + EXPECT_TRUE(check.SetValue("d", Value::CreateStringValue("test"))); + + reference.GetDifferingKeys(&check, &differing_paths); + expected_differing_paths.clear(); + expected_differing_paths.push_back("a"); + expected_differing_paths.push_back("b"); + expected_differing_paths.push_back("d"); + expected_differing_paths.push_back("e"); + EXPECT_EQ(expected_differing_paths, differing_paths); +} diff --git a/chrome/browser/prefs/pref_value_store.cc b/chrome/browser/prefs/pref_value_store.cc index 3ad6c44..0fd3449 100644 --- a/chrome/browser/prefs/pref_value_store.cc +++ b/chrome/browser/prefs/pref_value_store.cc @@ -4,10 +4,7 @@ #include "chrome/browser/prefs/pref_value_store.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/policy/configuration_policy_pref_store.h" #include "chrome/browser/prefs/pref_notifier.h" -#include "chrome/common/notification_service.h" PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() : pref_value_store_(NULL), @@ -48,10 +45,8 @@ PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, PrefStore* user_prefs, PrefStore* recommended_prefs, PrefStore* default_prefs, - PrefNotifier* pref_notifier, - Profile* profile) - : pref_notifier_(pref_notifier), - profile_(profile) { + PrefNotifier* pref_notifier) + : pref_notifier_(pref_notifier) { InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs); InitPrefStore(DEVICE_MANAGEMENT_STORE, device_management_prefs); InitPrefStore(EXTENSION_STORE, extension_prefs); @@ -60,11 +55,6 @@ PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, InitPrefStore(RECOMMENDED_STORE, recommended_prefs); InitPrefStore(DEFAULT_STORE, default_prefs); - // TODO(mnissler): Remove after policy refresh cleanup. - registrar_.Add(this, - NotificationType(NotificationType::POLICY_CHANGED), - NotificationService::AllSources()); - CheckInitializationCompleted(); } @@ -250,142 +240,6 @@ bool PrefValueStore::GetValueFromStore(const char* name, return false; } -void PrefValueStore::RefreshPolicyPrefsOnFileThread( - BrowserThread::ID calling_thread_id, - policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, - policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, - policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - scoped_ptr<policy::ConfigurationPolicyPrefStore> managed_platform_pref_store( - new_managed_platform_pref_store); - scoped_ptr<policy::ConfigurationPolicyPrefStore> device_management_pref_store( - new_device_management_pref_store); - scoped_ptr<policy::ConfigurationPolicyPrefStore> recommended_pref_store( - new_recommended_pref_store); - - BrowserThread::PostTask( - calling_thread_id, FROM_HERE, - NewRunnableMethod(this, - &PrefValueStore::RefreshPolicyPrefsCompletion, - managed_platform_pref_store.release(), - device_management_pref_store.release(), - recommended_pref_store.release())); -} - -void PrefValueStore::RefreshPolicyPrefs() { - using policy::ConfigurationPolicyPrefStore; - // Because loading of policy information must happen on the FILE - // thread, it's not possible to just replace the contents of the - // managed and recommended stores in place due to possible - // concurrent access from the UI thread. Instead, new stores are - // created and the refreshed policy read into them. The new stores - // are swapped with the old from a Task on the UI thread after the - // load is complete. - ConfigurationPolicyPrefStore* new_managed_platform_pref_store( - ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); - ConfigurationPolicyPrefStore* new_device_management_pref_store( - ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( - profile_)); - ConfigurationPolicyPrefStore* new_recommended_pref_store( - ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); - BrowserThread::ID current_thread_id; - CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - NewRunnableMethod(this, - &PrefValueStore::RefreshPolicyPrefsOnFileThread, - current_thread_id, - new_managed_platform_pref_store, - new_device_management_pref_store, - new_recommended_pref_store)); -} - -void PrefValueStore::RefreshPolicyPrefsCompletion( - policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, - policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, - policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { - // Determine the paths of all the changed preferences values in the three - // policy-related stores (managed platform, device management and - // recommended). - DictionaryValue* managed_platform_prefs_before( - static_cast<policy::ConfigurationPolicyPrefStore*>( - GetPrefStore(MANAGED_PLATFORM_STORE))->prefs()); - DictionaryValue* managed_platform_prefs_after( - new_managed_platform_pref_store->prefs()); - DictionaryValue* device_management_prefs_before( - static_cast<policy::ConfigurationPolicyPrefStore*>( - GetPrefStore(DEVICE_MANAGEMENT_STORE))->prefs()); - DictionaryValue* device_management_prefs_after( - new_device_management_pref_store->prefs()); - DictionaryValue* recommended_prefs_before( - static_cast<policy::ConfigurationPolicyPrefStore*>( - GetPrefStore(RECOMMENDED_STORE))->prefs()); - DictionaryValue* recommended_prefs_after(new_recommended_pref_store->prefs()); - - std::vector<std::string> changed_managed_platform_paths; - managed_platform_prefs_before->GetDifferingPaths( - managed_platform_prefs_after, - &changed_managed_platform_paths); - - std::vector<std::string> changed_device_management_paths; - device_management_prefs_before->GetDifferingPaths( - device_management_prefs_after, - &changed_device_management_paths); - - std::vector<std::string> changed_recommended_paths; - recommended_prefs_before->GetDifferingPaths( - recommended_prefs_after, - &changed_recommended_paths); - - // Merge all three vectors of changed value paths together, filtering - // duplicates in a post-processing step. - std::vector<std::string> all_changed_managed_platform_paths( - changed_managed_platform_paths.size() + - changed_device_management_paths.size()); - - std::vector<std::string>::iterator last_insert = - std::merge(changed_managed_platform_paths.begin(), - changed_managed_platform_paths.end(), - changed_device_management_paths.begin(), - changed_device_management_paths.end(), - all_changed_managed_platform_paths.begin()); - all_changed_managed_platform_paths.resize( - last_insert - all_changed_managed_platform_paths.begin()); - - std::vector<std::string> changed_paths( - all_changed_managed_platform_paths.size() + - changed_recommended_paths.size()); - last_insert = std::merge(all_changed_managed_platform_paths.begin(), - all_changed_managed_platform_paths.end(), - changed_recommended_paths.begin(), - changed_recommended_paths.end(), - changed_paths.begin()); - changed_paths.resize(last_insert - changed_paths.begin()); - - last_insert = unique(changed_paths.begin(), changed_paths.end()); - changed_paths.resize(last_insert - changed_paths.begin()); - - // Replace the old stores with the new and send notification of the changed - // preferences. - InitPrefStore(MANAGED_PLATFORM_STORE, new_managed_platform_pref_store); - InitPrefStore(DEVICE_MANAGEMENT_STORE, new_device_management_pref_store); - InitPrefStore(RECOMMENDED_STORE, new_recommended_pref_store); - - std::vector<std::string>::const_iterator current; - for (current = changed_paths.begin(); - current != changed_paths.end(); - ++current) { - pref_notifier_->OnPreferenceChanged(current->c_str()); - } -} - -void PrefValueStore::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::POLICY_CHANGED) - RefreshPolicyPrefs(); -} - void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type, const std::string& key) { NotifyPrefChanged(key.c_str(), type); diff --git a/chrome/browser/prefs/pref_value_store.h b/chrome/browser/prefs/pref_value_store.h index fec16b4..87bf4f7 100644 --- a/chrome/browser/prefs/pref_value_store.h +++ b/chrome/browser/prefs/pref_value_store.h @@ -11,14 +11,11 @@ #include <vector> #include "base/basictypes.h" -#include "base/callback.h" #include "base/gtest_prod_util.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/values.h" #include "chrome/browser/browser_thread.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" #include "chrome/common/pref_store.h" class FilePath; @@ -26,11 +23,6 @@ class PrefNotifier; class PrefStore; class Profile; -// TODO(danno, mnissler): Remove after policy refresh cleanup. -namespace policy { -class ConfigurationPolicyPrefStore; -} - // The PrefValueStore manages various sources of values for Preferences // (e.g., configuration policies, extensions, and user settings). It returns // the value of a Preference from the source with the highest priority, and @@ -38,8 +30,7 @@ class ConfigurationPolicyPrefStore; // // Unless otherwise explicitly noted, all of the methods of this class must // be called on the UI thread. -class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, - public NotificationObserver { +class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> { public: // In decreasing order of precedence: // |managed_platform_prefs| contains all managed platform (non-cloud policy) @@ -62,10 +53,6 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // the policy pref stores for new ones, so the |profile| pointer needs to be // kept around for then. It is safe to pass a NULL pointer for local state // preferences. - // - // TODO(mnissler, danno): Refactor the pref store interface and refresh logic - // so refreshes can be handled by the pref store itself without swapping - // stores. This way we can get rid of the profile pointer here. PrefValueStore(PrefStore* managed_platform_prefs, PrefStore* device_management_prefs, PrefStore* extension_prefs, @@ -73,8 +60,7 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, PrefStore* user_prefs, PrefStore* recommended_prefs, PrefStore* default_prefs, - PrefNotifier* pref_notifier, - Profile* profile); + PrefNotifier* pref_notifier); virtual ~PrefValueStore(); // Gets the value for the given preference name that has a valid value type; @@ -223,32 +209,6 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // controlling the pref has changed. void NotifyPrefChanged(const char* path, PrefStoreType new_store); - // Called as a result of a notification of policy change. Triggers a reload of - // managed platform, device management and recommended preferences from policy - // from a Task on the FILE thread. - void RefreshPolicyPrefs(); - - // Called during policy refresh after ReadPrefs completes on the thread - // that initiated the policy refresh. RefreshPolicyPrefsCompletion takes - // ownership of the |callback| object. - void RefreshPolicyPrefsCompletion( - policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, - policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, - policy::ConfigurationPolicyPrefStore* new_recommended_pref_store); - - // Called during policy refresh to do the ReadPrefs on the FILE thread. - // RefreshPolicyPrefsOnFileThread takes ownership of the |callback| object. - void RefreshPolicyPrefsOnFileThread( - BrowserThread::ID calling_thread_id, - policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, - policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, - policy::ConfigurationPolicyPrefStore* new_recommended_pref_store); - - // NotificationObserver methods: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - // Called from the PrefStoreKeeper implementation when a pref value for |key| // changed in the pref store for |type|. void OnPrefValueChanged(PrefStoreType type, const std::string& key); @@ -284,14 +244,6 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // A mapping of preference names to their registered types. PrefTypeMap pref_types_; - // The associated profile, in case this value store is associated with a - // profile pref service. Used for recreating the device management pref store - // upon policy refresh. - Profile* profile_; - - // TODO(mnissler): Remove this after cleaning up policy refresh handling. - NotificationRegistrar registrar_; - DISALLOW_COPY_AND_ASSIGN(PrefValueStore); }; diff --git a/chrome/browser/prefs/pref_value_store_unittest.cc b/chrome/browser/prefs/pref_value_store_unittest.cc index b78e0fc..5c0fa53 100644 --- a/chrome/browser/prefs/pref_value_store_unittest.cc +++ b/chrome/browser/prefs/pref_value_store_unittest.cc @@ -99,7 +99,7 @@ class PrefValueStoreTest : public testing::Test { CreateRecommendedPrefs(); CreateDefaultPrefs(); - // Create a new pref-value-store. + // Create a fresh PrefValueStore. pref_value_store_ = new PrefValueStore( managed_platform_pref_store_, device_management_pref_store_, @@ -108,8 +108,7 @@ class PrefValueStoreTest : public testing::Test { user_pref_store_, recommended_pref_store_, default_pref_store_, - &pref_notifier_, - NULL); + &pref_notifier_); // Register prefs with the PrefValueStore. pref_value_store_->RegisterPreferenceType(prefs::kApplicationLocale, @@ -619,222 +618,3 @@ TEST_F(PrefValueStoreTest, PrefValueFromDefaultStore) { EXPECT_FALSE( pref_value_store_->PrefValueFromDefaultStore(prefs::kMissingPref)); } - -// TODO(mnissler, danno): Clean this up when refactoring -// ConfigurationPolicyPrefStore. -class PrefValueStorePolicyRefreshTest : public testing::Test { - protected: - // Records preference changes. - class PrefChangeRecorder { - public: - void Record(const std::string& pref_name) { - changed_prefs_.insert(pref_name); - } - - void Clear() { - changed_prefs_.clear(); - } - - const std::set<std::string>& changed_prefs() { return changed_prefs_; } - - private: - std::set<std::string> changed_prefs_; - }; - - virtual void SetUp() { - using policy::ConfigurationPolicyPrefStore; - - ui_thread_.reset(new BrowserThread(BrowserThread::UI, &loop_)), - file_thread_.reset(new BrowserThread(BrowserThread::FILE, &loop_)), - policy_provider_.reset(new policy::DummyConfigurationPolicyProvider( - policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList())); - - ConfigurationPolicyPrefStore* managed_store = - NewConfigurationPolicyPrefStore(); - managed_store->prefs()->SetString(prefs::kHomePage, - managed_platform_pref::kHomepageValue); - expected_differing_paths_.insert(prefs::kHomePage); - - ConfigurationPolicyPrefStore* device_management_store = - NewConfigurationPolicyPrefStore(); - device_management_store->prefs()->SetString( - prefs::kDefaultSearchProviderName, - device_management_pref::kSearchProviderNameValue); - expected_differing_paths_.insert("default_search_provider"); - expected_differing_paths_.insert(prefs::kDefaultSearchProviderName); - - ConfigurationPolicyPrefStore* recommended_store = - NewConfigurationPolicyPrefStore(); - recommended_store->prefs()->SetInteger(prefs::kStabilityLaunchCount, - recommended_pref::kStabilityLaunchCountValue); - recommended_store->prefs()->SetBoolean(prefs::kRecommendedPref, - recommended_pref::kRecommendedPrefValue); - - expected_differing_paths_.insert("this"); - expected_differing_paths_.insert("this.pref"); - expected_differing_paths_.insert(prefs::kRecommendedPref); - expected_differing_paths_.insert("user_experience_metrics"); - expected_differing_paths_.insert("user_experience_metrics.stability"); - expected_differing_paths_.insert(prefs::kStabilityLaunchCount); - - pref_value_store_ = new PrefValueStore( - managed_store, - device_management_store, - NULL, - NULL, - new TestingPrefStore(), - recommended_store, - NULL, - &pref_notifier_, - NULL); - } - - virtual void TearDown() { - loop_.RunAllPending(); - pref_value_store_ = NULL; - file_thread_.reset(); - ui_thread_.reset(); - } - - // Creates a new ConfigurationPolicyPrefStore for testing. - policy::ConfigurationPolicyPrefStore* NewConfigurationPolicyPrefStore() { - return new policy::ConfigurationPolicyPrefStore(policy_provider_.get()); - } - - // A vector of the preferences paths in policy PrefStores that are set at the - // beginning of a test. Can be modified by the test to track changes that it - // makes to the preferences stored in the managed and recommended PrefStores. - std::set<std::string> expected_differing_paths_; - - MessageLoop loop_; - MockPrefNotifier pref_notifier_; - scoped_refptr<PrefValueStore> pref_value_store_; - - private: - scoped_ptr<BrowserThread> ui_thread_; - scoped_ptr<BrowserThread> file_thread_; - - scoped_ptr<policy::DummyConfigurationPolicyProvider> policy_provider_; -}; - -TEST_F(PrefValueStorePolicyRefreshTest, TestPolicyRefresh) { - // pref_value_store_ is initialized by PrefValueStoreTest to have values in - // the managed platform, device management and recommended stores. By - // replacing them with dummy stores, all of the paths of the prefs originally - // in the managed platform, device management and recommended stores should - // change. - pref_value_store_->RefreshPolicyPrefs(); - - PrefChangeRecorder recorder; - EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)) - .WillRepeatedly(Invoke(&recorder, &PrefChangeRecorder::Record)); - loop_.RunAllPending(); - EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); -} - -TEST_F(PrefValueStorePolicyRefreshTest, TestRefreshPolicyPrefsCompletion) { - using policy::ConfigurationPolicyPrefStore; - PrefChangeRecorder recorder; - EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)) - .WillRepeatedly(Invoke(&recorder, &PrefChangeRecorder::Record)); - - // Test changed preferences in the managed platform store and removed - // preferences in the recommended store. In addition to "homepage", the other - // prefs that are set by default in the test class are removed by the - // DummyStore. - scoped_ptr<ConfigurationPolicyPrefStore> new_managed_platform_store( - NewConfigurationPolicyPrefStore()); - new_managed_platform_store->prefs()->SetString("homepage", - "some other changed homepage"); - - recorder.Clear(); - pref_value_store_->RefreshPolicyPrefsCompletion( - new_managed_platform_store.release(), - NewConfigurationPolicyPrefStore(), - NewConfigurationPolicyPrefStore()); - EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); - - // Test properties that have been removed from the managed platform store. - // Homepage is still set in managed prefs. - expected_differing_paths_.clear(); - expected_differing_paths_.insert(prefs::kHomePage); - - recorder.Clear(); - pref_value_store_->RefreshPolicyPrefsCompletion( - NewConfigurationPolicyPrefStore(), - NewConfigurationPolicyPrefStore(), - NewConfigurationPolicyPrefStore()); - EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); - - // Test properties that are added to the device management store. - expected_differing_paths_.clear(); - expected_differing_paths_.insert(prefs::kHomePage); - scoped_ptr<ConfigurationPolicyPrefStore> new_device_management_store( - NewConfigurationPolicyPrefStore()); - new_device_management_store->prefs()->SetString( - "homepage", "some other changed homepage"); - - recorder.Clear(); - pref_value_store_->RefreshPolicyPrefsCompletion( - NewConfigurationPolicyPrefStore(), - new_device_management_store.release(), - NewConfigurationPolicyPrefStore()); - EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); - - // Test properties that are added to the recommended store. - scoped_ptr<ConfigurationPolicyPrefStore> new_recommended_store( - NewConfigurationPolicyPrefStore()); - new_recommended_store->prefs()->SetString("homepage", - "some other changed homepage 2"); - expected_differing_paths_.clear(); - expected_differing_paths_.insert(prefs::kHomePage); - - recorder.Clear(); - pref_value_store_->RefreshPolicyPrefsCompletion( - NewConfigurationPolicyPrefStore(), - NewConfigurationPolicyPrefStore(), - new_recommended_store.release()); - EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); - - // Test adding a multi-key path. - new_managed_platform_store.reset(NewConfigurationPolicyPrefStore()); - new_managed_platform_store->prefs()->SetString("segment1.segment2", "value"); - expected_differing_paths_.clear(); - expected_differing_paths_.insert(prefs::kHomePage); - expected_differing_paths_.insert("segment1"); - expected_differing_paths_.insert("segment1.segment2"); - - recorder.Clear(); - pref_value_store_->RefreshPolicyPrefsCompletion( - new_managed_platform_store.release(), - NewConfigurationPolicyPrefStore(), - NewConfigurationPolicyPrefStore()); - EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); -} - -TEST_F(PrefValueStorePolicyRefreshTest, TestConcurrentPolicyRefresh) { - PrefChangeRecorder recorder; - EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)) - .WillRepeatedly(Invoke(&recorder, &PrefChangeRecorder::Record)); - - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - pref_value_store_.get(), - &PrefValueStore::RefreshPolicyPrefs)); - - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - pref_value_store_.get(), - &PrefValueStore::RefreshPolicyPrefs)); - - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - pref_value_store_.get(), - &PrefValueStore::RefreshPolicyPrefs)); - - loop_.RunAllPending(); - EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); -} diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 3c50a76..7f0ad13 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1280,6 +1280,7 @@ 'browser/prefs/pref_notifier_impl_unittest.cc', 'browser/prefs/pref_service_unittest.cc', 'browser/prefs/pref_set_observer_unittest.cc', + 'browser/prefs/pref_value_map_unittest.cc', 'browser/prefs/pref_value_store_unittest.cc', 'browser/prefs/proxy_prefs_unittest.cc', 'browser/prefs/session_startup_pref_unittest.cc', diff --git a/chrome/common/pref_store_observer_mock.h b/chrome/common/pref_store_observer_mock.h index 72e27a1..2a49284 100644 --- a/chrome/common/pref_store_observer_mock.h +++ b/chrome/common/pref_store_observer_mock.h @@ -10,8 +10,8 @@ #include "chrome/common/pref_store.h" #include "testing/gmock/include/gmock/gmock.h" -// A gmock-ified implementation of PrefStore::ObserverInterface. -class PrefStoreObserverMock : public PrefStore::ObserverInterface { +// A gmock-ified implementation of PrefStore::Observer. +class PrefStoreObserverMock : public PrefStore::Observer { public: PrefStoreObserverMock() {} virtual ~PrefStoreObserverMock() {} diff --git a/chrome/test/testing_pref_service.cc b/chrome/test/testing_pref_service.cc index 66342bc..acb4be2 100644 --- a/chrome/test/testing_pref_service.cc +++ b/chrome/test/testing_pref_service.cc @@ -19,7 +19,6 @@ TestingPrefService::TestingPrefService() NULL, NULL, user_prefs_ = new TestingPrefStore(), - NULL, NULL) { } |