diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-17 19:15:49 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-17 19:15:49 +0000 |
commit | 3b19e8e47928c83800a62ef76e38403593685637 (patch) | |
tree | a29e8241cbcc840bb12ab828b8014260423c6ab0 | |
parent | 9388734eaca551954fe4eb077875cc9f8d0106e3 (diff) | |
download | chromium_src-3b19e8e47928c83800a62ef76e38403593685637.zip chromium_src-3b19e8e47928c83800a62ef76e38403593685637.tar.gz chromium_src-3b19e8e47928c83800a62ef76e38403593685637.tar.bz2 |
Cleanup shutdown of the policy code.
Moved ownership of the global PolicyService to the connector.
ManagedModePolicyProvider isn't a ProfileKeyedService for now, to simplify ownership.
Removed dead code (ProxyPolicyProvider, others).
Removed hacks around ownership issues (OnProviderGoingAway).
BUG=128999
Review URL: https://chromiumcodereview.appspot.com/10958075
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162481 0039d316-1c4b-4281-b951-d872f2087c98
49 files changed, 500 insertions, 400 deletions
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 2413102..2b33a94 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -43,7 +43,6 @@ #include "chrome/browser/net/sdch_dictionary_fetcher.h" #include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/plugins/plugin_finder.h" -#include "chrome/browser/policy/browser_policy_connector.h" #include "chrome/browser/policy/policy_service.h" #include "chrome/browser/prefs/browser_prefs.h" #include "chrome/browser/prefs/pref_service.h" @@ -81,7 +80,9 @@ #include "net/url_request/url_request_context_getter.h" #include "ui/base/l10n/l10n_util.h" -#if !defined(ENABLE_CONFIGURATION_POLICY) +#if defined(ENABLE_CONFIGURATION_POLICY) +#include "chrome/browser/policy/browser_policy_connector.h" +#else #include "chrome/browser/policy/policy_service_stub.h" #endif // defined(ENABLE_CONFIGURATION_POLICY) @@ -219,9 +220,12 @@ void BrowserProcessImpl::StartTearDown() { ExtensionTabIdMap::GetInstance()->Shutdown(); +#if defined(ENABLE_CONFIGURATION_POLICY) // The policy providers managed by |browser_policy_connector_| need to shut // down while the IO and FILE threads are still alive. - browser_policy_connector_.reset(); + if (browser_policy_connector_) + browser_policy_connector_->Shutdown(); +#endif // Stop the watchdog thread before stopping other threads. watchdog_thread_.reset(); @@ -426,28 +430,28 @@ NotificationUIManager* BrowserProcessImpl::notification_ui_manager() { policy::BrowserPolicyConnector* BrowserProcessImpl::browser_policy_connector() { DCHECK(CalledOnValidThread()); - if (!created_browser_policy_connector_) { - DCHECK(browser_policy_connector_.get() == NULL); #if defined(ENABLE_CONFIGURATION_POLICY) + if (!created_browser_policy_connector_) { + // Init() should not reenter this function. If it does this will DCHECK. + DCHECK(!browser_policy_connector_); browser_policy_connector_.reset(new policy::BrowserPolicyConnector()); browser_policy_connector_->Init(); -#endif - // Init() should not reenter this function. Updating - // |created_browser_policy_connector_| here makes reentering hit the DCHECK. created_browser_policy_connector_ = true; } return browser_policy_connector_.get(); +#else + return NULL; +#endif } policy::PolicyService* BrowserProcessImpl::policy_service() { - if (!policy_service_.get()) { #if defined(ENABLE_CONFIGURATION_POLICY) - policy_service_ = browser_policy_connector()->CreatePolicyService(NULL); + return browser_policy_connector()->GetPolicyService(); #else + if (!policy_service_.get()) policy_service_.reset(new policy::PolicyServiceStub()); -#endif - } return policy_service_.get(); +#endif } IconManager* BrowserProcessImpl::icon_manager() { diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index d2f4e85..6aa05e3 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -152,12 +152,15 @@ class BrowserProcessImpl : public BrowserProcess, bool created_watchdog_thread_; scoped_ptr<WatchDogThread> watchdog_thread_; - // Must be destroyed after |policy_service_| if StartTearDown() isn't invoked - // during an early shutdown. bool created_browser_policy_connector_; +#if defined(ENABLE_CONFIGURATION_POLICY) + // Must be destroyed after |local_state_|. scoped_ptr<policy::BrowserPolicyConnector> browser_policy_connector_; +#endif // Must be destroyed after |local_state_|. + // This is a stub when policy is not enabled. Otherwise, the PolicyService + // is owned by the |browser_policy_connector_| and this is not used. scoped_ptr<policy::PolicyService> policy_service_; bool created_profile_manager_; diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc index b31daea..1873542 100644 --- a/chrome/browser/chromeos/login/login_utils_browsertest.cc +++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc @@ -247,10 +247,10 @@ class LoginUtilsTest : public testing::Test, } // These trigger some tasks that have to run while BrowserThread::UI - // exists. + // exists. Delete all the profiles before deleting the connector. + browser_process_->SetProfileManager(NULL); connector_ = NULL; browser_process_->SetBrowserPolicyConnector(NULL); - browser_process_->SetProfileManager(NULL); RunAllPending(); } diff --git a/chrome/browser/extensions/api/managed_mode/managed_mode_api.cc b/chrome/browser/extensions/api/managed_mode/managed_mode_api.cc index 9fc6931..1703fc6 100644 --- a/chrome/browser/extensions/api/managed_mode/managed_mode_api.cc +++ b/chrome/browser/extensions/api/managed_mode/managed_mode_api.cc @@ -22,7 +22,6 @@ #if defined(ENABLE_CONFIGURATION_POLICY) #include "chrome/browser/policy/managed_mode_policy_provider.h" -#include "chrome/browser/policy/managed_mode_policy_provider_factory.h" #endif namespace { @@ -107,7 +106,7 @@ bool GetPolicyFunction::RunImpl() { EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &key)); #if defined(ENABLE_CONFIGURATION_POLICY) policy::ManagedModePolicyProvider* policy_provider = - ManagedModePolicyProviderFactory::GetForProfile(profile_); + profile_->GetManagedModePolicyProvider(); const base::Value* policy = policy_provider->GetPolicy(key); if (policy) SetResult(policy->DeepCopy()); @@ -124,7 +123,7 @@ bool SetPolicyFunction::RunImpl() { EXTENSION_FUNCTION_VALIDATE(args_->Get(1, &value)); #if defined(ENABLE_CONFIGURATION_POLICY) policy::ManagedModePolicyProvider* policy_provider = - ManagedModePolicyProviderFactory::GetForProfile(profile_); + profile_->GetManagedModePolicyProvider(); policy_provider->SetPolicy(key, value); #endif return true; diff --git a/chrome/browser/policy/async_policy_provider.cc b/chrome/browser/policy/async_policy_provider.cc index 71d4502..9163464 100644 --- a/chrome/browser/policy/async_policy_provider.cc +++ b/chrome/browser/policy/async_policy_provider.cc @@ -19,19 +19,36 @@ namespace policy { AsyncPolicyProvider::AsyncPolicyProvider(scoped_ptr<AsyncPolicyLoader> loader) : loader_(loader.release()), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { - // The FILE thread isn't ready early during startup. Post a task to the - // current loop to resume initialization on FILE once the loops are spinning. - MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&AsyncPolicyProvider::InitWithLoopsReady, - weak_factory_.GetWeakPtr())); // Make an immediate synchronous load on startup. OnLoaderReloaded(loader_->InitialLoad()); } AsyncPolicyProvider::~AsyncPolicyProvider() { DCHECK(CalledOnValidThread()); + // Shutdown() must have been called before. + DCHECK(!loader_); +} + +void AsyncPolicyProvider::Init() { + DCHECK(CalledOnValidThread()); + ConfigurationPolicyProvider::Init(); + + if (!loader_) + return; + + AsyncPolicyLoader::UpdateCallback callback = + base::Bind(&AsyncPolicyProvider::LoaderUpdateCallback, + base::MessageLoopProxy::current(), + weak_factory_.GetWeakPtr()); + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + base::Bind(&AsyncPolicyLoader::Init, + base::Unretained(loader_), + callback)); +} +void AsyncPolicyProvider::Shutdown() { + DCHECK(CalledOnValidThread()); // Note on the lifetime of |loader_|: // The |loader_| lives on the FILE thread, and is deleted from here. This // means that posting tasks on the |loader_| to FILE from the @@ -39,6 +56,8 @@ AsyncPolicyProvider::~AsyncPolicyProvider() { // posted from here. The |loader_| posts back to the AsyncPolicyProvider // through the |update_callback_|, which has a WeakPtr to |this|. BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, loader_); + loader_ = NULL; + ConfigurationPolicyProvider::Shutdown(); } void AsyncPolicyProvider::RefreshPolicies() { @@ -63,19 +82,6 @@ void AsyncPolicyProvider::RefreshPolicies() { refresh_callback_.callback()); } -void AsyncPolicyProvider::InitWithLoopsReady() { - DCHECK(CalledOnValidThread()); - AsyncPolicyLoader::UpdateCallback callback = - base::Bind(&AsyncPolicyProvider::LoaderUpdateCallback, - base::MessageLoopProxy::current(), - weak_factory_.GetWeakPtr()); - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::Bind(&AsyncPolicyLoader::Init, - base::Unretained(loader_), - callback)); -} - void AsyncPolicyProvider::ReloadAfterRefreshSync() { DCHECK(CalledOnValidThread()); // This task can only enter if it was posted from RefreshPolicies(), and it @@ -87,6 +93,9 @@ void AsyncPolicyProvider::ReloadAfterRefreshSync() { // sees that there is no refresh pending. refresh_callback_.Cancel(); + if (!loader_) + return; + BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, base::Bind(&AsyncPolicyLoader::Reload, @@ -96,7 +105,9 @@ void AsyncPolicyProvider::ReloadAfterRefreshSync() { void AsyncPolicyProvider::OnLoaderReloaded(scoped_ptr<PolicyBundle> bundle) { DCHECK(CalledOnValidThread()); - if (refresh_callback_.IsCancelled()) + // Only propagate policy updates if there are no pending refreshes, and if + // Shutdown() hasn't been called yet. + if (refresh_callback_.IsCancelled() && loader_) UpdatePolicy(bundle.Pass()); } diff --git a/chrome/browser/policy/async_policy_provider.h b/chrome/browser/policy/async_policy_provider.h index a8c97ce..d478b25 100644 --- a/chrome/browser/policy/async_policy_provider.h +++ b/chrome/browser/policy/async_policy_provider.h @@ -31,12 +31,11 @@ class AsyncPolicyProvider : public ConfigurationPolicyProvider, virtual ~AsyncPolicyProvider(); // ConfigurationPolicyProvider implementation. + virtual void Init() OVERRIDE; + virtual void Shutdown() OVERRIDE; virtual void RefreshPolicies() OVERRIDE; private: - // Resumes initialization once the loops are spinning. - void InitWithLoopsReady(); - // Helper for RefreshPolicies(). void ReloadAfterRefreshSync(); @@ -52,7 +51,7 @@ class AsyncPolicyProvider : public ConfigurationPolicyProvider, scoped_ptr<PolicyBundle> bundle); // The |loader_| that does the platform-specific policy loading. It lives - // on the FILE thread, and always outlives |this|. + // on the FILE thread but is owned by |this|. AsyncPolicyLoader* loader_; // Used to get a WeakPtr to |this| for the update callback given to the diff --git a/chrome/browser/policy/async_policy_provider_unittest.cc b/chrome/browser/policy/async_policy_provider_unittest.cc index be0d810..2272f59 100644 --- a/chrome/browser/policy/async_policy_provider_unittest.cc +++ b/chrome/browser/policy/async_policy_provider_unittest.cc @@ -103,6 +103,7 @@ void AsyncPolicyProviderTest::SetUp() { provider_.reset( new AsyncPolicyProvider(scoped_ptr<AsyncPolicyLoader>(loader_))); + provider_->Init(); // Verify that the initial load is done synchronously: EXPECT_TRUE(provider_->policies().Equals(initial_bundle_)); @@ -114,7 +115,10 @@ void AsyncPolicyProviderTest::SetUp() { } void AsyncPolicyProviderTest::TearDown() { - provider_.reset(); + if (provider_) { + provider_->Shutdown(); + provider_.reset(); + } loop_.RunAllPending(); } @@ -124,13 +128,13 @@ TEST_F(AsyncPolicyProviderTest, RefreshPolicies) { EXPECT_CALL(*loader_, MockLoad()).WillOnce(Return(&refreshed_bundle)); MockConfigurationPolicyObserver observer; - ConfigurationPolicyObserverRegistrar registrar; - registrar.Init(provider_.get(), &observer); + provider_->AddObserver(&observer); EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1); provider_->RefreshPolicies(); loop_.RunAllPending(); // The refreshed policies are now provided. EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle)); + provider_->RemoveObserver(&observer); } TEST_F(AsyncPolicyProviderTest, RefreshPoliciesTwice) { @@ -139,8 +143,7 @@ TEST_F(AsyncPolicyProviderTest, RefreshPoliciesTwice) { EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(Return(&refreshed_bundle)); MockConfigurationPolicyObserver observer; - ConfigurationPolicyObserverRegistrar registrar; - registrar.Init(provider_.get(), &observer); + provider_->AddObserver(&observer); EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0); provider_->RefreshPolicies(); // Doesn't refresh before going through the FILE thread. @@ -156,6 +159,7 @@ TEST_F(AsyncPolicyProviderTest, RefreshPoliciesTwice) { // The refreshed policies are now provided. EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle)); Mock::VerifyAndClearExpectations(&observer); + provider_->RemoveObserver(&observer); } TEST_F(AsyncPolicyProviderTest, RefreshPoliciesDuringReload) { @@ -173,8 +177,7 @@ TEST_F(AsyncPolicyProviderTest, RefreshPoliciesDuringReload) { .WillOnce(Return(&refreshed_bundle)); MockConfigurationPolicyObserver observer; - ConfigurationPolicyObserverRegistrar registrar; - registrar.Init(provider_.get(), &observer); + provider_->AddObserver(&observer); EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0); // A Reload is triggered before RefreshPolicies, and it shouldn't trigger @@ -193,14 +196,14 @@ TEST_F(AsyncPolicyProviderTest, RefreshPoliciesDuringReload) { // dropped. EXPECT_TRUE(provider_->policies().Equals(refreshed_bundle)); Mock::VerifyAndClearExpectations(&observer); + provider_->RemoveObserver(&observer); } TEST_F(AsyncPolicyProviderTest, Shutdown) { EXPECT_CALL(*loader_, MockLoad()).WillRepeatedly(Return(&initial_bundle_)); MockConfigurationPolicyObserver observer; - ConfigurationPolicyObserverRegistrar registrar; - registrar.Init(provider_.get(), &observer); + provider_->AddObserver(&observer); // Though there is a pending Reload, the provider and the loader can be // deleted at any time. @@ -209,10 +212,12 @@ TEST_F(AsyncPolicyProviderTest, Shutdown) { Mock::VerifyAndClearExpectations(&observer); EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(0); - EXPECT_CALL(observer, OnProviderGoingAway(provider_.get())); - provider_.reset(); + provider_->Shutdown(); loop_.RunAllPending(); Mock::VerifyAndClearExpectations(&observer); + + provider_->RemoveObserver(&observer); + provider_.reset(); } } // namespace policy diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc index 445ca3a..dde15bc 100644 --- a/chrome/browser/policy/browser_policy_connector.cc +++ b/chrome/browser/policy/browser_policy_connector.cc @@ -19,7 +19,6 @@ #include "chrome/browser/policy/configuration_policy_provider.h" #include "chrome/browser/policy/device_management_service.h" #include "chrome/browser/policy/managed_mode_policy_provider.h" -#include "chrome/browser/policy/managed_mode_policy_provider_factory.h" #include "chrome/browser/policy/policy_service_impl.h" #include "chrome/browser/policy/policy_statistics_collector.h" #include "chrome/browser/policy/user_cloud_policy_manager.h" @@ -118,33 +117,21 @@ ConfigurationPolicyProvider* g_testing_provider = NULL; } // namespace BrowserPolicyConnector::BrowserPolicyConnector() - : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {} + : is_initialized_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {} BrowserPolicyConnector::~BrowserPolicyConnector() { - // Shutdown device cloud policy. -#if defined(OS_CHROMEOS) - if (device_cloud_policy_subsystem_.get()) - device_cloud_policy_subsystem_->Shutdown(); - // The AppPackUpdater may be observing the |device_cloud_policy_subsystem_|. - // Delete it first. - app_pack_updater_.reset(); - device_cloud_policy_subsystem_.reset(); - device_data_store_.reset(); -#endif - - // Shutdown user cloud policy. - if (user_cloud_policy_subsystem_.get()) - user_cloud_policy_subsystem_->Shutdown(); - user_cloud_policy_subsystem_.reset(); - user_policy_token_cache_.reset(); - user_data_store_.reset(); - - device_management_service_.reset(); + if (is_initialized()) { + // Shutdown() wasn't invoked by our owner after having called Init(). + // This usually means it's an early shutdown and + // BrowserProcessImpl::StartTearDown() wasn't invoked. + // Cleanup properly in those cases and avoid crashing the ToastCrasher test. + Shutdown(); + } } void BrowserPolicyConnector::Init() { - DCHECK(!device_management_service_.get()) << - "BrowserPolicyConnector::Init() called twice."; + DCHECK(!is_initialized()) << "BrowserPolicyConnector::Init() called twice."; platform_provider_.reset(CreatePlatformProvider()); device_management_service_.reset( @@ -163,6 +150,40 @@ void BrowserPolicyConnector::Init() { FROM_HERE, base::Bind(&BrowserPolicyConnector::CompleteInitialization, weak_ptr_factory_.GetWeakPtr())); + + is_initialized_ = true; +} + +void BrowserPolicyConnector::Shutdown() { + is_initialized_ = false; + +#if defined(OS_CHROMEOS) + // Shutdown device cloud policy. + if (device_cloud_policy_subsystem_) + device_cloud_policy_subsystem_->Shutdown(); + // The AppPackUpdater may be observing the |device_cloud_policy_subsystem_|. + // Delete it first. + app_pack_updater_.reset(); + device_cloud_policy_subsystem_.reset(); + device_data_store_.reset(); +#endif + + // Shutdown user cloud policy. + if (user_cloud_policy_subsystem_) + user_cloud_policy_subsystem_->Shutdown(); + user_cloud_policy_subsystem_.reset(); + user_policy_token_cache_.reset(); + user_data_store_.reset(); + + device_management_service_.reset(); + + if (g_testing_provider) + g_testing_provider->Shutdown(); + if (platform_provider_) + platform_provider_->Shutdown(); + if (cloud_provider_) + cloud_provider_->Shutdown(); + user_cloud_policy_provider_.Shutdown(); } scoped_ptr<UserCloudPolicyManager> @@ -196,31 +217,18 @@ scoped_ptr<UserCloudPolicyManager> scoped_ptr<PolicyService> BrowserPolicyConnector::CreatePolicyService( Profile* profile) { - // |providers| in decreasing order of priority. - PolicyServiceImpl::Providers providers; - if (g_testing_provider) - providers.push_back(g_testing_provider); - if (platform_provider_.get()) - providers.push_back(platform_provider_.get()); - if (cloud_provider_.get()) - providers.push_back(cloud_provider_.get()); + DCHECK(profile); + return CreatePolicyServiceWithProviders( + profile->GetUserCloudPolicyManager(), + profile->GetManagedModePolicyProvider()); +} - // The global policy service uses the proxy provider to allow for swapping in - // user policy after startup, while profiles use |user_cloud_policy_manager_| - // directly as their provider, which may also block initialization on a policy - // fetch at login time. - if (profile) { - UserCloudPolicyManager* manager = profile->GetUserCloudPolicyManager(); - if (manager) - providers.push_back(manager); - - providers.push_back( - ManagedModePolicyProviderFactory::GetForProfile(profile)); - } else { - providers.push_back(&user_cloud_policy_provider_); +PolicyService* BrowserPolicyConnector::GetPolicyService() { + if (!policy_service_) { + policy_service_ = + CreatePolicyServiceWithProviders(&user_cloud_policy_provider_, NULL); } - - return scoped_ptr<PolicyService>(new PolicyServiceImpl(providers)).Pass(); + return policy_service_.get(); } void BrowserPolicyConnector::RegisterForDevicePolicy( @@ -569,6 +577,14 @@ void BrowserPolicyConnector::InitializeDevicePolicy() { } void BrowserPolicyConnector::CompleteInitialization() { + if (g_testing_provider) + g_testing_provider->Init(); + if (platform_provider_) + platform_provider_->Init(); + if (cloud_provider_) + cloud_provider_->Init(); + user_cloud_policy_provider_.Init(); + #if defined(OS_CHROMEOS) // Create the AppPackUpdater to start updating the cache. It requires the @@ -644,6 +660,26 @@ void BrowserPolicyConnector::SetTimezoneIfPolicyAvailable() { #endif } +scoped_ptr<PolicyService> + BrowserPolicyConnector::CreatePolicyServiceWithProviders( + ConfigurationPolicyProvider* user_cloud_policy_provider, + ConfigurationPolicyProvider* managed_mode_policy_provider) { + // |providers| in decreasing order of priority. + PolicyServiceImpl::Providers providers; + if (g_testing_provider) + providers.push_back(g_testing_provider); + if (platform_provider_) + providers.push_back(platform_provider_.get()); + if (cloud_provider_) + providers.push_back(cloud_provider_.get()); + if (user_cloud_policy_provider) + providers.push_back(user_cloud_policy_provider); + if (managed_mode_policy_provider) + providers.push_back(managed_mode_policy_provider); + + return scoped_ptr<PolicyService>(new PolicyServiceImpl(providers)); +} + // static ConfigurationPolicyProvider* BrowserPolicyConnector::CreatePlatformProvider() { #if defined(OS_WIN) diff --git a/chrome/browser/policy/browser_policy_connector.h b/chrome/browser/policy/browser_policy_connector.h index 53c31b3..ae2ff9e 100644 --- a/chrome/browser/policy/browser_policy_connector.h +++ b/chrome/browser/policy/browser_policy_connector.h @@ -43,6 +43,8 @@ class BrowserPolicyConnector : public content::NotificationObserver { // Builds an uninitialized BrowserPolicyConnector, suitable for testing. // Init() should be called to create and start the policy machinery. BrowserPolicyConnector(); + + // Invoke Shutdown() before deleting, see below. virtual ~BrowserPolicyConnector(); // Creates the policy providers and finalizes the initialization of the @@ -50,15 +52,26 @@ class BrowserPolicyConnector : public content::NotificationObserver { // policy system running. void Init(); + // Stops the policy providers and cleans up the connector before it can be + // safely deleted. This must be invoked before the destructor and while the + // threads are still running. The policy providers are still valid but won't + // update anymore after this call. + void Shutdown(); + + // Returns true if Init() has been called but Shutdown() hasn't been yet. + bool is_initialized() const { return is_initialized_; } + // Creates a UserCloudPolicyManager for the given profile, or returns NULL if - // it is not supported on this platform. Ownership is transferred to the - // caller. + // it is not supported on this platform. scoped_ptr<UserCloudPolicyManager> CreateCloudPolicyManager(Profile* profile); - // Creates a new policy service for the given profile, or a global one if - // it is NULL. Ownership is transferred to the caller. + // Creates a new policy service for the given profile. scoped_ptr<PolicyService> CreatePolicyService(Profile* profile); + // Returns the browser-global PolicyService, that contains policies for the + // whole browser. + PolicyService* GetPolicyService(); + // Returns a weak pointer to the CloudPolicySubsystem corresponding to the // device policy managed by this policy connector, or NULL if no such // subsystem exists (i.e. when running outside ChromeOS). @@ -157,7 +170,8 @@ class BrowserPolicyConnector : public content::NotificationObserver { // CreatePolicyService. This is a static method because local state is // created immediately after the connector, and tests don't have a chance to // inject the provider otherwise. |provider| must outlive the connector, and - // its ownership is not taken. + // its ownership is not taken though the connector will initialize and shut it + // down. static void SetPolicyProviderForTesting( ConfigurationPolicyProvider* provider); @@ -181,17 +195,32 @@ class BrowserPolicyConnector : public content::NotificationObserver { // Set the timezone as soon as the policies are available. void SetTimezoneIfPolicyAvailable(); + // Creates a new PolicyService with the shared policy providers and the given + // |user_cloud_policy_provider| and |managed_mode_policy_provider|, which are + // optional. + scoped_ptr<PolicyService> CreatePolicyServiceWithProviders( + ConfigurationPolicyProvider* user_cloud_policy_provider, + ConfigurationPolicyProvider* managed_mode_policy_provider); + static ConfigurationPolicyProvider* CreatePlatformProvider(); + // Whether Init() but not Shutdown() has been invoked. + bool is_initialized_; + // Used to convert policies to preferences. The providers declared below - // trigger policy updates during destruction via OnProviderGoingAway(), which - // will result in |handler_list_| being consulted for policy translation. + // may trigger policy updates during shutdown, which will result in + // |handler_list_| being consulted for policy translation. // Therefore, it's important to destroy |handler_list_| after the providers. ConfigurationPolicyHandlerList handler_list_; scoped_ptr<ConfigurationPolicyProvider> platform_provider_; scoped_ptr<CloudPolicyProvider> cloud_provider_; + ProxyPolicyProvider user_cloud_policy_provider_; + + // Must be deleted before all the policy providers. + scoped_ptr<PolicyService> policy_service_; + #if defined(OS_CHROMEOS) scoped_ptr<CloudPolicyDataStore> device_data_store_; scoped_ptr<CloudPolicySubsystem> device_cloud_policy_subsystem_; @@ -209,8 +238,6 @@ class BrowserPolicyConnector : public content::NotificationObserver { // completed the switch to the new cloud policy implementation. scoped_ptr<DeviceManagementService> device_management_service_; - ProxyPolicyProvider user_cloud_policy_provider_; - // Used to initialize the device policy subsystem once the message loops // are spinning. base::WeakPtrFactory<BrowserPolicyConnector> weak_ptr_factory_; diff --git a/chrome/browser/policy/cloud_policy_manager.cc b/chrome/browser/policy/cloud_policy_manager.cc index 5fc7168..5101fd4 100644 --- a/chrome/browser/policy/cloud_policy_manager.cc +++ b/chrome/browser/policy/cloud_policy_manager.cc @@ -21,9 +21,12 @@ CloudPolicyManager::CloudPolicyManager(scoped_ptr<CloudPolicyStore> store) store_->Load(); } -CloudPolicyManager::~CloudPolicyManager() { +CloudPolicyManager::~CloudPolicyManager() {} + +void CloudPolicyManager::Shutdown() { ShutdownService(); store_->RemoveObserver(this); + ConfigurationPolicyProvider::Shutdown(); } bool CloudPolicyManager::IsInitializationComplete() const { diff --git a/chrome/browser/policy/cloud_policy_manager.h b/chrome/browser/policy/cloud_policy_manager.h index 8e03007..82b73c6 100644 --- a/chrome/browser/policy/cloud_policy_manager.h +++ b/chrome/browser/policy/cloud_policy_manager.h @@ -48,6 +48,7 @@ class CloudPolicyManager : public ConfigurationPolicyProvider, } // ConfigurationPolicyProvider: + virtual void Shutdown() OVERRIDE; virtual bool IsInitializationComplete() const OVERRIDE; virtual void RefreshPolicies() OVERRIDE; diff --git a/chrome/browser/policy/cloud_policy_manager_unittest.cc b/chrome/browser/policy/cloud_policy_manager_unittest.cc index 2ac7c47..6e399e7 100644 --- a/chrome/browser/policy/cloud_policy_manager_unittest.cc +++ b/chrome/browser/policy/cloud_policy_manager_unittest.cc @@ -164,8 +164,14 @@ class CloudPolicyManagerTest : public testing::Test { EXPECT_CALL(*store_, Load()); manager_.reset( new TestCloudPolicyManager(scoped_ptr<CloudPolicyStore>(store_))); + manager_->Init(); Mock::VerifyAndClearExpectations(store_); - registrar_.Init(manager_.get(), &observer_); + manager_->AddObserver(&observer_); + } + + virtual void TearDown() OVERRIDE { + manager_->RemoveObserver(&observer_); + manager_->Shutdown(); } // Required by the refresh scheduler that's created by the manager. @@ -180,7 +186,6 @@ class CloudPolicyManagerTest : public testing::Test { MockConfigurationPolicyObserver observer_; MockCloudPolicyStore* store_; scoped_ptr<TestCloudPolicyManager> manager_; - ConfigurationPolicyObserverRegistrar registrar_; private: DISALLOW_COPY_AND_ASSIGN(CloudPolicyManagerTest); diff --git a/chrome/browser/policy/cloud_policy_provider.cc b/chrome/browser/policy/cloud_policy_provider.cc index 3e30598..a751088 100644 --- a/chrome/browser/policy/cloud_policy_provider.cc +++ b/chrome/browser/policy/cloud_policy_provider.cc @@ -18,12 +18,7 @@ CloudPolicyProvider::CloudPolicyProvider(BrowserPolicyConnector* connector) caches_[i] = NULL; } -CloudPolicyProvider::~CloudPolicyProvider() { - for (size_t i = 0; i < CACHE_SIZE; ++i) { - if (caches_[i]) - caches_[i]->RemoveObserver(this); - } -} +CloudPolicyProvider::~CloudPolicyProvider() {} void CloudPolicyProvider::SetUserPolicyCache(CloudPolicyCacheBase* cache) { DCHECK(!caches_[CACHE_USER]); @@ -41,6 +36,14 @@ void CloudPolicyProvider::SetDevicePolicyCache(CloudPolicyCacheBase* cache) { } #endif +void CloudPolicyProvider::Shutdown() { + for (size_t i = 0; i < CACHE_SIZE; ++i) { + if (caches_[i]) + caches_[i]->RemoveObserver(this); + } + ConfigurationPolicyProvider::Shutdown(); +} + bool CloudPolicyProvider::IsInitializationComplete() const { return initialization_complete_; } diff --git a/chrome/browser/policy/cloud_policy_provider.h b/chrome/browser/policy/cloud_policy_provider.h index 9560a40..bc37052 100644 --- a/chrome/browser/policy/cloud_policy_provider.h +++ b/chrome/browser/policy/cloud_policy_provider.h @@ -35,6 +35,7 @@ class CloudPolicyProvider : public ConfigurationPolicyProvider, #endif // ConfigurationPolicyProvider implementation. + virtual void Shutdown() OVERRIDE; virtual bool IsInitializationComplete() const OVERRIDE; virtual void RefreshPolicies() OVERRIDE; diff --git a/chrome/browser/policy/cloud_policy_provider_unittest.cc b/chrome/browser/policy/cloud_policy_provider_unittest.cc index 2310e10..d31848f 100644 --- a/chrome/browser/policy/cloud_policy_provider_unittest.cc +++ b/chrome/browser/policy/cloud_policy_provider_unittest.cc @@ -60,8 +60,15 @@ class CloudPolicyProviderTest : public testing::Test { CloudPolicyProviderTest() : cloud_policy_provider_(&browser_policy_connector_) {} - void SetUp() OVERRIDE { - registrar_.Init(&cloud_policy_provider_, &observer_); + virtual void SetUp() OVERRIDE { + cloud_policy_provider_.Init(); + cloud_policy_provider_.AddObserver(&observer_); + } + + virtual void TearDown() OVERRIDE { + cloud_policy_provider_.RemoveObserver(&observer_); + cloud_policy_provider_.Shutdown(); + browser_policy_connector_.Shutdown(); } void AddUserCache() { @@ -103,7 +110,6 @@ class CloudPolicyProviderTest : public testing::Test { CloudPolicyProvider cloud_policy_provider_; MockConfigurationPolicyObserver observer_; - ConfigurationPolicyObserverRegistrar registrar_; }; TEST_F(CloudPolicyProviderTest, Initialization) { diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc index 6071d9a..46e8cbf 100644 --- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc +++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc @@ -46,6 +46,7 @@ class ConfigurationPolicyPrefStoreTest : public testing::Test { ConfigurationPolicyPrefStoreTest() { EXPECT_CALL(provider_, IsInitializationComplete()) .WillRepeatedly(Return(false)); + provider_.Init(); PolicyServiceImpl::Providers providers; providers.push_back(&provider_); policy_service_.reset(new PolicyServiceImpl(providers)); @@ -53,6 +54,10 @@ class ConfigurationPolicyPrefStoreTest : public testing::Test { POLICY_LEVEL_MANDATORY); } + virtual void TearDown() OVERRIDE { + provider_.Shutdown(); + } + MockConfigurationPolicyProvider provider_; scoped_ptr<PolicyServiceImpl> policy_service_; scoped_refptr<ConfigurationPolicyPrefStore> store_; @@ -997,11 +1002,13 @@ class ConfigurationPolicyPrefStoreRefreshTest : public ConfigurationPolicyPrefStoreTest { protected: virtual void SetUp() { + ConfigurationPolicyPrefStoreTest::SetUp(); store_->AddObserver(&observer_); } virtual void TearDown() { store_->RemoveObserver(&observer_); + ConfigurationPolicyPrefStoreTest::TearDown(); } PrefStoreObserverMock observer_; diff --git a/chrome/browser/policy/configuration_policy_provider.cc b/chrome/browser/policy/configuration_policy_provider.cc index e34a9d2..e8b4011 100644 --- a/chrome/browser/policy/configuration_policy_provider.cc +++ b/chrome/browser/policy/configuration_policy_provider.cc @@ -65,15 +65,17 @@ void FixDeprecatedPolicies(PolicyMap* policies) { ConfigurationPolicyProvider::Observer::~Observer() {} -void ConfigurationPolicyProvider::Observer::OnProviderGoingAway( - ConfigurationPolicyProvider* provider) {} - -ConfigurationPolicyProvider::ConfigurationPolicyProvider() {} +ConfigurationPolicyProvider::ConfigurationPolicyProvider() + : did_shutdown_(false) {} ConfigurationPolicyProvider::~ConfigurationPolicyProvider() { - FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, - observer_list_, - OnProviderGoingAway(this)); + DCHECK(did_shutdown_); +} + +void ConfigurationPolicyProvider::Init() {} + +void ConfigurationPolicyProvider::Shutdown() { + did_shutdown_ = true; } bool ConfigurationPolicyProvider::IsInitializationComplete() const { @@ -101,46 +103,4 @@ void ConfigurationPolicyProvider::RemoveObserver(Observer* observer) { observer_list_.RemoveObserver(observer); } -ConfigurationPolicyObserverRegistrar::ConfigurationPolicyObserverRegistrar() - : provider_(NULL), - observer_(NULL) {} - -ConfigurationPolicyObserverRegistrar::~ConfigurationPolicyObserverRegistrar() { - // Subtle: see the comment in OnProviderGoingAway(). - if (observer_) - provider_->RemoveObserver(this); -} - -void ConfigurationPolicyObserverRegistrar::Init( - ConfigurationPolicyProvider* provider, - ConfigurationPolicyProvider::Observer* observer) { - // Must be either both NULL or both not NULL. - DCHECK(provider); - DCHECK(observer); - provider_ = provider; - observer_ = observer; - provider_->AddObserver(this); -} - -void ConfigurationPolicyObserverRegistrar::OnUpdatePolicy( - ConfigurationPolicyProvider* provider) { - DCHECK_EQ(provider_, provider); - observer_->OnUpdatePolicy(provider_); -} - -void ConfigurationPolicyObserverRegistrar::OnProviderGoingAway( - ConfigurationPolicyProvider* provider) { - DCHECK_EQ(provider_, provider); - // The |observer_| might delete |this| during this callback: don't touch any - // of |this| field's after it returns. - // It might also invoke provider() during this callback, so |provider_| can't - // be set to NULL. So we set |observer_| to NULL instead to signal that - // we're not observing the provider anymore. - ConfigurationPolicyProvider::Observer* observer = observer_; - observer_ = NULL; - provider_->RemoveObserver(this); - - observer->OnProviderGoingAway(provider); -} - } // namespace policy diff --git a/chrome/browser/policy/configuration_policy_provider.h b/chrome/browser/policy/configuration_policy_provider.h index d41887c..5bd7b30 100644 --- a/chrome/browser/policy/configuration_policy_provider.h +++ b/chrome/browser/policy/configuration_policy_provider.h @@ -21,13 +21,29 @@ class ConfigurationPolicyProvider { public: virtual ~Observer(); virtual void OnUpdatePolicy(ConfigurationPolicyProvider* provider) = 0; - virtual void OnProviderGoingAway(ConfigurationPolicyProvider* provider); }; ConfigurationPolicyProvider(); + // Policy providers can be deleted quite late during shutdown of the browser, + // and it's not guaranteed that the message loops will still be running when + // this is invoked. Override Shutdown() instead for cleanup code that needs + // to post to the FILE thread, for example. virtual ~ConfigurationPolicyProvider(); + // Invoked as soon as the main message loops are spinning. Policy providers + // are created early during startup to provide the initial policies; the + // Init() call allows them to perform initialization tasks that require + // running message loops. + virtual void Init(); + + // Must be invoked before deleting the provider. Implementations can override + // this method to do appropriate cleanup while threads are still running, and + // must also invoke ConfigurationPolicyProvider::Shutdown(). + // The provider should keep providing the current policies after Shutdown() + // is invoked, it only has to stop updating. + virtual void Shutdown(); + // Returns the current PolicyBundle. const PolicyBundle& policies() const { return policy_bundle_; } @@ -39,10 +55,14 @@ class ConfigurationPolicyProvider { // Asks the provider to refresh its policies. All the updates caused by this // call will be visible on the next call of OnUpdatePolicy on the observers, // which are guaranteed to happen even if the refresh fails. - // It is possible that OnProviderGoingAway is called first though, and + // It is possible that Shutdown() is called first though, and // OnUpdatePolicy won't be called if that happens. virtual void RefreshPolicies() = 0; + // Observers must detach themselves before the provider is deleted. + virtual void AddObserver(Observer* observer); + virtual void RemoveObserver(Observer* observer); + protected: // Subclasses must invoke this to update the policies currently served by // this provider. UpdatePolicy() takes ownership of |policies|. @@ -50,46 +70,17 @@ class ConfigurationPolicyProvider { void UpdatePolicy(scoped_ptr<PolicyBundle> bundle); private: - friend class ConfigurationPolicyObserverRegistrar; - - virtual void AddObserver(Observer* observer); - virtual void RemoveObserver(Observer* observer); - // The policies currently configured at this provider. PolicyBundle policy_bundle_; + // Whether Shutdown() has been invoked. + bool did_shutdown_; + ObserverList<Observer, true> observer_list_; DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProvider); }; -// Manages observers for a ConfigurationPolicyProvider. Is used to register -// observers, and automatically removes them upon destruction. -// Implementation detail: to avoid duplicate bookkeeping of registered -// observers, this registrar class acts as a proxy for notifications (since it -// needs to register itself anyway to get OnProviderGoingAway notifications). -class ConfigurationPolicyObserverRegistrar - : ConfigurationPolicyProvider::Observer { - public: - ConfigurationPolicyObserverRegistrar(); - virtual ~ConfigurationPolicyObserverRegistrar(); - void Init(ConfigurationPolicyProvider* provider, - ConfigurationPolicyProvider::Observer* observer); - - // ConfigurationPolicyProvider::Observer implementation: - virtual void OnUpdatePolicy(ConfigurationPolicyProvider* provider) OVERRIDE; - virtual void OnProviderGoingAway( - ConfigurationPolicyProvider* provider) OVERRIDE; - - ConfigurationPolicyProvider* provider() { return provider_; } - - private: - ConfigurationPolicyProvider* provider_; - ConfigurationPolicyProvider::Observer* observer_; - - DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyObserverRegistrar); -}; - } // namespace policy #endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_H_ diff --git a/chrome/browser/policy/configuration_policy_provider_test.cc b/chrome/browser/policy/configuration_policy_provider_test.cc index 5e6d3a4..2d0ac93 100644 --- a/chrome/browser/policy/configuration_policy_provider_test.cc +++ b/chrome/browser/policy/configuration_policy_provider_test.cc @@ -83,6 +83,7 @@ void ConfigurationPolicyProviderTest::SetUp() { provider_.reset( test_harness_->CreateProvider(&test_policy_definitions::kList)); + provider_->Init(); // Some providers do a reload on init. Make sure any notifications generated // are fired now. loop_.RunAllPending(); @@ -93,6 +94,7 @@ void ConfigurationPolicyProviderTest::SetUp() { void ConfigurationPolicyProviderTest::TearDown() { // Give providers the chance to clean up after themselves on the file thread. + provider_->Shutdown(); provider_.reset(); PolicyTestBase::TearDown(); @@ -206,8 +208,7 @@ TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) { // OnUpdatePolicy is called even when there are no changes. MockConfigurationPolicyObserver observer; - ConfigurationPolicyObserverRegistrar registrar; - registrar.Init(provider_.get(), &observer); + provider_->AddObserver(&observer); EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1); provider_->RefreshPolicies(); loop_.RunAllPending(); @@ -229,6 +230,7 @@ TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) { test_harness_->policy_scope(), base::Value::CreateStringValue("value")); EXPECT_TRUE(provider_->policies().Equals(bundle)); + provider_->RemoveObserver(&observer); } TEST(ConfigurationPolicyProviderTest, FixDeprecatedPolicies) { @@ -250,6 +252,7 @@ TEST(ConfigurationPolicyProviderTest, FixDeprecatedPolicies) { base::Value::CreateStringValue("http://example.com/wpad.dat")); MockConfigurationPolicyProvider provider; + provider.Init(); provider.UpdateChromePolicy(policy_map); PolicyBundle expected_bundle; @@ -259,6 +262,7 @@ TEST(ConfigurationPolicyProviderTest, FixDeprecatedPolicies) { .Set(key::kProxySettings, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, expected_value); EXPECT_TRUE(provider.policies().Equals(expected_bundle)); + provider.Shutdown(); } Configuration3rdPartyPolicyProviderTest:: diff --git a/chrome/browser/policy/managed_mode_policy_provider.cc b/chrome/browser/policy/managed_mode_policy_provider.cc index 4b09f85..eba924a 100644 --- a/chrome/browser/policy/managed_mode_policy_provider.cc +++ b/chrome/browser/policy/managed_mode_policy_provider.cc @@ -9,7 +9,6 @@ #include "chrome/common/json_pref_store.h" #include "chrome/common/chrome_constants.h" #include "content/public/browser/browser_thread.h" -#include "policy/policy_constants.h" using content::BrowserThread; @@ -35,9 +34,7 @@ ManagedModePolicyProvider::ManagedModePolicyProvider( store_->ReadPrefsAsync(NULL); } -ManagedModePolicyProvider::~ManagedModePolicyProvider() { - store_->RemoveObserver(this); -} +ManagedModePolicyProvider::~ManagedModePolicyProvider() {} const base::Value* ManagedModePolicyProvider::GetPolicy( const std::string& key) const { @@ -57,6 +54,11 @@ void ManagedModePolicyProvider::SetPolicy(const std::string& key, UpdatePolicyFromCache(); } +void ManagedModePolicyProvider::Shutdown() { + store_->RemoveObserver(this); + ConfigurationPolicyProvider::Shutdown(); +} + void ManagedModePolicyProvider::RefreshPolicies() { UpdatePolicyFromCache(); } diff --git a/chrome/browser/policy/managed_mode_policy_provider.h b/chrome/browser/policy/managed_mode_policy_provider.h index e0b2338..313b054 100644 --- a/chrome/browser/policy/managed_mode_policy_provider.h +++ b/chrome/browser/policy/managed_mode_policy_provider.h @@ -7,7 +7,6 @@ #include "base/memory/ref_counted.h" #include "chrome/browser/policy/configuration_policy_provider.h" -#include "chrome/browser/profiles/profile_keyed_service.h" #include "chrome/common/persistent_pref_store.h" class Profile; @@ -18,8 +17,7 @@ namespace policy { // It offers methods to set and read policies, and persists them on disk in // JSON format. class ManagedModePolicyProvider - : public ProfileKeyedService, - public ConfigurationPolicyProvider, + : public ConfigurationPolicyProvider, public PrefStore::Observer { public: // The dictionary key under which we store the policy dictionary. Public for @@ -41,6 +39,7 @@ class ManagedModePolicyProvider void SetPolicy(const std::string& key, const base::Value* value); // ConfigurationPolicyProvider implementation: + virtual void Shutdown() OVERRIDE; virtual void RefreshPolicies() OVERRIDE; virtual bool IsInitializationComplete() const OVERRIDE; diff --git a/chrome/browser/policy/managed_mode_policy_provider_factory.cc b/chrome/browser/policy/managed_mode_policy_provider_factory.cc deleted file mode 100644 index 32ea83a..0000000 --- a/chrome/browser/policy/managed_mode_policy_provider_factory.cc +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/policy/managed_mode_policy_provider_factory.h" - -#include "chrome/browser/policy/managed_mode_policy_provider.h" -#include "chrome/browser/profiles/profile_dependency_manager.h" - -using policy::ManagedModePolicyProvider; - -// static -ManagedModePolicyProviderFactory* - ManagedModePolicyProviderFactory::GetInstance() { - return Singleton<ManagedModePolicyProviderFactory>::get(); -} - -// static -ManagedModePolicyProvider* - ManagedModePolicyProviderFactory::GetForProfile(Profile* profile) { - return static_cast<ManagedModePolicyProvider*>( - GetInstance()->GetServiceForProfile(profile, true)); -} - -ManagedModePolicyProviderFactory::ManagedModePolicyProviderFactory() - : ProfileKeyedServiceFactory("ManagedModePolicyProvider", - ProfileDependencyManager::GetInstance()) {} -ManagedModePolicyProviderFactory::~ManagedModePolicyProviderFactory() {} - -ProfileKeyedService* ManagedModePolicyProviderFactory::BuildServiceInstanceFor( - Profile* profile) const { - return ManagedModePolicyProvider::Create(profile); -} diff --git a/chrome/browser/policy/managed_mode_policy_provider_factory.h b/chrome/browser/policy/managed_mode_policy_provider_factory.h deleted file mode 100644 index fee18cc..0000000 --- a/chrome/browser/policy/managed_mode_policy_provider_factory.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_POLICY_MANAGED_MODE_POLICY_PROVIDER_FACTORY_H_ -#define CHROME_BROWSER_POLICY_MANAGED_MODE_POLICY_PROVIDER_FACTORY_H_ - -#include "base/memory/singleton.h" -#include "chrome/browser/profiles/profile_keyed_service_factory.h" - -class Profile; - -namespace policy { -class ManagedModePolicyProvider; -} - -class ManagedModePolicyProviderFactory : public ProfileKeyedServiceFactory { - public: - static ManagedModePolicyProviderFactory* GetInstance(); - - static policy::ManagedModePolicyProvider* GetForProfile(Profile* profile); - - private: - friend struct DefaultSingletonTraits<ManagedModePolicyProviderFactory>; - - ManagedModePolicyProviderFactory(); - virtual ~ManagedModePolicyProviderFactory(); - - virtual ProfileKeyedService* BuildServiceInstanceFor( - Profile* profile) const OVERRIDE; - - DISALLOW_COPY_AND_ASSIGN(ManagedModePolicyProviderFactory); -}; - -#endif // CHROME_BROWSER_POLICY_MANAGED_MODE_POLICY_PROVIDER_FACTORY_H_ diff --git a/chrome/browser/policy/managed_mode_policy_provider_unittest.cc b/chrome/browser/policy/managed_mode_policy_provider_unittest.cc index 59353e5..a406c2a 100644 --- a/chrome/browser/policy/managed_mode_policy_provider_unittest.cc +++ b/chrome/browser/policy/managed_mode_policy_provider_unittest.cc @@ -133,6 +133,16 @@ class ManagedModePolicyProviderAPITest : public PolicyTestBase { provider_(pref_store_) {} virtual ~ManagedModePolicyProviderAPITest() {} + virtual void SetUp() OVERRIDE { + PolicyTestBase::SetUp(); + provider_.Init(); + } + + virtual void TearDown() OVERRIDE { + provider_.Shutdown(); + PolicyTestBase::TearDown(); + } + scoped_refptr<TestingPrefStore> pref_store_; ManagedModePolicyProvider provider_; }; @@ -162,7 +172,11 @@ TEST_F(ManagedModePolicyProviderAPITest, SetPolicy) { // A newly-created provider should have the same policies. ManagedModePolicyProvider new_provider(pref_store_); + new_provider.Init(); EXPECT_TRUE(new_provider.policies().Equals(expected_bundle)); + + // Cleanup. + new_provider.Shutdown(); } } // namespace policy diff --git a/chrome/browser/policy/mock_configuration_policy_provider.h b/chrome/browser/policy/mock_configuration_policy_provider.h index d969bc8..08a1875 100644 --- a/chrome/browser/policy/mock_configuration_policy_provider.h +++ b/chrome/browser/policy/mock_configuration_policy_provider.h @@ -36,7 +36,6 @@ class MockConfigurationPolicyObserver virtual ~MockConfigurationPolicyObserver(); MOCK_METHOD1(OnUpdatePolicy, void(ConfigurationPolicyProvider*)); - MOCK_METHOD1(OnProviderGoingAway, void(ConfigurationPolicyProvider*)); }; } // namespace policy diff --git a/chrome/browser/policy/policy_loader_mac_unittest.cc b/chrome/browser/policy/policy_loader_mac_unittest.cc index 32006d7..4e454b0 100644 --- a/chrome/browser/policy/policy_loader_mac_unittest.cc +++ b/chrome/browser/policy/policy_loader_mac_unittest.cc @@ -232,6 +232,16 @@ class PolicyLoaderMacTest : public PolicyTestBase { provider_(scoped_ptr<AsyncPolicyLoader>(loader_)) {} virtual ~PolicyLoaderMacTest() {} + virtual void SetUp() OVERRIDE { + PolicyTestBase::SetUp(); + provider_.Init(); + } + + virtual void TearDown() OVERRIDE { + provider_.Shutdown(); + PolicyTestBase::TearDown(); + } + MockPreferences* prefs_; PolicyLoaderMac* loader_; AsyncPolicyProvider provider_; diff --git a/chrome/browser/policy/policy_service_impl.cc b/chrome/browser/policy/policy_service_impl.cc index 3a20c47..2d0a243 100644 --- a/chrome/browser/policy/policy_service_impl.cc +++ b/chrome/browser/policy/policy_service_impl.cc @@ -4,20 +4,22 @@ #include "chrome/browser/policy/policy_service_impl.h" +#include <algorithm> + #include "base/stl_util.h" #include "chrome/browser/policy/policy_map.h" namespace policy { +typedef PolicyServiceImpl::Providers::const_iterator Iterator; + PolicyServiceImpl::PolicyServiceImpl(const Providers& providers) { initialization_complete_ = true; - for (size_t i = 0; i < providers.size(); ++i) { - ConfigurationPolicyProvider* provider = providers[i]; - ConfigurationPolicyObserverRegistrar* registrar = - new ConfigurationPolicyObserverRegistrar(); - registrar->Init(provider, this); + providers_ = providers; + for (Iterator it = providers.begin(); it != providers.end(); ++it) { + ConfigurationPolicyProvider* provider = *it; + provider->AddObserver(this); initialization_complete_ &= provider->IsInitializationComplete(); - registrars_.push_back(registrar); } // There are no observers yet, but calls to GetPolicies() should already get // the processed policy values. @@ -25,7 +27,8 @@ PolicyServiceImpl::PolicyServiceImpl(const Providers& providers) { } PolicyServiceImpl::~PolicyServiceImpl() { - STLDeleteElements(®istrars_); + for (Iterator it = providers_.begin(); it != providers_.end(); ++it) + (*it)->RemoveObserver(this); STLDeleteValues(&observers_); } @@ -65,50 +68,25 @@ void PolicyServiceImpl::RefreshPolicies(const base::Closure& callback) { if (!callback.is_null()) refresh_callbacks_.push_back(callback); - if (registrars_.empty()) { + if (providers_.empty()) { // Refresh is immediately complete if there are no providers. MergeAndTriggerUpdates(); } else { // Some providers might invoke OnUpdatePolicy synchronously while handling // RefreshPolicies. Mark all as pending before refreshing. - RegistrarList::iterator it; - for (it = registrars_.begin(); it != registrars_.end(); ++it) - refresh_pending_.insert((*it)->provider()); - for (it = registrars_.begin(); it != registrars_.end(); ++it) - (*it)->provider()->RefreshPolicies(); + for (Iterator it = providers_.begin(); it != providers_.end(); ++it) + refresh_pending_.insert(*it); + for (Iterator it = providers_.begin(); it != providers_.end(); ++it) + (*it)->RefreshPolicies(); } } void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) { - RegistrarList::iterator it = GetRegistrar(provider); - if (it == registrars_.end()) - return; - refresh_pending_.erase(provider); - MergeAndTriggerUpdates(); -} - -void PolicyServiceImpl::OnProviderGoingAway( - ConfigurationPolicyProvider* provider) { - RegistrarList::iterator it = GetRegistrar(provider); - if (it == registrars_.end()) - return; + DCHECK_EQ(1, std::count(providers_.begin(), providers_.end(), provider)); refresh_pending_.erase(provider); - delete *it; - registrars_.erase(it); MergeAndTriggerUpdates(); } -PolicyServiceImpl::RegistrarList::iterator PolicyServiceImpl::GetRegistrar( - ConfigurationPolicyProvider* provider) { - for (RegistrarList::iterator it = registrars_.begin(); - it != registrars_.end(); ++it) { - if ((*it)->provider() == provider) - return it; - } - NOTREACHED(); - return registrars_.end(); -} - void PolicyServiceImpl::NotifyNamespaceUpdated( const PolicyBundle::PolicyNamespace& ns, const PolicyMap& previous, @@ -125,10 +103,8 @@ void PolicyServiceImpl::NotifyNamespaceUpdated( void PolicyServiceImpl::MergeAndTriggerUpdates() { // Merge from each provider in their order of priority. PolicyBundle bundle; - for (RegistrarList::iterator it = registrars_.begin(); - it != registrars_.end(); ++it) { - bundle.MergeFrom((*it)->provider()->policies()); - } + for (Iterator it = providers_.begin(); it != providers_.end(); ++it) + bundle.MergeFrom((*it)->policies()); // Swap first, so that observers that call GetPolicies() see the current // values. @@ -175,9 +151,8 @@ void PolicyServiceImpl::CheckInitializationComplete() { // Check if all providers became initialized just now, if they weren't before. if (!initialization_complete_) { initialization_complete_ = true; - for (RegistrarList::iterator iter = registrars_.begin(); - iter != registrars_.end(); ++iter) { - if (!(*iter)->provider()->IsInitializationComplete()) { + for (Iterator it = providers_.begin(); it != providers_.end(); ++it) { + if (!(*it)->IsInitializationComplete()) { initialization_complete_ = false; break; } @@ -198,8 +173,9 @@ void PolicyServiceImpl::CheckRefreshComplete() { if (refresh_pending_.empty() && !refresh_callbacks_.empty()) { std::vector<base::Closure> callbacks; callbacks.swap(refresh_callbacks_); - for (size_t i = 0; i < callbacks.size(); ++i) - callbacks[i].Run(); + std::vector<base::Closure>::iterator it; + for (it = callbacks.begin(); it != callbacks.end(); ++it) + it->Run(); } } diff --git a/chrome/browser/policy/policy_service_impl.h b/chrome/browser/policy/policy_service_impl.h index f49d48a..d5b739d 100644 --- a/chrome/browser/policy/policy_service_impl.h +++ b/chrome/browser/policy/policy_service_impl.h @@ -28,7 +28,7 @@ class PolicyServiceImpl : public PolicyService, // The PolicyServiceImpl will merge policies from |providers|. |providers| // must be sorted in decreasing order of priority; the first provider will // have the highest priority. The PolicyServiceImpl does not take ownership of - // the providers, but handles OnProviderGoingAway() if they are destroyed. + // the providers, and they must outlive the PolicyServiceImpl. explicit PolicyServiceImpl(const Providers& providers); virtual ~PolicyServiceImpl(); @@ -46,16 +46,9 @@ class PolicyServiceImpl : public PolicyService, private: typedef ObserverList<PolicyService::Observer, true> Observers; typedef std::map<PolicyDomain, Observers*> ObserverMap; - typedef std::vector<ConfigurationPolicyObserverRegistrar*> RegistrarList; // ConfigurationPolicyProvider::Observer overrides: virtual void OnUpdatePolicy(ConfigurationPolicyProvider* provider) OVERRIDE; - virtual void OnProviderGoingAway( - ConfigurationPolicyProvider* provider) OVERRIDE; - - // Returns an iterator to the entry in |registrars_| that corresponds to - // |provider|, or |registrars_.end()|. - RegistrarList::iterator GetRegistrar(ConfigurationPolicyProvider* provider); // Notifies observers of |ns| that its policies have changed, passing along // the |previous| and the |current| policies. @@ -74,9 +67,8 @@ class PolicyServiceImpl : public PolicyService, // Invokes all the refresh callbacks if there are no more refreshes pending. void CheckRefreshComplete(); - // Contains a registrar for each of the providers passed in the constructor, - // in order of decreasing priority. - RegistrarList registrars_; + // The providers passed in the constructor, in order of decreasing priority. + Providers providers_; // Maps each policy namespace to its current policies. PolicyBundle policy_bundle_; diff --git a/chrome/browser/policy/policy_service_impl_unittest.cc b/chrome/browser/policy/policy_service_impl_unittest.cc index 1af56c8..7723f5e 100644 --- a/chrome/browser/policy/policy_service_impl_unittest.cc +++ b/chrome/browser/policy/policy_service_impl_unittest.cc @@ -72,7 +72,7 @@ class PolicyServiceTest : public testing::Test { public: PolicyServiceTest() {} - void SetUp() OVERRIDE { + virtual void SetUp() OVERRIDE { EXPECT_CALL(provider0_, IsInitializationComplete()) .WillRepeatedly(Return(true)); EXPECT_CALL(provider1_, IsInitializationComplete()) @@ -80,6 +80,10 @@ class PolicyServiceTest : public testing::Test { EXPECT_CALL(provider2_, IsInitializationComplete()) .WillRepeatedly(Return(true)); + provider0_.Init(); + provider1_.Init(); + provider2_.Init(); + policy0_.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, base::Value::CreateIntegerValue(13)); provider0_.UpdateChromePolicy(policy0_); @@ -91,6 +95,12 @@ class PolicyServiceTest : public testing::Test { policy_service_.reset(new PolicyServiceImpl(providers)); } + virtual void TearDown() OVERRIDE { + provider0_.Shutdown(); + provider1_.Shutdown(); + provider2_.Shutdown(); + } + MOCK_METHOD2(OnPolicyValueUpdated, void(const base::Value*, const base::Value*)); diff --git a/chrome/browser/policy/proxy_policy_provider.cc b/chrome/browser/policy/proxy_policy_provider.cc index d1db4c1..f9e334b 100644 --- a/chrome/browser/policy/proxy_policy_provider.cc +++ b/chrome/browser/policy/proxy_policy_provider.cc @@ -6,40 +6,54 @@ namespace policy { -ProxyPolicyProvider::ProxyPolicyProvider() {} +ProxyPolicyProvider::ProxyPolicyProvider() : delegate_(NULL) {} -ProxyPolicyProvider::~ProxyPolicyProvider() {} +ProxyPolicyProvider::~ProxyPolicyProvider() { + DCHECK(!delegate_); +} void ProxyPolicyProvider::SetDelegate(ConfigurationPolicyProvider* delegate) { - if (delegate) { - registrar_.reset(new ConfigurationPolicyObserverRegistrar()); - registrar_->Init(delegate, this); - OnUpdatePolicy(delegate); + if (delegate_) + delegate_->RemoveObserver(this); + delegate_ = delegate; + if (delegate_) { + delegate_->AddObserver(this); + OnUpdatePolicy(delegate_); } else { - registrar_.reset(); UpdatePolicy(scoped_ptr<PolicyBundle>(new PolicyBundle())); } } +void ProxyPolicyProvider::Shutdown() { + // Note: the delegate is not owned by the proxy provider, so this call is not + // forwarded. The same applies for the Init() call. + // Just drop the delegate without propagating updates here. + if (delegate_) { + delegate_->RemoveObserver(this); + delegate_ = NULL; + } + ConfigurationPolicyProvider::Shutdown(); +} + void ProxyPolicyProvider::RefreshPolicies() { - if (registrar_.get()) - registrar_->provider()->RefreshPolicies(); - else - UpdatePolicy(scoped_ptr<PolicyBundle>(new PolicyBundle())); + if (delegate_) { + delegate_->RefreshPolicies(); + } else { + // Subtle: if a RefreshPolicies() call comes after Shutdown() then the + // current bundle should be served instead. This also does the right thing + // if SetDelegate() was never called before. + scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); + bundle->CopyFrom(policies()); + UpdatePolicy(bundle.Pass()); + } } void ProxyPolicyProvider::OnUpdatePolicy( ConfigurationPolicyProvider* provider) { - DCHECK_EQ(registrar_->provider(), provider); + DCHECK_EQ(delegate_, provider); scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); - bundle->CopyFrom(registrar_->provider()->policies()); + bundle->CopyFrom(delegate_->policies()); UpdatePolicy(bundle.Pass()); } -void ProxyPolicyProvider::OnProviderGoingAway( - ConfigurationPolicyProvider* provider) { - registrar_.reset(); - UpdatePolicy(scoped_ptr<PolicyBundle>(new PolicyBundle())); -} - } // namespace policy diff --git a/chrome/browser/policy/proxy_policy_provider.h b/chrome/browser/policy/proxy_policy_provider.h index 81f4037..db7b317 100644 --- a/chrome/browser/policy/proxy_policy_provider.h +++ b/chrome/browser/policy/proxy_policy_provider.h @@ -23,15 +23,14 @@ class ProxyPolicyProvider : public ConfigurationPolicyProvider, void SetDelegate(ConfigurationPolicyProvider* delegate); // ConfigurationPolicyProvider: + virtual void Shutdown() OVERRIDE; virtual void RefreshPolicies() OVERRIDE; // ConfigurationPolicyProvider::Observer: virtual void OnUpdatePolicy(ConfigurationPolicyProvider* provider) OVERRIDE; - virtual void OnProviderGoingAway( - ConfigurationPolicyProvider* provider) OVERRIDE; private: - scoped_ptr<ConfigurationPolicyObserverRegistrar> registrar_; + ConfigurationPolicyProvider* delegate_; DISALLOW_COPY_AND_ASSIGN(ProxyPolicyProvider); }; diff --git a/chrome/browser/policy/proxy_policy_provider_unittest.cc b/chrome/browser/policy/proxy_policy_provider_unittest.cc index 7e226ef..e31ec3d 100644 --- a/chrome/browser/policy/proxy_policy_provider_unittest.cc +++ b/chrome/browser/policy/proxy_policy_provider_unittest.cc @@ -15,13 +15,20 @@ namespace policy { class ProxyPolicyProviderTest : public testing::Test { protected: ProxyPolicyProviderTest() { - registrar_.Init(&proxy_provider_, &observer_); + mock_provider_.Init(); + proxy_provider_.Init(); + proxy_provider_.AddObserver(&observer_); + } + + ~ProxyPolicyProviderTest() { + proxy_provider_.RemoveObserver(&observer_); + proxy_provider_.Shutdown(); + mock_provider_.Shutdown(); } MockConfigurationPolicyObserver observer_; MockConfigurationPolicyProvider mock_provider_; ProxyPolicyProvider proxy_provider_; - ConfigurationPolicyObserverRegistrar registrar_; static scoped_ptr<PolicyBundle> CopyBundle(const PolicyBundle& bundle) { scoped_ptr<PolicyBundle> copy(new PolicyBundle()); diff --git a/chrome/browser/policy/user_cloud_policy_manager.cc b/chrome/browser/policy/user_cloud_policy_manager.cc index 591aa1d..17bdb0a 100644 --- a/chrome/browser/policy/user_cloud_policy_manager.cc +++ b/chrome/browser/policy/user_cloud_policy_manager.cc @@ -18,10 +18,7 @@ UserCloudPolicyManager::UserCloudPolicyManager( : CloudPolicyManager(store.Pass()), wait_for_policy_fetch_(wait_for_policy_fetch) {} -UserCloudPolicyManager::~UserCloudPolicyManager() { - if (cloud_policy_client()) - cloud_policy_client()->RemoveObserver(this); -} +UserCloudPolicyManager::~UserCloudPolicyManager() {} // static scoped_ptr<UserCloudPolicyManager> UserCloudPolicyManager::Create( @@ -93,6 +90,12 @@ void UserCloudPolicyManager::RegisterClient(const std::string& access_token) { } } +void UserCloudPolicyManager::Shutdown() { + if (cloud_policy_client()) + cloud_policy_client()->RemoveObserver(this); + CloudPolicyManager::Shutdown(); +} + bool UserCloudPolicyManager::IsInitializationComplete() const { return CloudPolicyManager::IsInitializationComplete() && !wait_for_policy_fetch_; diff --git a/chrome/browser/policy/user_cloud_policy_manager.h b/chrome/browser/policy/user_cloud_policy_manager.h index a81c2841..3803dbd 100644 --- a/chrome/browser/policy/user_cloud_policy_manager.h +++ b/chrome/browser/policy/user_cloud_policy_manager.h @@ -64,6 +64,7 @@ class UserCloudPolicyManager : public CloudPolicyManager, void RegisterClient(const std::string& access_token); // ConfigurationPolicyProvider: + virtual void Shutdown() OVERRIDE; virtual bool IsInitializationComplete() const OVERRIDE; // CloudPolicyClient::Observer: diff --git a/chrome/browser/policy/user_cloud_policy_manager_unittest.cc b/chrome/browser/policy/user_cloud_policy_manager_unittest.cc index dc1f02f..7359268 100644 --- a/chrome/browser/policy/user_cloud_policy_manager_unittest.cc +++ b/chrome/browser/policy/user_cloud_policy_manager_unittest.cc @@ -52,13 +52,21 @@ class UserCloudPolicyManagerTest : public testing::Test { .Times(AnyNumber()); } + virtual void TearDown() OVERRIDE { + if (manager_) { + manager_->RemoveObserver(&observer_); + manager_->Shutdown(); + } + } + void CreateManager(bool wait_for_policy_fetch) { store_ = new MockCloudPolicyStore(); EXPECT_CALL(*store_, Load()); manager_.reset( new UserCloudPolicyManager(scoped_ptr<CloudPolicyStore>(store_), wait_for_policy_fetch)); - registrar_.Init(manager_.get(), &observer_); + manager_->Init(); + manager_->AddObserver(&observer_); Mock::VerifyAndClearExpectations(store_); } @@ -89,7 +97,6 @@ class UserCloudPolicyManagerTest : public testing::Test { MockDeviceManagementService device_management_service_; MockCloudPolicyStore* store_; scoped_ptr<UserCloudPolicyManager> manager_; - ConfigurationPolicyObserverRegistrar registrar_; private: DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyManagerTest); diff --git a/chrome/browser/policy/user_policy_signin_service_unittest.cc b/chrome/browser/policy/user_policy_signin_service_unittest.cc index e21cb6b..8a9ff10 100644 --- a/chrome/browser/policy/user_policy_signin_service_unittest.cc +++ b/chrome/browser/policy/user_policy_signin_service_unittest.cc @@ -66,6 +66,7 @@ class UserPolicySigninServiceTest : public testing::Test { // Make sure the UserPolicySigninService is created. UserPolicySigninServiceFactory::GetForProfile(profile_.get()); + testing::Mock::VerifyAndClearExpectations(mock_store_); } virtual void TearDown() OVERRIDE { @@ -96,9 +97,10 @@ class UserPolicySigninServiceTest : public testing::Test { }; TEST_F(UserPolicySigninServiceTest, InitWhileSignedOut) { + EXPECT_CALL(*mock_store_, Clear()); // Make sure user is not signed in. ASSERT_TRUE(SigninManagerFactory::GetForProfile(profile_.get())-> - GetAuthenticatedUsername().empty()); + GetAuthenticatedUsername().empty()); // Let the SigninService know that the profile has been created. content::NotificationService::current()->Notify( @@ -126,6 +128,7 @@ TEST_F(UserPolicySigninServiceTest, InitWhileSignedIn) { } TEST_F(UserPolicySigninServiceTest, SignInAfterInit) { + EXPECT_CALL(*mock_store_, Clear()); // Let the SigninService know that the profile has been created. content::NotificationService::current()->Notify( chrome::NOTIFICATION_PROFILE_ADDED, @@ -148,6 +151,7 @@ TEST_F(UserPolicySigninServiceTest, SignInAfterInit) { } TEST_F(UserPolicySigninServiceTest, SignOutAfterInit) { + EXPECT_CALL(*mock_store_, Clear()); // Set the user as signed in. SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername( "testuser@test.com"); diff --git a/chrome/browser/prefs/proxy_policy_unittest.cc b/chrome/browser/prefs/proxy_policy_unittest.cc index 40094cc..a2f3e1c 100644 --- a/chrome/browser/prefs/proxy_policy_unittest.cc +++ b/chrome/browser/prefs/proxy_policy_unittest.cc @@ -85,6 +85,11 @@ class ProxyPolicyTest : public testing::Test { PolicyServiceImpl::Providers providers; providers.push_back(&provider_); policy_service_.reset(new PolicyServiceImpl(providers)); + provider_.Init(); + } + + virtual void TearDown() OVERRIDE { + provider_.Shutdown(); } PrefService* CreatePrefService(bool with_managed_policies) { diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index 88080b2..75d42a6 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc @@ -248,6 +248,11 @@ policy::UserCloudPolicyManager* return profile_->GetUserCloudPolicyManager(); } +policy::ManagedModePolicyProvider* + OffTheRecordProfileImpl::GetManagedModePolicyProvider() { + return profile_->GetManagedModePolicyProvider(); +} + policy::PolicyService* OffTheRecordProfileImpl::GetPolicyService() { return profile_->GetPolicyService(); } diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h index 15c5ac6..f5e5ef1 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.h +++ b/chrome/browser/profiles/off_the_record_profile_impl.h @@ -47,6 +47,8 @@ class OffTheRecordProfileImpl : public Profile, GetExtensionSpecialStoragePolicy() OVERRIDE; virtual GAIAInfoUpdateService* GetGAIAInfoUpdateService() OVERRIDE; virtual policy::UserCloudPolicyManager* GetUserCloudPolicyManager() OVERRIDE; + virtual policy::ManagedModePolicyProvider* + GetManagedModePolicyProvider() OVERRIDE; virtual policy::PolicyService* GetPolicyService() OVERRIDE; virtual PrefService* GetPrefs() OVERRIDE; virtual PrefService* GetOffTheRecordPrefs() OVERRIDE; diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index 88dce13..16c34e9 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h @@ -72,6 +72,7 @@ class SSLConfigService; } namespace policy { +class ManagedModePolicyProvider; class PolicyService; class UserCloudPolicyManager; } @@ -233,6 +234,9 @@ class Profile : public content::BrowserContext { // connection to the cloud-based management service. virtual policy::UserCloudPolicyManager* GetUserCloudPolicyManager() = 0; + // Returns the ManagedModePolicyProvider for this profile, if it exists. + virtual policy::ManagedModePolicyProvider* GetManagedModePolicyProvider() = 0; + // Returns the PolicyService that provides policies for this profile. virtual policy::PolicyService* GetPolicyService() = 0; diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc index 02b5673..cc5c301 100644 --- a/chrome/browser/profiles/profile_dependency_manager.cc +++ b/chrome/browser/profiles/profile_dependency_manager.cc @@ -65,7 +65,6 @@ #endif #if defined(ENABLE_CONFIGURATION_POLICY) -#include "chrome/browser/policy/managed_mode_policy_provider_factory.h" #include "chrome/browser/policy/user_policy_signin_service_factory.h" #endif @@ -231,9 +230,6 @@ void ProfileDependencyManager::AssertFactoriesBuilt() { GlobalErrorServiceFactory::GetInstance(); GoogleURLTrackerFactory::GetInstance(); HistoryServiceFactory::GetInstance(); -#if defined(ENABLE_CONFIGURATION_POLICY) - ManagedModePolicyProviderFactory::GetInstance(); -#endif MediaGalleriesPreferencesFactory::GetInstance(); NTPResourceCacheFactory::GetInstance(); PasswordStoreFactory::GetInstance(); diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 98cd169..4705483 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -50,8 +50,6 @@ #include "chrome/browser/net/ssl_config_service_manager.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/plugins/plugin_prefs.h" -#include "chrome/browser/policy/policy_service.h" -#include "chrome/browser/policy/user_cloud_policy_manager.h" #include "chrome/browser/prefs/browser_prefs.h" #include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/browser/prerender/prerender_manager_factory.h" @@ -93,6 +91,8 @@ #if defined(ENABLE_CONFIGURATION_POLICY) #include "chrome/browser/policy/browser_policy_connector.h" +#include "chrome/browser/policy/managed_mode_policy_provider.h" +#include "chrome/browser/policy/user_cloud_policy_manager.h" #else #include "chrome/browser/policy/policy_service_stub.h" #endif // defined(ENABLE_CONFIGURATION_POLICY) @@ -312,14 +312,19 @@ ProfileImpl::ProfileImpl(const FilePath& path, // a ProfileKeyedService (policy must be initialized before PrefService // because PrefService depends on policy loading to get overridden pref // values). - cloud_policy_manager_ = - g_browser_process->browser_policy_connector()->CreateCloudPolicyManager( - this); - policy_service_ = - g_browser_process->browser_policy_connector()->CreatePolicyService(this); + policy::BrowserPolicyConnector* connector = + g_browser_process->browser_policy_connector(); + cloud_policy_manager_ = connector->CreateCloudPolicyManager(this); + if (cloud_policy_manager_) + cloud_policy_manager_->Init(); + managed_mode_policy_provider_.reset( + policy::ManagedModePolicyProvider::Create(this)); + managed_mode_policy_provider_->Init(); + policy_service_ = connector->CreatePolicyService(this); #else policy_service_.reset(new policy::PolicyServiceStub()); #endif + if (create_mode == CREATE_MODE_ASYNCHRONOUS) { prefs_.reset(PrefService::CreatePrefService( GetPrefFilePath(), @@ -545,6 +550,13 @@ ProfileImpl::~ProfileImpl() { if (host_content_settings_map_) host_content_settings_map_->ShutdownOnUIThread(); +#if defined(ENABLE_CONFIGURATION_POLICY) + if (cloud_policy_manager_) + cloud_policy_manager_->Shutdown(); + if (managed_mode_policy_provider_) + managed_mode_policy_provider_->Shutdown(); +#endif + // This causes the Preferences file to be written to disk. if (prefs_loaded) SetExitType(EXIT_NORMAL); @@ -701,7 +713,19 @@ Profile::ExitType ProfileImpl::GetLastSessionExitType() { } policy::UserCloudPolicyManager* ProfileImpl::GetUserCloudPolicyManager() { +#if defined(ENABLE_CONFIGURATION_POLICY) return cloud_policy_manager_.get(); +#else + return NULL; +#endif +} + +policy::ManagedModePolicyProvider* ProfileImpl::GetManagedModePolicyProvider() { +#if defined(ENABLE_CONFIGURATION_POLICY) + return managed_mode_policy_provider_.get(); +#else + return NULL; +#endif } policy::PolicyService* ProfileImpl::GetPolicyService() { diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index 8a97ff5..39b5a41 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -93,6 +93,8 @@ class ProfileImpl : public Profile, GetExtensionSpecialStoragePolicy() OVERRIDE; virtual GAIAInfoUpdateService* GetGAIAInfoUpdateService() OVERRIDE; virtual policy::UserCloudPolicyManager* GetUserCloudPolicyManager() OVERRIDE; + virtual policy::ManagedModePolicyProvider* + GetManagedModePolicyProvider() OVERRIDE; virtual policy::PolicyService* GetPolicyService() OVERRIDE; virtual PrefService* GetPrefs() OVERRIDE; virtual PrefService* GetOffTheRecordPrefs() OVERRIDE; @@ -190,12 +192,14 @@ class ProfileImpl : public Profile, // that the declaration occurs AFTER things it depends on as destruction // happens in reverse order of declaration. +#if defined(ENABLE_CONFIGURATION_POLICY) // |prefs_| depends on |policy_service_|, which depends on - // |user_cloud_policy_manager_|. - // TODO(bauerb, mnissler): Once |prefs_| is a ProfileKeyedService, - // |policy_service_| and |user_cloud_policy_manager_| should become - // ProfiledKeyedServices as well. + // |user_cloud_policy_manager_| and |managed_mode_policy_provider_|. + // TODO(bauerb, mnissler): Once |prefs_| is a ProfileKeyedService, these + // should become ProfileKeyedServices as well. scoped_ptr<policy::UserCloudPolicyManager> cloud_policy_manager_; + scoped_ptr<policy::ManagedModePolicyProvider> managed_mode_policy_provider_; +#endif scoped_ptr<policy::PolicyService> policy_service_; // Keep |prefs_| on top for destruction order because |extension_prefs_|, diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index fef1760..c8ab673 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1320,8 +1320,6 @@ 'browser/policy/enterprise_metrics.h', 'browser/policy/managed_mode_policy_provider.cc', 'browser/policy/managed_mode_policy_provider.h', - 'browser/policy/managed_mode_policy_provider_factory.cc', - 'browser/policy/managed_mode_policy_provider_factory.h', 'browser/policy/network_configuration_updater.cc', 'browser/policy/network_configuration_updater.h', 'browser/policy/policy_bundle.cc', diff --git a/chrome/common/persistent_pref_store.h b/chrome/common/persistent_pref_store.h index 2d77262..dfd81e0 100644 --- a/chrome/common/persistent_pref_store.h +++ b/chrome/common/persistent_pref_store.h @@ -7,7 +7,7 @@ #include <string> -#include <chrome/common/pref_store.h> +#include "chrome/common/pref_store.h" // This interface is complementary to the PrefStore interface, declaring // additional functionality that adds support for setting values and persisting diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc index 91d8169..7b67dbc 100644 --- a/chrome/test/base/testing_browser_process.cc +++ b/chrome/test/base/testing_browser_process.cc @@ -6,8 +6,6 @@ #include "base/string_util.h" #include "chrome/browser/notifications/notification_ui_manager.h" -#include "chrome/browser/policy/browser_policy_connector.h" -#include "chrome/browser/policy/policy_service.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prerender/prerender_tracker.h" #include "chrome/browser/printing/background_printing_manager.h" @@ -19,7 +17,9 @@ #include "net/url_request/url_request_context_getter.h" #include "testing/gtest/include/gtest/gtest.h" -#if !defined(ENABLE_CONFIGURATION_POLICY) +#if defined(ENABLE_CONFIGURATION_POLICY) +#include "chrome/browser/policy/browser_policy_connector.h" +#else #include "chrome/browser/policy/policy_service_stub.h" #endif // defined(ENABLE_CONFIGURATION_POLICY) @@ -34,6 +34,10 @@ TestingBrowserProcess::TestingBrowserProcess() TestingBrowserProcess::~TestingBrowserProcess() { EXPECT_FALSE(local_state_); +#if defined(ENABLE_CONFIGURATION_POLICY) + if (browser_policy_connector_) + browser_policy_connector_->Shutdown(); +#endif } void TestingBrowserProcess::ResourceDispatcherHostCreated() { @@ -74,21 +78,22 @@ chrome_variations::VariationsService* policy::BrowserPolicyConnector* TestingBrowserProcess::browser_policy_connector() { #if defined(ENABLE_CONFIGURATION_POLICY) - if (!browser_policy_connector_.get()) + if (!browser_policy_connector_) browser_policy_connector_.reset(new policy::BrowserPolicyConnector()); -#endif return browser_policy_connector_.get(); +#else + return NULL; +#endif } policy::PolicyService* TestingBrowserProcess::policy_service() { - if (!policy_service_.get()) { #if defined(ENABLE_CONFIGURATION_POLICY) - policy_service_ = browser_policy_connector()->CreatePolicyService(NULL); + return browser_policy_connector()->GetPolicyService(); #else + if (!policy_service_) policy_service_.reset(new policy::PolicyServiceStub()); -#endif - } return policy_service_.get(); +#endif } IconManager* TestingBrowserProcess::icon_manager() { @@ -253,7 +258,9 @@ void TestingBrowserProcess::SetLocalState(PrefService* local_state) { // any components owned by TestingBrowserProcess that depend on local_state // are also freed. notification_ui_manager_.reset(); - browser_policy_connector_.reset(); +#if defined(ENABLE_CONFIGURATION_POLICY) + SetBrowserPolicyConnector(NULL); +#endif } local_state_ = local_state; } @@ -264,7 +271,13 @@ void TestingBrowserProcess::SetIOThread(IOThread* io_thread) { void TestingBrowserProcess::SetBrowserPolicyConnector( policy::BrowserPolicyConnector* connector) { +#if defined(ENABLE_CONFIGURATION_POLICY) + if (browser_policy_connector_) + browser_policy_connector_->Shutdown(); browser_policy_connector_.reset(connector); +#else + CHECK(false); +#endif } void TestingBrowserProcess::SetSafeBrowsingService( diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h index a6835c7..e28096a 100644 --- a/chrome/test/base/testing_browser_process.h +++ b/chrome/test/base/testing_browser_process.h @@ -114,8 +114,11 @@ class TestingBrowserProcess : public BrowserProcess { // Weak pointer. PrefService* local_state_; +#if defined(ENABLE_CONFIGURATION_POLICY) scoped_ptr<policy::BrowserPolicyConnector> browser_policy_connector_; +#else scoped_ptr<policy::PolicyService> policy_service_; +#endif scoped_ptr<ProfileManager> profile_manager_; scoped_ptr<NotificationUIManager> notification_ui_manager_; scoped_ptr<printing::BackgroundPrintingManager> background_printing_manager_; diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 4f99292..f6f5427 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -300,6 +300,11 @@ TestingProfile::~TestingProfile() { DestroyTopSites(); +#if defined(ENABLE_CONFIGURATION_POLICY) + if (user_cloud_policy_manager_) + user_cloud_policy_manager_->Shutdown(); +#endif + if (pref_proxy_config_tracker_.get()) pref_proxy_config_tracker_->DetachFromPrefService(); } @@ -553,6 +558,11 @@ policy::UserCloudPolicyManager* TestingProfile::GetUserCloudPolicyManager() { return user_cloud_policy_manager_.get(); } +policy::ManagedModePolicyProvider* +TestingProfile::GetManagedModePolicyProvider() { + return NULL; +} + policy::PolicyService* TestingProfile::GetPolicyService() { if (!policy_service_.get()) { #if defined(ENABLE_CONFIGURATION_POLICY) diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index 9668bc1..81e4111 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h @@ -224,6 +224,8 @@ class TestingProfile : public Profile { net::CookieMonster* GetCookieMonster(); virtual policy::UserCloudPolicyManager* GetUserCloudPolicyManager() OVERRIDE; + virtual policy::ManagedModePolicyProvider* + GetManagedModePolicyProvider() OVERRIDE; virtual policy::PolicyService* GetPolicyService() OVERRIDE; // Sets the profile's PrefService. If a pref service hasn't been explicitly // set GetPrefs creates one, so normally you need not invoke this. If you need |