| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/path_service.h" | 8 #include "base/path_service.h" |
| 9 #include "base/scoped_temp_dir.h" |
| 9 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| 10 #include "chrome/browser/policy/config_dir_policy_provider.h" | 11 #include "chrome/browser/policy/config_dir_policy_provider.h" |
| 11 #include "chrome/browser/policy/configuration_policy_pref_store.h" | 12 #include "chrome/browser/policy/configuration_policy_pref_store.h" |
| 12 #include "chrome/browser/policy/mock_configuration_policy_store.h" | 13 #include "chrome/browser/policy/mock_configuration_policy_store.h" |
| 13 #include "chrome/common/json_value_serializer.h" | 14 #include "chrome/common/json_value_serializer.h" |
| 14 #include "chrome/common/policy_constants.h" | 15 #include "chrome/common/policy_constants.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 using testing::Mock; | |
| 19 | |
| 20 namespace policy { | 18 namespace policy { |
| 21 | 19 |
| 22 // Shorter reload intervals for testing PolicyDirWatcher. | |
| 23 const int kSettleIntervalSecondsForTesting = 0; | |
| 24 const int kReloadIntervalMinutesForTesting = 1; | |
| 25 | |
| 26 template<typename BASE> | 20 template<typename BASE> |
| 27 class ConfigDirPolicyProviderTestBase : public BASE { | 21 class ConfigDirPolicyProviderTestBase : public BASE { |
| 28 protected: | 22 protected: |
| 29 ConfigDirPolicyProviderTestBase() | 23 ConfigDirPolicyProviderTestBase() {} |
| 30 : ui_thread_(BrowserThread::UI, &loop_), | |
| 31 file_thread_(BrowserThread::FILE, &loop_) {} | |
| 32 | 24 |
| 33 virtual void SetUp() { | 25 virtual void SetUp() { |
| 34 // Determine the directory to use for testing. | 26 ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); |
| 35 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &test_dir_)); | |
| 36 test_dir_ = | |
| 37 test_dir_.Append(FILE_PATH_LITERAL("ConfigDirPolicyProviderTest")); | |
| 38 | |
| 39 // Make sure the directory is fresh. | |
| 40 file_util::Delete(test_dir_, true); | |
| 41 file_util::CreateDirectory(test_dir_); | |
| 42 ASSERT_TRUE(file_util::DirectoryExists(test_dir_)); | |
| 43 } | |
| 44 | |
| 45 virtual void TearDown() { | |
| 46 loop_.RunAllPending(); | |
| 47 // Clean up test directory. | |
| 48 ASSERT_TRUE(file_util::Delete(test_dir_, true)); | |
| 49 ASSERT_FALSE(file_util::PathExists(test_dir_)); | |
| 50 } | 27 } |
| 51 | 28 |
| 52 // JSON-encode a dictionary and write it to a file. | 29 // JSON-encode a dictionary and write it to a file. |
| 53 void WriteConfigFile(const DictionaryValue& dict, | 30 void WriteConfigFile(const DictionaryValue& dict, |
| 54 const std::string& file_name) { | 31 const std::string& file_name) { |
| 55 std::string data; | 32 std::string data; |
| 56 JSONStringValueSerializer serializer(&data); | 33 JSONStringValueSerializer serializer(&data); |
| 57 serializer.Serialize(dict); | 34 serializer.Serialize(dict); |
| 58 FilePath file_path(test_dir_.AppendASCII(file_name)); | 35 FilePath file_path(test_dir().AppendASCII(file_name)); |
| 59 ASSERT_TRUE(file_util::WriteFile(file_path, data.c_str(), data.size())); | 36 ASSERT_TRUE(file_util::WriteFile(file_path, data.c_str(), data.size())); |
| 60 } | 37 } |
| 61 | 38 |
| 62 FilePath test_dir_; | 39 const FilePath& test_dir() { return test_dir_.path(); } |
| 63 MessageLoop loop_; | 40 |
| 64 BrowserThread ui_thread_; | 41 private: |
| 65 BrowserThread file_thread_; | 42 ScopedTempDir test_dir_; |
| 66 }; | 43 }; |
| 67 | 44 |
| 68 // A mock provider that allows us to capture reload notifications. | 45 class ConfigDirPolicyLoaderTest |
| 69 class MockConfigDirPolicyProvider : public ConfigDirPolicyProvider { | 46 : public ConfigDirPolicyProviderTestBase<testing::Test> { |
| 70 public: | |
| 71 explicit MockConfigDirPolicyProvider(const FilePath& config_dir_) | |
| 72 : ConfigDirPolicyProvider( | |
| 73 ConfigurationPolicyPrefStore::GetChromePolicyValueMap(), | |
| 74 config_dir_) { | |
| 75 } | |
| 76 | |
| 77 MOCK_METHOD0(NotifyStoreOfPolicyChange, void()); | |
| 78 }; | 47 }; |
| 79 | 48 |
| 80 class PolicyDirLoaderTest | 49 // The preferences dictionary is expected to be empty when there are no files to |
| 81 : public ConfigDirPolicyProviderTestBase<testing::Test> { | 50 // load. |
| 82 protected: | 51 TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsEmpty) { |
| 83 PolicyDirLoaderTest() {} | 52 ConfigDirPolicyLoader loader(test_dir()); |
| 53 scoped_ptr<DictionaryValue> policy(loader.Load()); |
| 54 EXPECT_TRUE(policy.get()); |
| 55 EXPECT_TRUE(policy->empty()); |
| 56 } |
| 84 | 57 |
| 85 virtual void SetUp() { | 58 // Reading from a non-existent directory should result in an empty preferences |
| 86 ConfigDirPolicyProviderTestBase<testing::Test>::SetUp(); | 59 // dictionary. |
| 87 provider_.reset(new MockConfigDirPolicyProvider(test_dir_)); | 60 TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsNonExistentDirectory) { |
| 88 } | 61 FilePath non_existent_dir(test_dir().Append(FILE_PATH_LITERAL("not_there"))); |
| 62 ConfigDirPolicyLoader loader(non_existent_dir); |
| 63 scoped_ptr<DictionaryValue> policy(loader.Load()); |
| 64 EXPECT_TRUE(policy.get()); |
| 65 EXPECT_TRUE(policy->empty()); |
| 66 } |
| 89 | 67 |
| 90 virtual void TearDown() { | 68 // Test reading back a single preference value. |
| 91 provider_.reset(NULL); | 69 TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsSinglePref) { |
| 92 ConfigDirPolicyProviderTestBase<testing::Test>::TearDown(); | |
| 93 } | |
| 94 | |
| 95 scoped_ptr<MockConfigDirPolicyProvider> provider_; | |
| 96 }; | |
| 97 | |
| 98 TEST_F(PolicyDirLoaderTest, BasicLoad) { | |
| 99 DictionaryValue test_dict; | 70 DictionaryValue test_dict; |
| 100 test_dict.SetString("HomepageLocation", "http://www.google.com"); | 71 test_dict.SetString("HomepageLocation", "http://www.google.com"); |
| 101 WriteConfigFile(test_dict, "config_file"); | 72 WriteConfigFile(test_dict, "config_file"); |
| 102 | 73 |
| 103 scoped_refptr<PolicyDirLoader> loader_( | 74 ConfigDirPolicyLoader loader(test_dir()); |
| 104 new PolicyDirLoader(provider_->AsWeakPtr(), test_dir_, | 75 scoped_ptr<DictionaryValue> policy(loader.Load()); |
| 105 kSettleIntervalSecondsForTesting, | |
| 106 kReloadIntervalMinutesForTesting)); | |
| 107 scoped_ptr<DictionaryValue> policy(loader_->GetPolicy()); | |
| 108 EXPECT_TRUE(policy.get()); | 76 EXPECT_TRUE(policy.get()); |
| 109 EXPECT_EQ(1U, policy->size()); | 77 EXPECT_TRUE(policy->Equals(&test_dict)); |
| 110 | |
| 111 std::string str_value; | |
| 112 EXPECT_TRUE(policy->GetString("HomepageLocation", &str_value)); | |
| 113 EXPECT_EQ("http://www.google.com", str_value); | |
| 114 | |
| 115 loader_->Stop(); | |
| 116 } | |
| 117 | |
| 118 TEST_F(PolicyDirLoaderTest, TestRefresh) { | |
| 119 scoped_refptr<PolicyDirLoader> loader_( | |
| 120 new PolicyDirLoader(provider_->AsWeakPtr(), test_dir_, | |
| 121 kSettleIntervalSecondsForTesting, | |
| 122 kReloadIntervalMinutesForTesting)); | |
| 123 scoped_ptr<DictionaryValue> policy(loader_->GetPolicy()); | |
| 124 EXPECT_TRUE(policy.get()); | |
| 125 EXPECT_EQ(0U, policy->size()); | |
| 126 | |
| 127 DictionaryValue test_dict; | |
| 128 test_dict.SetString("HomepageLocation", "http://www.google.com"); | |
| 129 WriteConfigFile(test_dict, "config_file"); | |
| 130 | |
| 131 EXPECT_CALL(*provider_, NotifyStoreOfPolicyChange()).Times(1); | |
| 132 loader_->OnFilePathChanged(test_dir_.AppendASCII("config_file")); | |
| 133 | |
| 134 // Run the loop. The refresh should be handled immediately since the settle | |
| 135 // interval has been disabled. | |
| 136 loop_.RunAllPending(); | |
| 137 Mock::VerifyAndClearExpectations(provider_.get()); | |
| 138 | |
| 139 policy.reset(loader_->GetPolicy()); | |
| 140 EXPECT_TRUE(policy.get()); | |
| 141 EXPECT_EQ(1U, policy->size()); | |
| 142 | |
| 143 std::string str_value; | |
| 144 EXPECT_TRUE(policy->GetString("HomepageLocation", &str_value)); | |
| 145 EXPECT_EQ("http://www.google.com", str_value); | |
| 146 | |
| 147 loader_->Stop(); | |
| 148 } | |
| 149 | |
| 150 template<typename BASE> | |
| 151 class ConfigDirPolicyProviderTestWithMockStore | |
| 152 : public ConfigDirPolicyProviderTestBase<BASE> { | |
| 153 protected: | |
| 154 virtual void SetUp() { | |
| 155 ConfigDirPolicyProviderTestBase<BASE>::SetUp(); | |
| 156 // Create a fresh policy store mock. | |
| 157 policy_store_.reset(new MockConfigurationPolicyStore()); | |
| 158 } | |
| 159 | |
| 160 scoped_ptr<MockConfigurationPolicyStore> policy_store_; | |
| 161 }; | |
| 162 | |
| 163 class ConfigDirPolicyProviderTest | |
| 164 : public ConfigDirPolicyProviderTestWithMockStore<testing::Test> { | |
| 165 }; | |
| 166 | |
| 167 // The preferences dictionary is expected to be empty when there are no files to | |
| 168 // load. | |
| 169 TEST_F(ConfigDirPolicyProviderTest, ReadPrefsEmpty) { | |
| 170 ConfigDirPolicyProvider provider( | |
| 171 ConfigurationPolicyPrefStore::GetChromePolicyValueMap(), test_dir_); | |
| 172 EXPECT_TRUE(provider.Provide(policy_store_.get())); | |
| 173 EXPECT_TRUE(policy_store_->policy_map().empty()); | |
| 174 } | |
| 175 | |
| 176 // Reading from a non-existent directory should result in an empty preferences | |
| 177 // dictionary. | |
| 178 TEST_F(ConfigDirPolicyProviderTest, ReadPrefsNonExistentDirectory) { | |
| 179 FilePath non_existent_dir(test_dir_.Append(FILE_PATH_LITERAL("not_there"))); | |
| 180 ConfigDirPolicyProvider provider( | |
| 181 ConfigurationPolicyPrefStore::GetChromePolicyValueMap(), | |
| 182 non_existent_dir); | |
| 183 EXPECT_TRUE(provider.Provide(policy_store_.get())); | |
| 184 EXPECT_TRUE(policy_store_->policy_map().empty()); | |
| 185 } | |
| 186 | |
| 187 // Test reading back a single preference value. | |
| 188 TEST_F(ConfigDirPolicyProviderTest, ReadPrefsSinglePref) { | |
| 189 DictionaryValue test_dict; | |
| 190 test_dict.SetString("HomepageLocation", "http://www.google.com"); | |
| 191 WriteConfigFile(test_dict, "config_file"); | |
| 192 ConfigDirPolicyProvider provider( | |
| 193 ConfigurationPolicyPrefStore::GetChromePolicyValueMap(), test_dir_); | |
| 194 | |
| 195 EXPECT_TRUE(provider.Provide(policy_store_.get())); | |
| 196 EXPECT_EQ(1U, policy_store_->policy_map().size()); | |
| 197 const Value* value = | |
| 198 policy_store_->Get(ConfigurationPolicyStore::kPolicyHomePage); | |
| 199 ASSERT_TRUE(value); | |
| 200 std::string str_value; | |
| 201 EXPECT_TRUE(value->GetAsString(&str_value)); | |
| 202 EXPECT_EQ("http://www.google.com", str_value); | |
| 203 } | 78 } |
| 204 | 79 |
| 205 // Test merging values from different files. | 80 // Test merging values from different files. |
| 206 TEST_F(ConfigDirPolicyProviderTest, ReadPrefsMergePrefs) { | 81 TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsMergePrefs) { |
| 207 // Write a bunch of data files in order to increase the chance to detect the | 82 // Write a bunch of data files in order to increase the chance to detect the |
| 208 // provider not respecting lexicographic ordering when reading them. Since the | 83 // provider not respecting lexicographic ordering when reading them. Since the |
| 209 // filesystem may return files in arbitrary order, there is no way to be sure, | 84 // filesystem may return files in arbitrary order, there is no way to be sure, |
| 210 // but this is better than nothing. | 85 // but this is better than nothing. |
| 211 DictionaryValue test_dict_bar; | 86 DictionaryValue test_dict_bar; |
| 212 test_dict_bar.SetString("HomepageLocation", "http://bar.com"); | 87 test_dict_bar.SetString("HomepageLocation", "http://bar.com"); |
| 213 for (unsigned int i = 1; i <= 4; ++i) | 88 for (unsigned int i = 1; i <= 4; ++i) |
| 214 WriteConfigFile(test_dict_bar, base::IntToString(i)); | 89 WriteConfigFile(test_dict_bar, base::IntToString(i)); |
| 215 DictionaryValue test_dict_foo; | 90 DictionaryValue test_dict_foo; |
| 216 test_dict_foo.SetString("HomepageLocation", "http://foo.com"); | 91 test_dict_foo.SetString("HomepageLocation", "http://foo.com"); |
| 217 WriteConfigFile(test_dict_foo, "9"); | 92 WriteConfigFile(test_dict_foo, "9"); |
| 218 for (unsigned int i = 5; i <= 8; ++i) | 93 for (unsigned int i = 5; i <= 8; ++i) |
| 219 WriteConfigFile(test_dict_bar, base::IntToString(i)); | 94 WriteConfigFile(test_dict_bar, base::IntToString(i)); |
| 220 ConfigDirPolicyProvider provider( | |
| 221 ConfigurationPolicyPrefStore::GetChromePolicyValueMap(), test_dir_); | |
| 222 | 95 |
| 223 EXPECT_TRUE(provider.Provide(policy_store_.get())); | 96 ConfigDirPolicyLoader loader(test_dir()); |
| 224 EXPECT_EQ(1U, policy_store_->policy_map().size()); | 97 scoped_ptr<DictionaryValue> policy(loader.Load()); |
| 225 const Value* value = | 98 EXPECT_TRUE(policy.get()); |
| 226 policy_store_->Get(ConfigurationPolicyStore::kPolicyHomePage); | 99 EXPECT_TRUE(policy->Equals(&test_dict_foo)); |
| 227 ASSERT_TRUE(value); | |
| 228 std::string str_value; | |
| 229 EXPECT_TRUE(value->GetAsString(&str_value)); | |
| 230 EXPECT_EQ("http://foo.com", str_value); | |
| 231 } | 100 } |
| 232 | 101 |
| 233 // Holds policy type, corresponding policy key string and a valid value for use | 102 // Holds policy type, corresponding policy key string and a valid value for use |
| 234 // in parametrized value tests. | 103 // in parametrized value tests. |
| 235 class ValueTestParams { | 104 class ValueTestParams { |
| 236 public: | 105 public: |
| 237 // Assumes ownership of |test_value|. | 106 // Assumes ownership of |test_value|. |
| 238 ValueTestParams(ConfigurationPolicyStore::PolicyType type, | 107 ValueTestParams(ConfigurationPolicyStore::PolicyType type, |
| 239 const char* policy_key, | 108 const char* policy_key, |
| 240 Value* test_value) | 109 Value* test_value) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 | 160 |
| 292 private: | 161 private: |
| 293 ConfigurationPolicyStore::PolicyType type_; | 162 ConfigurationPolicyStore::PolicyType type_; |
| 294 const char* policy_key_; | 163 const char* policy_key_; |
| 295 scoped_ptr<Value> test_value_; | 164 scoped_ptr<Value> test_value_; |
| 296 }; | 165 }; |
| 297 | 166 |
| 298 // Tests whether the provider correctly reads a value from the file and forwards | 167 // Tests whether the provider correctly reads a value from the file and forwards |
| 299 // it to the store. | 168 // it to the store. |
| 300 class ConfigDirPolicyProviderValueTest | 169 class ConfigDirPolicyProviderValueTest |
| 301 : public ConfigDirPolicyProviderTestWithMockStore< | 170 : public ConfigDirPolicyProviderTestBase< |
| 302 testing::TestWithParam<ValueTestParams> > { | 171 testing::TestWithParam<ValueTestParams> > { |
| 172 protected: |
| 173 ConfigDirPolicyProviderValueTest() |
| 174 : ui_thread_(BrowserThread::UI, &loop_), |
| 175 file_thread_(BrowserThread::FILE, &loop_) {} |
| 176 |
| 177 virtual void TearDown() { |
| 178 loop_.RunAllPending(); |
| 179 } |
| 180 |
| 181 MockConfigurationPolicyStore policy_store_; |
| 182 |
| 183 private: |
| 184 MessageLoop loop_; |
| 185 BrowserThread ui_thread_; |
| 186 BrowserThread file_thread_; |
| 303 }; | 187 }; |
| 304 | 188 |
| 305 TEST_P(ConfigDirPolicyProviderValueTest, Default) { | 189 TEST_P(ConfigDirPolicyProviderValueTest, Default) { |
| 306 ConfigDirPolicyProvider provider( | 190 ConfigDirPolicyProvider provider( |
| 307 ConfigurationPolicyPrefStore::GetChromePolicyValueMap(), test_dir_); | 191 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), |
| 308 EXPECT_TRUE(provider.Provide(policy_store_.get())); | 192 test_dir()); |
| 309 EXPECT_TRUE(policy_store_->policy_map().empty()); | 193 EXPECT_TRUE(provider.Provide(&policy_store_)); |
| 194 EXPECT_TRUE(policy_store_.policy_map().empty()); |
| 310 } | 195 } |
| 311 | 196 |
| 312 TEST_P(ConfigDirPolicyProviderValueTest, NullValue) { | 197 TEST_P(ConfigDirPolicyProviderValueTest, NullValue) { |
| 313 DictionaryValue dict; | 198 DictionaryValue dict; |
| 314 dict.Set(GetParam().policy_key(), Value::CreateNullValue()); | 199 dict.Set(GetParam().policy_key(), Value::CreateNullValue()); |
| 315 WriteConfigFile(dict, "empty"); | 200 WriteConfigFile(dict, "empty"); |
| 316 ConfigDirPolicyProvider provider( | 201 ConfigDirPolicyProvider provider( |
| 317 ConfigurationPolicyPrefStore::GetChromePolicyValueMap(), test_dir_); | 202 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), |
| 318 EXPECT_TRUE(provider.Provide(policy_store_.get())); | 203 test_dir()); |
| 319 EXPECT_TRUE(policy_store_->policy_map().empty()); | 204 EXPECT_TRUE(provider.Provide(&policy_store_)); |
| 205 EXPECT_TRUE(policy_store_.policy_map().empty()); |
| 320 } | 206 } |
| 321 | 207 |
| 322 TEST_P(ConfigDirPolicyProviderValueTest, TestValue) { | 208 TEST_P(ConfigDirPolicyProviderValueTest, TestValue) { |
| 323 DictionaryValue dict; | 209 DictionaryValue dict; |
| 324 dict.Set(GetParam().policy_key(), GetParam().test_value()->DeepCopy()); | 210 dict.Set(GetParam().policy_key(), GetParam().test_value()->DeepCopy()); |
| 325 WriteConfigFile(dict, "policy"); | 211 WriteConfigFile(dict, "policy"); |
| 326 ConfigDirPolicyProvider provider( | 212 ConfigDirPolicyProvider provider( |
| 327 ConfigurationPolicyPrefStore::GetChromePolicyValueMap(), test_dir_); | 213 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), |
| 328 EXPECT_TRUE(provider.Provide(policy_store_.get())); | 214 test_dir()); |
| 329 EXPECT_EQ(1U, policy_store_->policy_map().size()); | 215 EXPECT_TRUE(provider.Provide(&policy_store_)); |
| 330 const Value* value = policy_store_->Get(GetParam().type()); | 216 EXPECT_EQ(1U, policy_store_.policy_map().size()); |
| 217 const Value* value = policy_store_.Get(GetParam().type()); |
| 331 ASSERT_TRUE(value); | 218 ASSERT_TRUE(value); |
| 332 EXPECT_TRUE(GetParam().test_value()->Equals(value)); | 219 EXPECT_TRUE(GetParam().test_value()->Equals(value)); |
| 333 } | 220 } |
| 334 | 221 |
| 335 // Test parameters for all supported policies. | 222 // Test parameters for all supported policies. |
| 336 INSTANTIATE_TEST_CASE_P( | 223 INSTANTIATE_TEST_CASE_P( |
| 337 ConfigDirPolicyProviderValueTestInstance, | 224 ConfigDirPolicyProviderValueTestInstance, |
| 338 ConfigDirPolicyProviderValueTest, | 225 ConfigDirPolicyProviderValueTest, |
| 339 testing::Values( | 226 testing::Values( |
| 340 ValueTestParams::ForStringPolicy( | 227 ValueTestParams::ForStringPolicy( |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 ConfigurationPolicyStore::kPolicyExtensionInstallDenyList, | 309 ConfigurationPolicyStore::kPolicyExtensionInstallDenyList, |
| 423 key::kExtensionInstallDenyList), | 310 key::kExtensionInstallDenyList), |
| 424 ValueTestParams::ForBooleanPolicy( | 311 ValueTestParams::ForBooleanPolicy( |
| 425 ConfigurationPolicyStore::kPolicyShowHomeButton, | 312 ConfigurationPolicyStore::kPolicyShowHomeButton, |
| 426 key::kShowHomeButton), | 313 key::kShowHomeButton), |
| 427 ValueTestParams::ForBooleanPolicy( | 314 ValueTestParams::ForBooleanPolicy( |
| 428 ConfigurationPolicyStore::kPolicyPrintingEnabled, | 315 ConfigurationPolicyStore::kPolicyPrintingEnabled, |
| 429 key::kPrintingEnabled))); | 316 key::kPrintingEnabled))); |
| 430 | 317 |
| 431 } // namespace policy | 318 } // namespace policy |
| OLD | NEW |