| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/policy/browser_policy_connector.h" | 5 #include "chrome/browser/policy/browser_policy_connector.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/policy/async_policy_provider.h" | 14 #include "chrome/browser/policy/async_policy_provider.h" |
| 15 #include "chrome/browser/policy/cloud_policy_client.h" | 15 #include "chrome/browser/policy/cloud_policy_client.h" |
| 16 #include "chrome/browser/policy/cloud_policy_provider.h" | 16 #include "chrome/browser/policy/cloud_policy_provider.h" |
| 17 #include "chrome/browser/policy/cloud_policy_service.h" | 17 #include "chrome/browser/policy/cloud_policy_service.h" |
| 18 #include "chrome/browser/policy/cloud_policy_subsystem.h" | 18 #include "chrome/browser/policy/cloud_policy_subsystem.h" |
| 19 #include "chrome/browser/policy/configuration_policy_provider.h" | 19 #include "chrome/browser/policy/configuration_policy_provider.h" |
| 20 #include "chrome/browser/policy/device_management_service.h" | 20 #include "chrome/browser/policy/device_management_service.h" |
| 21 #include "chrome/browser/policy/managed_mode_policy_provider.h" | 21 #include "chrome/browser/policy/managed_mode_policy_provider.h" |
| 22 #include "chrome/browser/policy/policy_service_impl.h" | 22 #include "chrome/browser/policy/policy_service_impl.h" |
| 23 #include "chrome/browser/policy/policy_statistics_collector.h" | 23 #include "chrome/browser/policy/policy_statistics_collector.h" |
| 24 #include "chrome/browser/policy/user_cloud_policy_manager.h" | |
| 25 #include "chrome/browser/policy/user_policy_cache.h" | 24 #include "chrome/browser/policy/user_policy_cache.h" |
| 26 #include "chrome/browser/policy/user_policy_token_cache.h" | 25 #include "chrome/browser/policy/user_policy_token_cache.h" |
| 27 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
| 28 #include "chrome/browser/signin/token_service.h" | 27 #include "chrome/browser/signin/token_service.h" |
| 29 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
| 30 #include "chrome/common/chrome_paths.h" | 29 #include "chrome/common/chrome_paths.h" |
| 31 #include "chrome/common/chrome_switches.h" | 30 #include "chrome/common/chrome_switches.h" |
| 32 #include "chrome/common/pref_names.h" | 31 #include "chrome/common/pref_names.h" |
| 33 #include "content/public/browser/notification_details.h" | 32 #include "content/public/browser/notification_details.h" |
| 34 #include "content/public/browser/notification_source.h" | 33 #include "content/public/browser/notification_source.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 54 #include "chrome/browser/chromeos/settings/cros_settings_provider.h" | 53 #include "chrome/browser/chromeos/settings/cros_settings_provider.h" |
| 55 #include "chrome/browser/chromeos/settings/device_settings_service.h" | 54 #include "chrome/browser/chromeos/settings/device_settings_service.h" |
| 56 #include "chrome/browser/chromeos/system/statistics_provider.h" | 55 #include "chrome/browser/chromeos/system/statistics_provider.h" |
| 57 #include "chrome/browser/chromeos/system/timezone_settings.h" | 56 #include "chrome/browser/chromeos/system/timezone_settings.h" |
| 58 #include "chrome/browser/policy/app_pack_updater.h" | 57 #include "chrome/browser/policy/app_pack_updater.h" |
| 59 #include "chrome/browser/policy/cros_user_policy_cache.h" | 58 #include "chrome/browser/policy/cros_user_policy_cache.h" |
| 60 #include "chrome/browser/policy/device_cloud_policy_manager_chromeos.h" | 59 #include "chrome/browser/policy/device_cloud_policy_manager_chromeos.h" |
| 61 #include "chrome/browser/policy/device_cloud_policy_store_chromeos.h" | 60 #include "chrome/browser/policy/device_cloud_policy_store_chromeos.h" |
| 62 #include "chrome/browser/policy/device_policy_cache.h" | 61 #include "chrome/browser/policy/device_policy_cache.h" |
| 63 #include "chrome/browser/policy/network_configuration_updater.h" | 62 #include "chrome/browser/policy/network_configuration_updater.h" |
| 63 #include "chrome/browser/policy/user_cloud_policy_manager_chromeos.h" |
| 64 #include "chrome/browser/policy/user_cloud_policy_store_chromeos.h" |
| 64 #include "chromeos/dbus/dbus_thread_manager.h" | 65 #include "chromeos/dbus/dbus_thread_manager.h" |
| 66 #else |
| 67 #include "chrome/browser/policy/user_cloud_policy_manager.h" |
| 68 #include "chrome/browser/policy/user_cloud_policy_manager_factory.h" |
| 65 #endif | 69 #endif |
| 66 | 70 |
| 67 using content::BrowserThread; | 71 using content::BrowserThread; |
| 68 | 72 |
| 69 namespace policy { | 73 namespace policy { |
| 70 | 74 |
| 71 namespace { | 75 namespace { |
| 72 | 76 |
| 73 // Subdirectory in the user's profile for storing user policies. | 77 // Subdirectory in the user's profile for storing user policies. |
| 74 const FilePath::CharType kPolicyDir[] = FILE_PATH_LITERAL("Device Management"); | 78 const FilePath::CharType kPolicyDir[] = FILE_PATH_LITERAL("Device Management"); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 g_testing_provider->Shutdown(); | 154 g_testing_provider->Shutdown(); |
| 151 // Drop g_testing_provider so that tests executed with --single_process can | 155 // Drop g_testing_provider so that tests executed with --single_process can |
| 152 // call SetPolicyProviderForTesting() again. It is still owned by the test. | 156 // call SetPolicyProviderForTesting() again. It is still owned by the test. |
| 153 g_testing_provider = NULL; | 157 g_testing_provider = NULL; |
| 154 if (platform_provider_) | 158 if (platform_provider_) |
| 155 platform_provider_->Shutdown(); | 159 platform_provider_->Shutdown(); |
| 156 // The |cloud_provider_| must be shut down before destroying the cloud | 160 // The |cloud_provider_| must be shut down before destroying the cloud |
| 157 // policy subsystems, which own the caches that |cloud_provider_| uses. | 161 // policy subsystems, which own the caches that |cloud_provider_| uses. |
| 158 if (cloud_provider_) | 162 if (cloud_provider_) |
| 159 cloud_provider_->Shutdown(); | 163 cloud_provider_->Shutdown(); |
| 160 user_cloud_policy_provider_.Shutdown(); | |
| 161 | 164 |
| 162 #if defined(OS_CHROMEOS) | 165 #if defined(OS_CHROMEOS) |
| 163 // Shutdown device cloud policy. | 166 // Shutdown device cloud policy. |
| 164 if (device_cloud_policy_subsystem_) | 167 if (device_cloud_policy_subsystem_) |
| 165 device_cloud_policy_subsystem_->Shutdown(); | 168 device_cloud_policy_subsystem_->Shutdown(); |
| 166 // The AppPackUpdater may be observing the |device_cloud_policy_subsystem_|. | 169 // The AppPackUpdater may be observing the |device_cloud_policy_subsystem_|. |
| 167 // Delete it first. | 170 // Delete it first. |
| 168 app_pack_updater_.reset(); | 171 app_pack_updater_.reset(); |
| 169 device_cloud_policy_subsystem_.reset(); | 172 device_cloud_policy_subsystem_.reset(); |
| 170 device_data_store_.reset(); | 173 device_data_store_.reset(); |
| 171 | 174 |
| 172 if (device_cloud_policy_manager_) | 175 if (device_cloud_policy_manager_) |
| 173 device_cloud_policy_manager_->Shutdown(); | 176 device_cloud_policy_manager_->Shutdown(); |
| 177 if (user_cloud_policy_manager_) |
| 178 user_cloud_policy_manager_->Shutdown(); |
| 179 global_user_cloud_policy_provider_.Shutdown(); |
| 174 #endif | 180 #endif |
| 175 | 181 |
| 176 // Shutdown user cloud policy. | 182 // Shutdown user cloud policy. |
| 177 if (user_cloud_policy_subsystem_) | 183 if (user_cloud_policy_subsystem_) |
| 178 user_cloud_policy_subsystem_->Shutdown(); | 184 user_cloud_policy_subsystem_->Shutdown(); |
| 179 user_cloud_policy_subsystem_.reset(); | 185 user_cloud_policy_subsystem_.reset(); |
| 180 user_policy_token_cache_.reset(); | 186 user_policy_token_cache_.reset(); |
| 181 user_data_store_.reset(); | 187 user_data_store_.reset(); |
| 182 | 188 |
| 183 device_management_service_.reset(); | 189 device_management_service_.reset(); |
| 184 } | 190 } |
| 185 | 191 |
| 186 scoped_ptr<UserCloudPolicyManager> | |
| 187 BrowserPolicyConnector::CreateCloudPolicyManager( | |
| 188 Profile* profile, | |
| 189 bool force_immediate_policy_load) { | |
| 190 scoped_ptr<UserCloudPolicyManager> manager; | |
| 191 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 192 if (command_line->HasSwitch(switches::kEnableCloudPolicyService)) { | |
| 193 UserCloudPolicyManager::PolicyInit policy_init = | |
| 194 UserCloudPolicyManager::POLICY_INIT_IN_BACKGROUND; | |
| 195 #if defined(OS_CHROMEOS) | |
| 196 // TODO(mnissler): Revisit once Chrome OS gains multi-profiles support. | |
| 197 // Don't wait for a policy fetch if there's no logged in user. | |
| 198 if (chromeos::UserManager::Get()->IsUserLoggedIn()) { | |
| 199 std::string email = | |
| 200 chromeos::UserManager::Get()->GetLoggedInUser()->email(); | |
| 201 if (GetUserAffiliation(email) == USER_AFFILIATION_MANAGED) | |
| 202 policy_init = UserCloudPolicyManager::POLICY_INIT_REFRESH_FROM_SERVER; | |
| 203 } | |
| 204 #else | |
| 205 // On desktop, there's no way to figure out if a user is logged in yet | |
| 206 // because prefs are not yet initialized, and further there's no way to know | |
| 207 // if the user is managed. So this code does not request a policy refresh | |
| 208 // from the server because that would inhibit startup for non-signed-in | |
| 209 // users. This code relies on the fact that a signed-in profile should | |
| 210 // already have policy downloaded. If no policy is available | |
| 211 // (due to a previous fetch failing), the normal policy refresh mechanism | |
| 212 // will cause it to get downloaded eventually. | |
| 213 if (force_immediate_policy_load) { | |
| 214 // On desktop, profile creation on startup requires that policies get | |
| 215 // loaded immediately (the normal asynchronous policy initialization | |
| 216 // does not happen because services are initialized before the | |
| 217 // MessageLoop runs). So load policy immediately if desired. | |
| 218 policy_init = UserCloudPolicyManager::POLICY_INIT_IMMEDIATELY; | |
| 219 } | |
| 220 #endif | |
| 221 manager = UserCloudPolicyManager::Create(profile, policy_init); | |
| 222 } | |
| 223 return manager.Pass(); | |
| 224 } | |
| 225 | |
| 226 scoped_ptr<PolicyService> BrowserPolicyConnector::CreatePolicyService( | 192 scoped_ptr<PolicyService> BrowserPolicyConnector::CreatePolicyService( |
| 227 Profile* profile) { | 193 Profile* profile) { |
| 228 DCHECK(profile); | 194 DCHECK(profile); |
| 195 ConfigurationPolicyProvider* user_cloud_policy_provider = NULL; |
| 196 #if !defined(OS_CHROMEOS) |
| 197 user_cloud_policy_provider = |
| 198 UserCloudPolicyManagerFactory::GetForProfile(profile); |
| 199 #endif |
| 229 return CreatePolicyServiceWithProviders( | 200 return CreatePolicyServiceWithProviders( |
| 230 profile->GetUserCloudPolicyManager(), | 201 user_cloud_policy_provider, |
| 231 profile->GetManagedModePolicyProvider()); | 202 profile->GetManagedModePolicyProvider()); |
| 232 } | 203 } |
| 233 | 204 |
| 234 PolicyService* BrowserPolicyConnector::GetPolicyService() { | 205 PolicyService* BrowserPolicyConnector::GetPolicyService() { |
| 235 if (!policy_service_) { | 206 if (!policy_service_) |
| 236 policy_service_ = | 207 policy_service_ = CreatePolicyServiceWithProviders(NULL, NULL); |
| 237 CreatePolicyServiceWithProviders(&user_cloud_policy_provider_, NULL); | |
| 238 } | |
| 239 return policy_service_.get(); | 208 return policy_service_.get(); |
| 240 } | 209 } |
| 241 | 210 |
| 242 void BrowserPolicyConnector::RegisterForDevicePolicy( | 211 void BrowserPolicyConnector::RegisterForDevicePolicy( |
| 243 const std::string& owner_email, | 212 const std::string& owner_email, |
| 244 const std::string& token, | 213 const std::string& token, |
| 245 bool known_machine_id, | 214 bool known_machine_id, |
| 246 bool reregister) { | 215 bool reregister) { |
| 247 #if defined(OS_CHROMEOS) | 216 #if defined(OS_CHROMEOS) |
| 248 if (device_data_store_.get()) { | 217 if (device_data_store_.get()) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 | 308 |
| 340 void BrowserPolicyConnector::InitializeUserPolicy( | 309 void BrowserPolicyConnector::InitializeUserPolicy( |
| 341 const std::string& user_name, | 310 const std::string& user_name, |
| 342 bool wait_for_policy_fetch) { | 311 bool wait_for_policy_fetch) { |
| 343 #if defined(OS_CHROMEOS) | 312 #if defined(OS_CHROMEOS) |
| 344 // If the user is managed then importing certificates from ONC policy is | 313 // If the user is managed then importing certificates from ONC policy is |
| 345 // allowed, otherwise it's not. Update this flag once the user has signed in, | 314 // allowed, otherwise it's not. Update this flag once the user has signed in, |
| 346 // and before user policy is loaded. | 315 // and before user policy is loaded. |
| 347 GetNetworkConfigurationUpdater()->set_allow_web_trust( | 316 GetNetworkConfigurationUpdater()->set_allow_web_trust( |
| 348 GetUserAffiliation(user_name) == USER_AFFILIATION_MANAGED); | 317 GetUserAffiliation(user_name) == USER_AFFILIATION_MANAGED); |
| 318 |
| 319 if (user_cloud_policy_manager_.get()) { |
| 320 global_user_cloud_policy_provider_.SetDelegate(NULL); |
| 321 user_cloud_policy_manager_->Shutdown(); |
| 322 user_cloud_policy_manager_.reset(); |
| 323 } |
| 349 #endif | 324 #endif |
| 350 | 325 |
| 351 // Throw away the old backend. | 326 // Throw away the old backend. |
| 352 user_cloud_policy_subsystem_.reset(); | 327 user_cloud_policy_subsystem_.reset(); |
| 353 user_policy_token_cache_.reset(); | 328 user_policy_token_cache_.reset(); |
| 354 user_data_store_.reset(); | 329 user_data_store_.reset(); |
| 355 token_service_ = NULL; | 330 token_service_ = NULL; |
| 356 registrar_.RemoveAll(); | 331 registrar_.RemoveAll(); |
| 357 | 332 |
| 358 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 333 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 359 | 334 |
| 360 int64 startup_delay = | 335 int64 startup_delay = |
| 361 wait_for_policy_fetch ? 0 : kServiceInitializationStartupDelay; | 336 wait_for_policy_fetch ? 0 : kServiceInitializationStartupDelay; |
| 362 | 337 |
| 363 if (!command_line->HasSwitch(switches::kEnableCloudPolicyService)) { | 338 FilePath profile_dir; |
| 364 FilePath profile_dir; | 339 PathService::Get(chrome::DIR_USER_DATA, &profile_dir); |
| 365 PathService::Get(chrome::DIR_USER_DATA, &profile_dir); | |
| 366 #if defined(OS_CHROMEOS) | 340 #if defined(OS_CHROMEOS) |
| 367 profile_dir = profile_dir.Append( | 341 profile_dir = profile_dir.Append( |
| 368 command_line->GetSwitchValuePath(switches::kLoginProfile)); | 342 command_line->GetSwitchValuePath(switches::kLoginProfile)); |
| 369 #endif | 343 #endif |
| 370 const FilePath policy_dir = profile_dir.Append(kPolicyDir); | 344 const FilePath policy_dir = profile_dir.Append(kPolicyDir); |
| 371 const FilePath policy_cache_file = policy_dir.Append(kPolicyCacheFile); | 345 const FilePath policy_cache_file = policy_dir.Append(kPolicyCacheFile); |
| 372 const FilePath token_cache_file = policy_dir.Append(kTokenCacheFile); | 346 const FilePath token_cache_file = policy_dir.Append(kTokenCacheFile); |
| 347 |
| 348 if (command_line->HasSwitch(switches::kEnableCloudPolicyService)) { |
| 349 #if defined(OS_CHROMEOS) |
| 350 scoped_ptr<CloudPolicyStore> store( |
| 351 new UserCloudPolicyStoreChromeOS( |
| 352 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(), |
| 353 policy_cache_file, token_cache_file)); |
| 354 user_cloud_policy_manager_.reset( |
| 355 new UserCloudPolicyManagerChromeOS(store.Pass(), |
| 356 wait_for_policy_fetch)); |
| 357 user_cloud_policy_manager_->Init(); |
| 358 user_cloud_policy_manager_->Initialize(g_browser_process->local_state(), |
| 359 device_management_service_.get(), |
| 360 GetUserAffiliation(user_name)); |
| 361 global_user_cloud_policy_provider_.SetDelegate( |
| 362 user_cloud_policy_manager_.get()); |
| 363 #endif |
| 364 } else { |
| 373 CloudPolicyCacheBase* user_policy_cache = NULL; | 365 CloudPolicyCacheBase* user_policy_cache = NULL; |
| 374 | 366 |
| 375 user_data_store_.reset(CloudPolicyDataStore::CreateForUserPolicies()); | 367 user_data_store_.reset(CloudPolicyDataStore::CreateForUserPolicies()); |
| 376 #if defined(OS_CHROMEOS) | 368 #if defined(OS_CHROMEOS) |
| 377 user_policy_cache = | 369 user_policy_cache = |
| 378 new CrosUserPolicyCache( | 370 new CrosUserPolicyCache( |
| 379 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(), | 371 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(), |
| 380 user_data_store_.get(), | 372 user_data_store_.get(), |
| 381 wait_for_policy_fetch, | 373 wait_for_policy_fetch, |
| 382 token_cache_file, | 374 token_cache_file, |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 #endif | 550 #endif |
| 559 } | 551 } |
| 560 | 552 |
| 561 void BrowserPolicyConnector::CompleteInitialization() { | 553 void BrowserPolicyConnector::CompleteInitialization() { |
| 562 if (g_testing_provider) | 554 if (g_testing_provider) |
| 563 g_testing_provider->Init(); | 555 g_testing_provider->Init(); |
| 564 if (platform_provider_) | 556 if (platform_provider_) |
| 565 platform_provider_->Init(); | 557 platform_provider_->Init(); |
| 566 if (cloud_provider_) | 558 if (cloud_provider_) |
| 567 cloud_provider_->Init(); | 559 cloud_provider_->Init(); |
| 568 user_cloud_policy_provider_.Init(); | |
| 569 | 560 |
| 570 #if defined(OS_CHROMEOS) | 561 #if defined(OS_CHROMEOS) |
| 562 global_user_cloud_policy_provider_.Init(); |
| 571 | 563 |
| 572 // Create the AppPackUpdater to start updating the cache. It requires the | 564 // Create the AppPackUpdater to start updating the cache. It requires the |
| 573 // system request context, which isn't available in Init(); therefore it is | 565 // system request context, which isn't available in Init(); therefore it is |
| 574 // created only once the loops are running. | 566 // created only once the loops are running. |
| 575 GetAppPackUpdater(); | 567 GetAppPackUpdater(); |
| 576 | 568 |
| 577 if (device_cloud_policy_subsystem_.get()) { | 569 if (device_cloud_policy_subsystem_.get()) { |
| 578 // Read serial number and machine model. This must be done before we call | 570 // Read serial number and machine model. This must be done before we call |
| 579 // CompleteInitialization() below such that the serial number is available | 571 // CompleteInitialization() below such that the serial number is available |
| 580 // for re-submission in case we're doing serial number recovery. | 572 // for re-submission in case we're doing serial number recovery. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 if (g_testing_provider) | 639 if (g_testing_provider) |
| 648 providers.push_back(g_testing_provider); | 640 providers.push_back(g_testing_provider); |
| 649 if (platform_provider_) | 641 if (platform_provider_) |
| 650 providers.push_back(platform_provider_.get()); | 642 providers.push_back(platform_provider_.get()); |
| 651 if (cloud_provider_) | 643 if (cloud_provider_) |
| 652 providers.push_back(cloud_provider_.get()); | 644 providers.push_back(cloud_provider_.get()); |
| 653 | 645 |
| 654 #if defined(OS_CHROMEOS) | 646 #if defined(OS_CHROMEOS) |
| 655 if (device_cloud_policy_manager_.get()) | 647 if (device_cloud_policy_manager_.get()) |
| 656 providers.push_back(device_cloud_policy_manager_.get()); | 648 providers.push_back(device_cloud_policy_manager_.get()); |
| 649 if (!user_cloud_policy_provider) |
| 650 user_cloud_policy_provider = &global_user_cloud_policy_provider_; |
| 657 #endif | 651 #endif |
| 658 | 652 |
| 659 if (user_cloud_policy_provider) | 653 if (user_cloud_policy_provider) |
| 660 providers.push_back(user_cloud_policy_provider); | 654 providers.push_back(user_cloud_policy_provider); |
| 661 if (managed_mode_policy_provider) | 655 if (managed_mode_policy_provider) |
| 662 providers.push_back(managed_mode_policy_provider); | 656 providers.push_back(managed_mode_policy_provider); |
| 663 | 657 |
| 664 return scoped_ptr<PolicyService>(new PolicyServiceImpl(providers)); | 658 return scoped_ptr<PolicyService>(new PolicyServiceImpl(providers)); |
| 665 } | 659 } |
| 666 | 660 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 683 return new AsyncPolicyProvider(loader.Pass()); | 677 return new AsyncPolicyProvider(loader.Pass()); |
| 684 } else { | 678 } else { |
| 685 return NULL; | 679 return NULL; |
| 686 } | 680 } |
| 687 #else | 681 #else |
| 688 return NULL; | 682 return NULL; |
| 689 #endif | 683 #endif |
| 690 } | 684 } |
| 691 | 685 |
| 692 } // namespace policy | 686 } // namespace policy |
| OLD | NEW |