summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-17 19:15:49 +0000
committerjoaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-17 19:15:49 +0000
commit3b19e8e47928c83800a62ef76e38403593685637 (patch)
treea29e8241cbcc840bb12ab828b8014260423c6ab0
parent9388734eaca551954fe4eb077875cc9f8d0106e3 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/browser_process_impl.cc28
-rw-r--r--chrome/browser/browser_process_impl.h7
-rw-r--r--chrome/browser/chromeos/login/login_utils_browsertest.cc4
-rw-r--r--chrome/browser/extensions/api/managed_mode/managed_mode_api.cc5
-rw-r--r--chrome/browser/policy/async_policy_provider.cc51
-rw-r--r--chrome/browser/policy/async_policy_provider.h7
-rw-r--r--chrome/browser/policy/async_policy_provider_unittest.cc27
-rw-r--r--chrome/browser/policy/browser_policy_connector.cc128
-rw-r--r--chrome/browser/policy/browser_policy_connector.h45
-rw-r--r--chrome/browser/policy/cloud_policy_manager.cc5
-rw-r--r--chrome/browser/policy/cloud_policy_manager.h1
-rw-r--r--chrome/browser/policy/cloud_policy_manager_unittest.cc9
-rw-r--r--chrome/browser/policy/cloud_policy_provider.cc15
-rw-r--r--chrome/browser/policy/cloud_policy_provider.h1
-rw-r--r--chrome/browser/policy/cloud_policy_provider_unittest.cc12
-rw-r--r--chrome/browser/policy/configuration_policy_pref_store_unittest.cc7
-rw-r--r--chrome/browser/policy/configuration_policy_provider.cc58
-rw-r--r--chrome/browser/policy/configuration_policy_provider.h59
-rw-r--r--chrome/browser/policy/configuration_policy_provider_test.cc8
-rw-r--r--chrome/browser/policy/managed_mode_policy_provider.cc10
-rw-r--r--chrome/browser/policy/managed_mode_policy_provider.h5
-rw-r--r--chrome/browser/policy/managed_mode_policy_provider_factory.cc33
-rw-r--r--chrome/browser/policy/managed_mode_policy_provider_factory.h35
-rw-r--r--chrome/browser/policy/managed_mode_policy_provider_unittest.cc14
-rw-r--r--chrome/browser/policy/mock_configuration_policy_provider.h1
-rw-r--r--chrome/browser/policy/policy_loader_mac_unittest.cc10
-rw-r--r--chrome/browser/policy/policy_service_impl.cc70
-rw-r--r--chrome/browser/policy/policy_service_impl.h14
-rw-r--r--chrome/browser/policy/policy_service_impl_unittest.cc12
-rw-r--r--chrome/browser/policy/proxy_policy_provider.cc52
-rw-r--r--chrome/browser/policy/proxy_policy_provider.h5
-rw-r--r--chrome/browser/policy/proxy_policy_provider_unittest.cc11
-rw-r--r--chrome/browser/policy/user_cloud_policy_manager.cc11
-rw-r--r--chrome/browser/policy/user_cloud_policy_manager.h1
-rw-r--r--chrome/browser/policy/user_cloud_policy_manager_unittest.cc11
-rw-r--r--chrome/browser/policy/user_policy_signin_service_unittest.cc6
-rw-r--r--chrome/browser/prefs/proxy_policy_unittest.cc5
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.cc5
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.h2
-rw-r--r--chrome/browser/profiles/profile.h4
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.cc4
-rw-r--r--chrome/browser/profiles/profile_impl.cc38
-rw-r--r--chrome/browser/profiles/profile_impl.h12
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/persistent_pref_store.h2
-rw-r--r--chrome/test/base/testing_browser_process.cc33
-rw-r--r--chrome/test/base/testing_browser_process.h3
-rw-r--r--chrome/test/base/testing_profile.cc10
-rw-r--r--chrome/test/base/testing_profile.h2
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(&registrars_);
+ 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