summaryrefslogtreecommitdiffstats
path: root/chrome/browser/policy
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/policy')
-rw-r--r--chrome/browser/policy/asynchronous_policy_loader.cc158
-rw-r--r--chrome/browser/policy/asynchronous_policy_loader.h118
-rw-r--r--chrome/browser/policy/asynchronous_policy_loader_unittest.cc134
-rw-r--r--chrome/browser/policy/asynchronous_policy_provider.cc46
-rw-r--r--chrome/browser/policy/asynchronous_policy_provider.h61
-rw-r--r--chrome/browser/policy/asynchronous_policy_provider_unittest.cc57
-rw-r--r--chrome/browser/policy/asynchronous_policy_test_base.h64
-rw-r--r--chrome/browser/policy/config_dir_policy_provider.cc16
-rw-r--r--chrome/browser/policy/config_dir_policy_provider.h35
-rw-r--r--chrome/browser/policy/config_dir_policy_provider_unittest.cc13
-rw-r--r--chrome/browser/policy/configuration_policy_loader_win.cc90
-rw-r--r--chrome/browser/policy/configuration_policy_loader_win.h57
-rw-r--r--chrome/browser/policy/configuration_policy_pref_store.cc991
-rw-r--r--chrome/browser/policy/configuration_policy_pref_store.h117
-rw-r--r--chrome/browser/policy/configuration_policy_pref_store_unittest.cc785
-rw-r--r--chrome/browser/policy/configuration_policy_provider.cc45
-rw-r--r--chrome/browser/policy/configuration_policy_provider.h54
-rw-r--r--chrome/browser/policy/configuration_policy_provider_delegate_win.cc160
-rw-r--r--chrome/browser/policy/configuration_policy_provider_delegate_win.h47
-rw-r--r--chrome/browser/policy/configuration_policy_provider_mac.cc14
-rw-r--r--chrome/browser/policy/configuration_policy_provider_mac.h9
-rw-r--r--chrome/browser/policy/configuration_policy_provider_mac_unittest.cc4
-rw-r--r--chrome/browser/policy/configuration_policy_provider_win.cc279
-rw-r--r--chrome/browser/policy/configuration_policy_provider_win.h95
-rw-r--r--chrome/browser/policy/configuration_policy_provider_win_unittest.cc26
-rw-r--r--chrome/browser/policy/configuration_policy_store_interface.h26
-rw-r--r--chrome/browser/policy/device_management_policy_cache.cc2
-rw-r--r--chrome/browser/policy/device_management_policy_cache.h1
-rw-r--r--chrome/browser/policy/device_management_policy_provider.cc34
-rw-r--r--chrome/browser/policy/device_management_policy_provider.h25
-rw-r--r--chrome/browser/policy/device_management_policy_provider_unittest.cc35
-rw-r--r--chrome/browser/policy/device_management_service.cc1
-rw-r--r--chrome/browser/policy/device_management_service_browsertest.cc13
-rw-r--r--chrome/browser/policy/device_token_fetcher.cc31
-rw-r--r--chrome/browser/policy/device_token_fetcher.h25
-rw-r--r--chrome/browser/policy/device_token_fetcher_unittest.cc1
-rw-r--r--chrome/browser/policy/dummy_configuration_policy_provider.cc22
-rw-r--r--chrome/browser/policy/dummy_configuration_policy_provider.h18
-rw-r--r--chrome/browser/policy/file_based_policy_loader.cc144
-rw-r--r--chrome/browser/policy/file_based_policy_loader.h78
-rw-r--r--chrome/browser/policy/file_based_policy_provider.cc238
-rw-r--r--chrome/browser/policy/file_based_policy_provider.h165
-rw-r--r--chrome/browser/policy/file_based_policy_provider_unittest.cc170
-rw-r--r--chrome/browser/policy/managed_prefs_banner_base.cc3
-rw-r--r--chrome/browser/policy/managed_prefs_banner_base.h2
-rw-r--r--chrome/browser/policy/managed_prefs_banner_base_unittest.cc1
-rw-r--r--chrome/browser/policy/mock_configuration_policy_provider.cc22
-rw-r--r--chrome/browser/policy/mock_configuration_policy_provider.h12
-rw-r--r--chrome/browser/policy/profile_policy_context.cc2
49 files changed, 2686 insertions, 1860 deletions
diff --git a/chrome/browser/policy/asynchronous_policy_loader.cc b/chrome/browser/policy/asynchronous_policy_loader.cc
new file mode 100644
index 0000000..6ccae7a
--- /dev/null
+++ b/chrome/browser/policy/asynchronous_policy_loader.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/asynchronous_policy_loader.h"
+
+#include "base/message_loop.h"
+#include "base/task.h"
+#include "chrome/browser/browser_thread.h"
+
+namespace policy {
+
+AsynchronousPolicyLoader::AsynchronousPolicyLoader(
+ AsynchronousPolicyProvider::Delegate* delegate,
+ int reload_interval_minutes)
+ : delegate_(delegate),
+ reload_task_(NULL),
+ reload_interval_(base::TimeDelta::FromMinutes(reload_interval_minutes)),
+ origin_loop_(MessageLoop::current()),
+ stopped_(false) {}
+
+void AsynchronousPolicyLoader::Init() {
+ policy_.reset(delegate_->Load());
+ // Initialization can happen early when the file thread is not yet available,
+ // but the subclass of the loader must do some of their initialization on the
+ // file thread. Posting to the file thread directly before it is initialized
+ // will cause the task to be forgotten. Instead, post a task to the ui thread
+ // to delay the remainder of initialization until threading is fully
+ // initialized.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &AsynchronousPolicyLoader::InitAfterFileThreadAvailable));
+}
+
+void AsynchronousPolicyLoader::Stop() {
+ if (!stopped_) {
+ stopped_ = true;
+ delegate_.reset();
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &AsynchronousPolicyLoader::StopOnFileThread));
+ }
+}
+
+AsynchronousPolicyLoader::~AsynchronousPolicyLoader() {
+}
+
+// Manages the life cycle of a new policy map during until its life cycle is
+// taken over by the policy loader.
+class UpdatePolicyTask : public Task {
+ public:
+ UpdatePolicyTask(scoped_refptr<AsynchronousPolicyLoader> loader,
+ DictionaryValue* new_policy)
+ : loader_(loader),
+ new_policy_(new_policy) {}
+
+ virtual void Run() {
+ loader_->UpdatePolicy(new_policy_.release());
+ }
+
+ private:
+ scoped_refptr<AsynchronousPolicyLoader> loader_;
+ scoped_ptr<DictionaryValue> new_policy_;
+ DISALLOW_COPY_AND_ASSIGN(UpdatePolicyTask);
+};
+
+void AsynchronousPolicyLoader::Reload() {
+ if (delegate_.get()) {
+ DictionaryValue* new_policy = delegate_->Load();
+ PostUpdatePolicyTask(new_policy);
+ }
+}
+
+void AsynchronousPolicyLoader::AddObserver(
+ ConfigurationPolicyProvider::Observer* observer) {
+ observer_list_.AddObserver(observer);
+}
+
+void AsynchronousPolicyLoader::RemoveObserver(
+ ConfigurationPolicyProvider::Observer* observer) {
+ observer_list_.RemoveObserver(observer);
+}
+
+void AsynchronousPolicyLoader::CancelReloadTask() {
+ if (reload_task_) {
+ // Only check the thread if there's still a reload task. During
+ // destruction of unit tests, the message loop destruction can
+ // call this method when the file thread is no longer around,
+ // but in that case reload_task_ is NULL.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ reload_task_->Cancel();
+ reload_task_ = NULL;
+ }
+}
+
+void AsynchronousPolicyLoader::ScheduleReloadTask(
+ const base::TimeDelta& delay) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ CancelReloadTask();
+
+ reload_task_ =
+ NewRunnableMethod(this, &AsynchronousPolicyLoader::ReloadFromTask);
+ BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, reload_task_,
+ delay.InMilliseconds());
+}
+
+void AsynchronousPolicyLoader::ScheduleFallbackReloadTask() {
+ // As a safeguard in case that the load delegate failed to timely notice a
+ // change in policy, schedule a reload task that'll make us recheck after a
+ // reasonable interval.
+ ScheduleReloadTask(reload_interval_);
+}
+
+void AsynchronousPolicyLoader::ReloadFromTask() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ // Drop the reference to the reload task, since the task might be the only
+ // referrer that keeps us alive, so we should not Cancel() it.
+ reload_task_ = NULL;
+
+ Reload();
+}
+
+void AsynchronousPolicyLoader::InitOnFileThread() {
+}
+
+void AsynchronousPolicyLoader::StopOnFileThread() {
+ CancelReloadTask();
+}
+
+void AsynchronousPolicyLoader::PostUpdatePolicyTask(
+ DictionaryValue* new_policy) {
+ origin_loop_->PostTask(FROM_HERE, new UpdatePolicyTask(this, new_policy));
+}
+
+void AsynchronousPolicyLoader::UpdatePolicy(DictionaryValue* new_policy_raw) {
+ scoped_ptr<DictionaryValue> new_policy(new_policy_raw);
+ DCHECK(policy_.get());
+ if (!policy_->Equals(new_policy.get())) {
+ policy_.reset(new_policy.release());
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
+ observer_list_,
+ OnUpdatePolicy());
+ }
+}
+
+void AsynchronousPolicyLoader::InitAfterFileThreadAvailable() {
+ if (!stopped_) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &AsynchronousPolicyLoader::InitOnFileThread));
+ }
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/asynchronous_policy_loader.h b/chrome/browser/policy/asynchronous_policy_loader.h
new file mode 100644
index 0000000..677ce6f
--- /dev/null
+++ b/chrome/browser/policy/asynchronous_policy_loader.h
@@ -0,0 +1,118 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_LOADER_H_
+#define CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_LOADER_H_
+#pragma once
+
+#include "base/message_loop.h"
+#include "base/observer_list.h"
+#include "base/ref_counted.h"
+#include "base/values.h"
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
+#include "chrome/browser/policy/configuration_policy_provider.h"
+
+namespace policy {
+
+// Used by the implementation of asynchronous policy provider to manage the
+// tasks on the file thread that do the heavy lifting of loading policies.
+class AsynchronousPolicyLoader
+ : public base::RefCountedThreadSafe<AsynchronousPolicyLoader> {
+ public:
+ explicit AsynchronousPolicyLoader(
+ AsynchronousPolicyProvider::Delegate* delegate,
+ int reload_interval_minutes);
+
+ // Triggers initial policy load.
+ virtual void Init();
+
+ // Reloads policy, sending notification of changes if necessary. Must be
+ // called on the file thread.
+ virtual void Reload();
+
+ // Stops any pending reload tasks.
+ virtual void Stop();
+
+ void AddObserver(ConfigurationPolicyProvider::Observer* observer);
+ void RemoveObserver(ConfigurationPolicyProvider::Observer* observer);
+
+ const DictionaryValue* policy() const { return policy_.get(); }
+
+ protected:
+ friend class UpdatePolicyTask;
+
+ // AsynchronousPolicyLoader objects should only be deleted by
+ // RefCountedThreadSafe.
+ friend class base::RefCountedThreadSafe<AsynchronousPolicyLoader>;
+ virtual ~AsynchronousPolicyLoader();
+
+ // Schedules a call to UpdatePolicy on |origin_loop_|. Takes ownership of
+ // |new_policy|.
+ void PostUpdatePolicyTask(DictionaryValue* new_policy);
+
+ AsynchronousPolicyProvider::Delegate* delegate() {
+ return delegate_.get();
+ }
+
+ // Performs start operations that must be performed on the file thread.
+ virtual void InitOnFileThread();
+
+ // Performs stop operations that must be performed on the file thread.
+ virtual void StopOnFileThread();
+
+ // Schedules a reload task to run when |delay| expires. Must be called on the
+ // file thread.
+ void ScheduleReloadTask(const base::TimeDelta& delay);
+
+ // Schedules a reload task to run after the number of minutes specified
+ // in |reload_interval_minutes_|. Must be called on the file thread.
+ void ScheduleFallbackReloadTask();
+
+ void CancelReloadTask();
+
+ // Invoked from the reload task on the file thread.
+ void ReloadFromTask();
+
+ private:
+ friend class AsynchronousPolicyLoaderTest;
+
+ // Finishes loader initialization after the threading system has been fully
+ // intialized.
+ void InitAfterFileThreadAvailable();
+
+ // Replaces the existing policy to value map with a new one, sending
+ // notification to the observers if there is a policy change. Must be called
+ // on |origin_loop_| so that it's safe to call back into the provider, which
+ // is not thread-safe. Takes ownership of |new_policy|.
+ void UpdatePolicy(DictionaryValue* new_policy);
+
+ // Provides the low-level mechanics for loading policy.
+ scoped_ptr<AsynchronousPolicyProvider::Delegate> delegate_;
+
+ // Current policy.
+ scoped_ptr<DictionaryValue> policy_;
+
+ // The reload task. Access only on the file thread. Holds a reference to the
+ // currently posted task, so we can cancel and repost it if necessary.
+ CancelableTask* reload_task_;
+
+ // The interval at which a policy reload will be triggered as a fallback.
+ const base::TimeDelta reload_interval_;
+
+ // The message loop on which this object was constructed. Recorded so that
+ // it's possible to call back into the non thread safe provider to fire the
+ // notification.
+ MessageLoop* origin_loop_;
+
+ // True if Stop has been called.
+ bool stopped_;
+
+ ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(AsynchronousPolicyLoader);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_LOADER_H_
diff --git a/chrome/browser/policy/asynchronous_policy_loader_unittest.cc b/chrome/browser/policy/asynchronous_policy_loader_unittest.cc
new file mode 100644
index 0000000..3cc416c
--- /dev/null
+++ b/chrome/browser/policy/asynchronous_policy_loader_unittest.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/asynchronous_policy_loader.h"
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
+#include "chrome/browser/policy/asynchronous_policy_test_base.h"
+#include "chrome/browser/policy/mock_configuration_policy_provider.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Return;
+
+namespace policy {
+
+class MockConfigurationPolicyObserver
+ : public ConfigurationPolicyProvider::Observer {
+ public:
+ MOCK_METHOD0(OnUpdatePolicy, void());
+};
+
+class AsynchronousPolicyLoaderTest : public AsynchronousPolicyTestBase {
+ public:
+ AsynchronousPolicyLoaderTest() {}
+ virtual ~AsynchronousPolicyLoaderTest() {}
+
+ virtual void SetUp() {
+ AsynchronousPolicyTestBase::SetUp();
+ mock_provider_.reset(new MockConfigurationPolicyProvider());
+ }
+
+ protected:
+ scoped_ptr<MockConfigurationPolicyProvider> mock_provider_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AsynchronousPolicyLoaderTest);
+};
+
+ACTION(CreateTestDictionary) {
+ return new DictionaryValue();
+}
+
+ACTION_P(CreateSequencedTestDictionary, number) {
+ DictionaryValue* test_dictionary = new DictionaryValue();
+ test_dictionary->SetInteger("id", ++(*number));
+ return test_dictionary;
+}
+
+ACTION(RescheduleImmediatePolicyReload) {
+ *arg1 = base::TimeDelta();
+ return false;
+}
+
+TEST_F(AsynchronousPolicyLoaderTest, InitialLoad) {
+ DictionaryValue* template_dict(new DictionaryValue());
+ EXPECT_CALL(*delegate_, Load()).WillOnce(Return(template_dict));
+ scoped_refptr<AsynchronousPolicyLoader> loader =
+ new AsynchronousPolicyLoader(delegate_.release(), 10);
+ loader->Init();
+ const DictionaryValue* loaded_dict(loader->policy());
+ EXPECT_TRUE(loaded_dict->Equals(template_dict));
+}
+
+// Verify that the fallback policy requests are made.
+TEST_F(AsynchronousPolicyLoaderTest, InitialLoadWithFallback) {
+ int dictionary_number = 0;
+ InSequence s;
+ EXPECT_CALL(*delegate_, Load()).WillOnce(
+ CreateSequencedTestDictionary(&dictionary_number));
+ EXPECT_CALL(*delegate_, Load()).WillOnce(
+ CreateSequencedTestDictionary(&dictionary_number));
+ scoped_refptr<AsynchronousPolicyLoader> loader =
+ new AsynchronousPolicyLoader(delegate_.release(), 10);
+ loader->Init();
+ loop_.RunAllPending();
+ loader->Reload();
+ loop_.RunAllPending();
+
+ const DictionaryValue* loaded_dict(loader->policy());
+ int loaded_number;
+ EXPECT_TRUE(loaded_dict->GetInteger("id", &loaded_number));
+ EXPECT_EQ(dictionary_number, loaded_number);
+}
+
+// Ensure that calling stop on the loader stops subsequent reloads from
+// happening.
+TEST_F(AsynchronousPolicyLoaderTest, Stop) {
+ ON_CALL(*delegate_, Load()).WillByDefault(CreateTestDictionary());
+ EXPECT_CALL(*delegate_, Load()).Times(1);
+ scoped_refptr<AsynchronousPolicyLoader> loader =
+ new AsynchronousPolicyLoader(delegate_.release(), 10);
+ loader->Init();
+ loop_.RunAllPending();
+ loader->Stop();
+ loop_.RunAllPending();
+ loader->Reload();
+ loop_.RunAllPending();
+}
+
+// Verifies that the provider is notified upon policy reload, but only
+// if the policy changed.
+TEST_F(AsynchronousPolicyLoaderTest, ProviderNotificationOnPolicyChange) {
+ InSequence s;
+ MockConfigurationPolicyObserver observer;
+ int dictionary_number_1 = 0;
+ int dictionary_number_2 = 0;
+ EXPECT_CALL(*delegate_, Load()).WillOnce(
+ CreateSequencedTestDictionary(&dictionary_number_1));
+ EXPECT_CALL(*delegate_, Load()).WillOnce(
+ CreateSequencedTestDictionary(&dictionary_number_2));
+ EXPECT_CALL(observer, OnUpdatePolicy()).Times(0);
+ EXPECT_CALL(*delegate_, Load()).WillOnce(
+ CreateSequencedTestDictionary(&dictionary_number_2));
+ EXPECT_CALL(observer, OnUpdatePolicy()).Times(1);
+ EXPECT_CALL(*delegate_, Load()).WillOnce(
+ CreateSequencedTestDictionary(&dictionary_number_1));
+ scoped_refptr<AsynchronousPolicyLoader> loader =
+ new AsynchronousPolicyLoader(delegate_.release(), 10);
+ AsynchronousPolicyProvider provider(NULL, loader);
+ // |registrar| must be declared last so that it is destroyed first.
+ ConfigurationPolicyObserverRegistrar registrar;
+ registrar.Init(&provider);
+ registrar.AddObserver(&observer);
+ loop_.RunAllPending();
+ loader->Reload();
+ loop_.RunAllPending();
+ loader->Reload();
+ loop_.RunAllPending();
+ loader->Reload();
+ loop_.RunAllPending();
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/asynchronous_policy_provider.cc b/chrome/browser/policy/asynchronous_policy_provider.cc
new file mode 100644
index 0000000..e697b05
--- /dev/null
+++ b/chrome/browser/policy/asynchronous_policy_provider.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
+
+#include "chrome/browser/policy/asynchronous_policy_loader.h"
+
+namespace policy {
+
+AsynchronousPolicyProvider::AsynchronousPolicyProvider(
+ const PolicyDefinitionList* policy_list,
+ scoped_refptr<AsynchronousPolicyLoader> loader)
+ : ConfigurationPolicyProvider(policy_list),
+ loader_(loader) {
+ loader_->Init();
+}
+
+AsynchronousPolicyProvider::~AsynchronousPolicyProvider() {
+ DCHECK(CalledOnValidThread());
+ loader_->Stop();
+}
+
+bool AsynchronousPolicyProvider::Provide(
+ ConfigurationPolicyStoreInterface* store) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(loader_->policy());
+ DecodePolicyValueTree(loader_->policy(), store);
+ return true;
+}
+
+void AsynchronousPolicyProvider::AddObserver(
+ ConfigurationPolicyProvider::Observer* observer) {
+ loader_->AddObserver(observer);
+}
+
+void AsynchronousPolicyProvider::RemoveObserver(
+ ConfigurationPolicyProvider::Observer* observer) {
+ loader_->RemoveObserver(observer);
+}
+
+scoped_refptr<AsynchronousPolicyLoader> AsynchronousPolicyProvider::loader() {
+ return loader_;
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/asynchronous_policy_provider.h b/chrome/browser/policy/asynchronous_policy_provider.h
new file mode 100644
index 0000000..561fc37
--- /dev/null
+++ b/chrome/browser/policy/asynchronous_policy_provider.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_PROVIDER_H_
+#define CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_PROVIDER_H_
+#pragma once
+
+#include "base/non_thread_safe.h"
+#include "base/ref_counted.h"
+#include "base/weak_ptr.h"
+#include "chrome/browser/policy/configuration_policy_provider.h"
+
+namespace policy {
+
+class AsynchronousPolicyLoader;
+
+// Policy provider that loads policy asynchronously. Providers should subclass
+// from this class if loading the policy requires disk access or must for some
+// other reason be performed on the file thread. The actual logic for loading
+// policy is handled by a delegate passed at construction time.
+class AsynchronousPolicyProvider
+ : public ConfigurationPolicyProvider,
+ public NonThreadSafe {
+ public:
+ // Must be implemented by subclasses of the asynchronous policy provider to
+ // provide the implementation details of how policy is loaded.
+ class Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ virtual DictionaryValue* Load() = 0;
+ };
+
+ // Assumes ownership of |loader|.
+ AsynchronousPolicyProvider(
+ const PolicyDefinitionList* policy_list,
+ scoped_refptr<AsynchronousPolicyLoader> loader);
+ virtual ~AsynchronousPolicyProvider();
+
+ // ConfigurationPolicyProvider implementation.
+ virtual bool Provide(ConfigurationPolicyStoreInterface* store);
+
+ // For tests to trigger reloads.
+ scoped_refptr<AsynchronousPolicyLoader> loader();
+
+ protected:
+ // The loader object used internally.
+ scoped_refptr<AsynchronousPolicyLoader> loader_;
+
+ private:
+ // ConfigurationPolicyProvider overrides:
+ virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer);
+ virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer);
+
+ DISALLOW_COPY_AND_ASSIGN(AsynchronousPolicyProvider);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_PROVIDER_H_
diff --git a/chrome/browser/policy/asynchronous_policy_provider_unittest.cc b/chrome/browser/policy/asynchronous_policy_provider_unittest.cc
new file mode 100644
index 0000000..c6aee70
--- /dev/null
+++ b/chrome/browser/policy/asynchronous_policy_provider_unittest.cc
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/asynchronous_policy_loader.h"
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
+#include "chrome/browser/policy/asynchronous_policy_test_base.h"
+#include "chrome/browser/policy/configuration_policy_pref_store.h"
+#include "chrome/browser/policy/mock_configuration_policy_store.h"
+#include "chrome/common/policy_constants.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Return;
+
+namespace policy {
+
+// Creating the provider should provide initial policy.
+TEST_F(AsynchronousPolicyTestBase, Provide) {
+ InSequence s;
+ DictionaryValue* policies = new DictionaryValue();
+ policies->SetBoolean(policy::key::kSyncDisabled, true);
+ EXPECT_CALL(*delegate_, Load()).WillOnce(Return(policies));
+ EXPECT_CALL(*store_, Apply(policy::kPolicySyncDisabled, _)).Times(1);
+ AsynchronousPolicyProvider provider(
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
+ new AsynchronousPolicyLoader(delegate_.release(), 10));
+ provider.Provide(store_.get());
+}
+
+
+// Trigger a refresh manually and ensure that policy gets reloaded.
+TEST_F(AsynchronousPolicyTestBase, ProvideAfterRefresh) {
+ InSequence s;
+ DictionaryValue* original_policies = new DictionaryValue();
+ original_policies->SetBoolean(policy::key::kSyncDisabled, true);
+ EXPECT_CALL(*delegate_, Load()).WillOnce(Return(original_policies));
+ DictionaryValue* refresh_policies = new DictionaryValue();
+ refresh_policies->SetBoolean(
+ policy::key::kJavascriptEnabled,
+ true);
+ EXPECT_CALL(*delegate_, Load()).WillOnce(Return(refresh_policies));
+ AsynchronousPolicyLoader* loader =
+ new AsynchronousPolicyLoader(delegate_.release(), 10);
+ AsynchronousPolicyProvider provider(
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
+ loader);
+ loop_.RunAllPending();
+ loader->Reload();
+ loop_.RunAllPending();
+ EXPECT_CALL(*store_, Apply(policy::kPolicyJavascriptEnabled, _)).Times(1);
+ provider.Provide(store_.get());
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/asynchronous_policy_test_base.h b/chrome/browser/policy/asynchronous_policy_test_base.h
new file mode 100644
index 0000000..0281afd
--- /dev/null
+++ b/chrome/browser/policy/asynchronous_policy_test_base.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_TEST_BASE_H_
+#define CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_TEST_BASE_H_
+#pragma once
+
+#include "base/message_loop.h"
+#include "chrome/browser/browser_thread.h"
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
+#include "chrome/browser/policy/mock_configuration_policy_store.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+// A delegate for testing that can feed arbitrary information to the loader.
+class ProviderDelegateMock : public AsynchronousPolicyProvider::Delegate {
+ public:
+ ProviderDelegateMock() : AsynchronousPolicyProvider::Delegate() {}
+ virtual ~ProviderDelegateMock() {}
+
+ MOCK_METHOD0(Load, DictionaryValue*());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProviderDelegateMock);
+};
+
+class AsynchronousPolicyTestBase : public testing::Test {
+ public:
+ AsynchronousPolicyTestBase()
+ : ui_thread_(BrowserThread::UI, &loop_),
+ file_thread_(BrowserThread::FILE, &loop_) {}
+
+ virtual ~AsynchronousPolicyTestBase() {}
+
+ virtual void SetUp() {
+ delegate_.reset(new ProviderDelegateMock());
+ store_.reset(new MockConfigurationPolicyStore);
+ }
+
+ virtual void TearDown() {
+ loop_.RunAllPending();
+ }
+
+ protected:
+ MessageLoop loop_;
+
+ // The mocks that are used in the test must outlive the scope of the test
+ // because they still get accessed in the RunAllPending of the TearDown.
+ scoped_ptr<MockConfigurationPolicyStore> store_;
+ scoped_ptr<ProviderDelegateMock> delegate_;
+
+ private:
+ BrowserThread ui_thread_;
+ BrowserThread file_thread_;
+
+ DISALLOW_COPY_AND_ASSIGN(AsynchronousPolicyTestBase);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_ASYNCHRONOUS_POLICY_TEST_BASE_H_
diff --git a/chrome/browser/policy/config_dir_policy_provider.cc b/chrome/browser/policy/config_dir_policy_provider.cc
index f134aeb..fb2f6eb 100644
--- a/chrome/browser/policy/config_dir_policy_provider.cc
+++ b/chrome/browser/policy/config_dir_policy_provider.cc
@@ -12,11 +12,12 @@
namespace policy {
-ConfigDirPolicyLoader::ConfigDirPolicyLoader(const FilePath& config_dir)
- : FileBasedPolicyProvider::Delegate(config_dir) {
+ConfigDirPolicyProviderDelegate::ConfigDirPolicyProviderDelegate(
+ const FilePath& config_dir)
+ : FileBasedPolicyProvider::ProviderDelegate(config_dir) {
}
-DictionaryValue* ConfigDirPolicyLoader::Load() {
+DictionaryValue* ConfigDirPolicyProviderDelegate::Load() {
// Enumerate the files and sort them lexicographically.
std::set<FilePath> files;
file_util::FileEnumerator file_enumerator(config_file_path(), false,
@@ -49,7 +50,7 @@ DictionaryValue* ConfigDirPolicyLoader::Load() {
return policy;
}
-base::Time ConfigDirPolicyLoader::GetLastModification() {
+base::Time ConfigDirPolicyProviderDelegate::GetLastModification() {
base::Time last_modification = base::Time();
base::PlatformFileInfo file_info;
@@ -68,7 +69,7 @@ base::Time ConfigDirPolicyLoader::GetLastModification() {
config_file = file_enumerator.Next()) {
if (file_util::GetFileInfo(config_file, &file_info) &&
!file_info.is_directory) {
- last_modification = std::min(last_modification, file_info.last_modified);
+ last_modification = std::max(last_modification, file_info.last_modified);
}
}
@@ -78,8 +79,9 @@ base::Time ConfigDirPolicyLoader::GetLastModification() {
ConfigDirPolicyProvider::ConfigDirPolicyProvider(
const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list,
const FilePath& config_dir)
- : FileBasedPolicyProvider(policy_list,
- new ConfigDirPolicyLoader(config_dir)) {
+ : FileBasedPolicyProvider(
+ policy_list,
+ new ConfigDirPolicyProviderDelegate(config_dir)) {
}
} // namespace policy
diff --git a/chrome/browser/policy/config_dir_policy_provider.h b/chrome/browser/policy/config_dir_policy_provider.h
index 6096513..3647489 100644
--- a/chrome/browser/policy/config_dir_policy_provider.h
+++ b/chrome/browser/policy/config_dir_policy_provider.h
@@ -10,23 +10,6 @@
namespace policy {
-// A policy loader implementation backed by a set of files in a given directory.
-// The files should contain JSON-formatted policy settings. They are merged
-// together and the result is returned via the PolicyLoader interface. The files
-// are consulted in lexicographic file name order, so the last value read takes
-// precedence in case of preference key collisions.
-class ConfigDirPolicyLoader : public FileBasedPolicyProvider::Delegate {
- public:
- explicit ConfigDirPolicyLoader(const FilePath& config_dir);
-
- // FileBasedPolicyLoader::Delegate implementation.
- virtual DictionaryValue* Load();
- virtual base::Time GetLastModification();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ConfigDirPolicyLoader);
-};
-
// Policy provider backed by JSON files in a configuration directory.
class ConfigDirPolicyProvider : public FileBasedPolicyProvider {
public:
@@ -38,6 +21,24 @@ class ConfigDirPolicyProvider : public FileBasedPolicyProvider {
DISALLOW_COPY_AND_ASSIGN(ConfigDirPolicyProvider);
};
+// A provider delegate implementation backed by a set of files in a given
+// directory. The files should contain JSON-formatted policy settings. They are
+// merged together and the result is returned via the ProviderDelegate
+// interface. The files are consulted in lexicographic file name order, so the
+// last value read takes precedence in case of preference key collisions.
+class ConfigDirPolicyProviderDelegate
+ : public FileBasedPolicyProvider::ProviderDelegate {
+ public:
+ explicit ConfigDirPolicyProviderDelegate(const FilePath& config_dir);
+
+ // FileBasedPolicyProvider::ProviderDelegate implementation.
+ virtual DictionaryValue* Load();
+ virtual base::Time GetLastModification();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConfigDirPolicyProviderDelegate);
+};
+
} // namespace policy
#endif // CHROME_BROWSER_POLICY_CONFIG_DIR_POLICY_PROVIDER_H_
diff --git a/chrome/browser/policy/config_dir_policy_provider_unittest.cc b/chrome/browser/policy/config_dir_policy_provider_unittest.cc
index 25893da..8b7e9a0 100644
--- a/chrome/browser/policy/config_dir_policy_provider_unittest.cc
+++ b/chrome/browser/policy/config_dir_policy_provider_unittest.cc
@@ -8,6 +8,7 @@
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/string_number_conversions.h"
+#include "chrome/browser/browser_thread.h"
#include "chrome/browser/policy/config_dir_policy_provider.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/mock_configuration_policy_store.h"
@@ -49,7 +50,7 @@ class ConfigDirPolicyLoaderTest
// The preferences dictionary is expected to be empty when there are no files to
// load.
TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsEmpty) {
- ConfigDirPolicyLoader loader(test_dir());
+ ConfigDirPolicyProviderDelegate loader(test_dir());
scoped_ptr<DictionaryValue> policy(loader.Load());
EXPECT_TRUE(policy.get());
EXPECT_TRUE(policy->empty());
@@ -59,7 +60,7 @@ TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsEmpty) {
// dictionary.
TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsNonExistentDirectory) {
FilePath non_existent_dir(test_dir().Append(FILE_PATH_LITERAL("not_there")));
- ConfigDirPolicyLoader loader(non_existent_dir);
+ ConfigDirPolicyProviderDelegate loader(non_existent_dir);
scoped_ptr<DictionaryValue> policy(loader.Load());
EXPECT_TRUE(policy.get());
EXPECT_TRUE(policy->empty());
@@ -71,7 +72,7 @@ TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsSinglePref) {
test_dict.SetString("HomepageLocation", "http://www.google.com");
WriteConfigFile(test_dict, "config_file");
- ConfigDirPolicyLoader loader(test_dir());
+ ConfigDirPolicyProviderDelegate loader(test_dir());
scoped_ptr<DictionaryValue> policy(loader.Load());
EXPECT_TRUE(policy.get());
EXPECT_TRUE(policy->Equals(&test_dict));
@@ -93,7 +94,7 @@ TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsMergePrefs) {
for (unsigned int i = 5; i <= 8; ++i)
WriteConfigFile(test_dict_bar, base::IntToString(i));
- ConfigDirPolicyLoader loader(test_dir());
+ ConfigDirPolicyProviderDelegate loader(test_dir());
scoped_ptr<DictionaryValue> policy(loader.Load());
EXPECT_TRUE(policy.get());
EXPECT_TRUE(policy->Equals(&test_dict_foo));
@@ -258,8 +259,8 @@ INSTANTIATE_TEST_CASE_P(
kPolicyDefaultSearchProviderEncodings,
key::kDefaultSearchProviderEncodings),
ValueTestParams::ForIntegerPolicy(
- kPolicyProxyServerMode,
- key::kProxyServerMode),
+ kPolicyProxyMode,
+ key::kProxyMode),
ValueTestParams::ForStringPolicy(
kPolicyProxyServer,
key::kProxyServer),
diff --git a/chrome/browser/policy/configuration_policy_loader_win.cc b/chrome/browser/policy/configuration_policy_loader_win.cc
new file mode 100644
index 0000000..68ccf80
--- /dev/null
+++ b/chrome/browser/policy/configuration_policy_loader_win.cc
@@ -0,0 +1,90 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/configuration_policy_loader_win.h"
+
+#include <userenv.h>
+
+#include "chrome/browser/browser_thread.h"
+
+namespace policy {
+
+ConfigurationPolicyLoaderWin::ConfigurationPolicyLoaderWin(
+ AsynchronousPolicyProvider::Delegate* delegate,
+ int reload_interval_minutes)
+ : AsynchronousPolicyLoader(delegate, reload_interval_minutes),
+ user_policy_changed_event_(false, false),
+ machine_policy_changed_event_(false, false),
+ user_policy_watcher_failed_(false),
+ machine_policy_watcher_failed_(false) {
+ if (!RegisterGPNotification(user_policy_changed_event_.handle(), false)) {
+ PLOG(WARNING) << "Failed to register user group policy notification";
+ user_policy_watcher_failed_ = true;
+ }
+ if (!RegisterGPNotification(machine_policy_changed_event_.handle(), true)) {
+ PLOG(WARNING) << "Failed to register machine group policy notification.";
+ machine_policy_watcher_failed_ = true;
+ }
+}
+
+void ConfigurationPolicyLoaderWin::InitOnFileThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ AsynchronousPolicyLoader::InitOnFileThread();
+ MessageLoop::current()->AddDestructionObserver(this);
+ SetupWatches();
+}
+
+void ConfigurationPolicyLoaderWin::StopOnFileThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ MessageLoop::current()->RemoveDestructionObserver(this);
+ user_policy_watcher_.StopWatching();
+ machine_policy_watcher_.StopWatching();
+ AsynchronousPolicyLoader::StopOnFileThread();
+}
+
+void ConfigurationPolicyLoaderWin::SetupWatches() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ CancelReloadTask();
+
+ if (!user_policy_watcher_failed_ &&
+ !user_policy_watcher_.GetWatchedObject() &&
+ !user_policy_watcher_.StartWatching(
+ user_policy_changed_event_.handle(), this)) {
+ LOG(WARNING) << "Failed to start watch for user policy change event";
+ user_policy_watcher_failed_ = true;
+ }
+ if (!machine_policy_watcher_failed_ &&
+ !machine_policy_watcher_.GetWatchedObject() &&
+ !machine_policy_watcher_.StartWatching(
+ machine_policy_changed_event_.handle(), this)) {
+ LOG(WARNING) << "Failed to start watch for machine policy change event";
+ machine_policy_watcher_failed_ = true;
+ }
+
+ if (user_policy_watcher_failed_ || machine_policy_watcher_failed_)
+ ScheduleFallbackReloadTask();
+}
+
+void ConfigurationPolicyLoaderWin::Reload() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ AsynchronousPolicyLoader::Reload();
+ SetupWatches();
+}
+
+void ConfigurationPolicyLoaderWin::OnObjectSignaled(HANDLE object) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK(object == user_policy_changed_event_.handle() ||
+ object == machine_policy_changed_event_.handle())
+ << "unexpected object signaled policy reload, obj = "
+ << std::showbase << std::hex << object;
+ Reload();
+}
+
+void ConfigurationPolicyLoaderWin::
+ WillDestroyCurrentMessageLoop() {
+ CancelReloadTask();
+ MessageLoop::current()->RemoveDestructionObserver(this);
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/configuration_policy_loader_win.h b/chrome/browser/policy/configuration_policy_loader_win.h
new file mode 100644
index 0000000..a898afc
--- /dev/null
+++ b/chrome/browser/policy/configuration_policy_loader_win.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_LOADER_WIN_H_
+#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_LOADER_WIN_H_
+#pragma once
+
+#include "base/object_watcher.h"
+#include "base/waitable_event.h"
+#include "chrome/browser/policy/asynchronous_policy_loader.h"
+
+namespace policy {
+
+// Keeps watch on Windows Group Policy notification event to trigger a policy
+// reload when Group Policy changes.
+class ConfigurationPolicyLoaderWin
+ : public AsynchronousPolicyLoader,
+ public base::ObjectWatcher::Delegate,
+ public MessageLoop::DestructionObserver {
+ public:
+ ConfigurationPolicyLoaderWin(
+ AsynchronousPolicyProvider::Delegate* delegate,
+ int reload_interval_minutes);
+ virtual ~ConfigurationPolicyLoaderWin() {}
+
+ protected:
+ // AsynchronousPolicyLoader overrides:
+ virtual void InitOnFileThread();
+ virtual void StopOnFileThread();
+
+ private:
+ // Updates the watchers and schedules the reload task if appropriate.
+ void SetupWatches();
+
+ // Post a reload notification and update the watch machinery.
+ void Reload();
+
+ // ObjectWatcher::Delegate overrides:
+ virtual void OnObjectSignaled(HANDLE object);
+
+ // MessageLoop::DestructionObserver overrides:
+ virtual void WillDestroyCurrentMessageLoop();
+
+ base::WaitableEvent user_policy_changed_event_;
+ base::WaitableEvent machine_policy_changed_event_;
+ base::ObjectWatcher user_policy_watcher_;
+ base::ObjectWatcher machine_policy_watcher_;
+ bool user_policy_watcher_failed_;
+ bool machine_policy_watcher_failed_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyLoaderWin);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_LOADER_WIN_H_
diff --git a/chrome/browser/policy/configuration_policy_pref_store.cc b/chrome/browser/policy/configuration_policy_pref_store.cc
index 5a1eaaa..23e6510 100644
--- a/chrome/browser/policy/configuration_policy_pref_store.cc
+++ b/chrome/browser/policy/configuration_policy_pref_store.cc
@@ -4,15 +4,19 @@
#include "chrome/browser/policy/configuration_policy_pref_store.h"
+#include <set>
+#include <string>
+#include <vector>
+
#include "base/command_line.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/path_service.h"
-#include "base/singleton.h"
+#include "base/stl_util-inl.h"
#include "base/string16.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
-#include "chrome/browser/profile.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
#if defined(OS_WIN)
#include "chrome/browser/policy/configuration_policy_provider_win.h"
@@ -24,98 +28,135 @@
#include "chrome/browser/policy/device_management_policy_provider.h"
#include "chrome/browser/policy/dummy_configuration_policy_provider.h"
#include "chrome/browser/policy/profile_policy_context.h"
+#include "chrome/browser/prefs/pref_value_map.h"
+#include "chrome/browser/prefs/proxy_prefs.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/search_terms_data.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/notification_service.h"
#include "chrome/common/policy_constants.h"
#include "chrome/common/pref_names.h"
namespace policy {
-// Manages the lifecycle of the shared platform-specific policy providers for
-// managed platform, device management and recommended policy. Instantiated as a
-// Singleton.
-class ConfigurationPolicyProviderKeeper {
+// Accepts policy settings from a ConfigurationPolicyProvider, converts them
+// to preferences and caches the result.
+class ConfigurationPolicyPrefKeeper
+ : private ConfigurationPolicyStoreInterface {
public:
- ConfigurationPolicyProviderKeeper()
- : managed_platform_provider_(CreateManagedPlatformProvider()),
- device_management_provider_(CreateDeviceManagementProvider()),
- recommended_provider_(CreateRecommendedProvider()) {}
- virtual ~ConfigurationPolicyProviderKeeper() {}
+ explicit ConfigurationPolicyPrefKeeper(ConfigurationPolicyProvider* provider);
+ virtual ~ConfigurationPolicyPrefKeeper();
- ConfigurationPolicyProvider* managed_platform_provider() const {
- return managed_platform_provider_.get();
- }
-
- ConfigurationPolicyProvider* device_management_provider() const {
- return device_management_provider_.get();
- }
+ // Get a preference value.
+ PrefStore::ReadResult GetValue(const std::string& key, Value** result) const;
- ConfigurationPolicyProvider* recommended_provider() const {
- return recommended_provider_.get();
- }
+ // Compute the set of preference names that are different in |keeper|. This
+ // includes preferences that are missing in either one.
+ void GetDifferingPrefPaths(const ConfigurationPolicyPrefKeeper* other,
+ std::vector<std::string>* differing_prefs) const;
private:
- scoped_ptr<ConfigurationPolicyProvider> managed_platform_provider_;
- scoped_ptr<ConfigurationPolicyProvider> device_management_provider_;
- scoped_ptr<ConfigurationPolicyProvider> recommended_provider_;
-
- static ConfigurationPolicyProvider* CreateManagedPlatformProvider();
- static ConfigurationPolicyProvider* CreateDeviceManagementProvider();
- static ConfigurationPolicyProvider* CreateRecommendedProvider();
+ // ConfigurationPolicyStore methods:
+ virtual void Apply(ConfigurationPolicyType setting, Value* value);
+
+ // Policies that map to a single preference are handled
+ // by an automated converter. Each one of these policies
+ // has an entry in |simple_policy_map_| with the following type.
+ struct PolicyToPreferenceMapEntry {
+ Value::ValueType value_type;
+ ConfigurationPolicyType policy_type;
+ const char* preference_path; // A DictionaryValue path, not a file path.
+ };
- DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProviderKeeper);
+ // Returns the map entry that corresponds to |policy| in the map.
+ const PolicyToPreferenceMapEntry* FindPolicyInMap(
+ ConfigurationPolicyType policy,
+ const PolicyToPreferenceMapEntry* map,
+ int size) const;
+
+ // Remove the preferences found in the map from |prefs_|. Returns true if any
+ // such preferences were found and removed.
+ bool RemovePreferencesOfMap(const PolicyToPreferenceMapEntry* map,
+ int table_size);
+
+ bool ApplyPolicyFromMap(ConfigurationPolicyType policy,
+ Value* value,
+ const PolicyToPreferenceMapEntry* map,
+ int size);
+
+ // Processes proxy-specific policies. Returns true if the specified policy
+ // is a proxy-related policy. ApplyProxyPolicy assumes the ownership
+ // of |value| in the case that the policy is proxy-specific.
+ bool ApplyProxyPolicy(ConfigurationPolicyType policy, Value* value);
+
+ // Handles sync-related policies. Returns true if the policy was handled.
+ // Assumes ownership of |value| in that case.
+ bool ApplySyncPolicy(ConfigurationPolicyType policy, Value* value);
+
+ // Handles policies that affect AutoFill. Returns true if the policy was
+ // handled and assumes ownership of |value| in that case.
+ bool ApplyAutoFillPolicy(ConfigurationPolicyType policy, Value* value);
+
+ // Make sure that the |path| if present in |prefs_|. If not, set it to
+ // a blank string.
+ void EnsureStringPrefExists(const std::string& path);
+
+ // If the required entries for default search are specified and valid,
+ // finalizes the policy-specified configuration by initializing the
+ // unspecified map entries. Otherwise wipes all default search related
+ // map entries from |prefs_|.
+ void FinalizeDefaultSearchPolicySettings();
+
+ // If the required entries for the proxy settings are specified and valid,
+ // finalizes the policy-specified configuration by initializing the
+ // respective values in |prefs_|.
+ void FinalizeProxyPolicySettings();
+
+ // Returns true if the policy values stored in proxy_* represent a valid
+ // proxy configuration.
+ bool CheckProxySettings();
+
+ // Assumes CheckProxySettings returns true and applies the values stored
+ // in proxy_*.
+ void ApplyProxySettings();
+
+ bool HasProxyPolicy(ConfigurationPolicyType policy) const;
+
+ // Temporary cache that stores values until FinalizeProxyPolicySettings()
+ // is called.
+ std::map<ConfigurationPolicyType, Value*> proxy_policies_;
+
+ // Set to false until the first proxy-relevant policy is applied. At that
+ // time, default values are provided for all proxy-relevant prefs
+ // to override any values set from stores with a lower priority.
+ bool lower_priority_proxy_settings_overridden_;
+
+ // The following are used to track what proxy-relevant policy has been applied
+ // accross calls to Apply to provide a warning if a policy specifies a
+ // contradictory proxy configuration. |proxy_disabled_| is set to true if and
+ // only if the kPolicyNoProxyServer has been applied,
+ // |proxy_configuration_specified_| is set to true if and only if any other
+ // proxy policy other than kPolicyNoProxyServer has been applied.
+ bool proxy_disabled_;
+ bool proxy_configuration_specified_;
+
+ // Set to true if a the proxy mode policy has been set to force Chrome
+ // to use the system proxy.
+ bool use_system_proxy_;
+
+ PrefValueMap prefs_;
+
+ static const PolicyToPreferenceMapEntry kSimplePolicyMap[];
+ static const PolicyToPreferenceMapEntry kProxyPolicyMap[];
+ static const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[];
+
+ DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyPrefKeeper);
};
-ConfigurationPolicyProvider*
- ConfigurationPolicyProviderKeeper::CreateManagedPlatformProvider() {
- const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list =
- ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
-#if defined(OS_WIN)
- return new ConfigurationPolicyProviderWin(policy_list);
-#elif defined(OS_MACOSX)
- return new ConfigurationPolicyProviderMac(policy_list);
-#elif defined(OS_POSIX)
- FilePath config_dir_path;
- if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
- return new ConfigDirPolicyProvider(
- policy_list,
- config_dir_path.Append(FILE_PATH_LITERAL("managed")));
- } else {
- return new DummyConfigurationPolicyProvider(policy_list);
- }
-#else
- return new DummyConfigurationPolicyProvider(policy_list);
-#endif
-}
-
-ConfigurationPolicyProvider*
- ConfigurationPolicyProviderKeeper::CreateDeviceManagementProvider() {
- return new DummyConfigurationPolicyProvider(
- ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList());
-}
-
-ConfigurationPolicyProvider*
- ConfigurationPolicyProviderKeeper::CreateRecommendedProvider() {
- const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list =
- ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
- FilePath config_dir_path;
- if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
- return new ConfigDirPolicyProvider(
- policy_list,
- config_dir_path.Append(FILE_PATH_LITERAL("recommended")));
- } else {
- return new DummyConfigurationPolicyProvider(policy_list);
- }
-#else
- return new DummyConfigurationPolicyProvider(policy_list);
-#endif
-}
-
-const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
- ConfigurationPolicyPrefStore::kSimplePolicyMap[] = {
+const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry
+ ConfigurationPolicyPrefKeeper::kSimplePolicyMap[] = {
{ Value::TYPE_STRING, kPolicyHomePage, prefs::kHomePage },
{ Value::TYPE_BOOLEAN, kPolicyHomepageIsNewTabPage,
prefs::kHomePageIsNewTabPage },
@@ -160,17 +201,21 @@ const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
{ Value::TYPE_BOOLEAN, kPolicyDeveloperToolsDisabled,
prefs::kDevToolsDisabled },
{ Value::TYPE_BOOLEAN, kPolicyBlockThirdPartyCookies,
- prefs::kBlockThirdPartyCookies},
+ prefs::kBlockThirdPartyCookies },
{ Value::TYPE_INTEGER, kPolicyDefaultCookiesSetting,
- prefs::kManagedDefaultCookiesSetting},
+ prefs::kManagedDefaultCookiesSetting },
{ Value::TYPE_INTEGER, kPolicyDefaultImagesSetting,
- prefs::kManagedDefaultImagesSetting},
+ prefs::kManagedDefaultImagesSetting },
{ Value::TYPE_INTEGER, kPolicyDefaultJavaScriptSetting,
- prefs::kManagedDefaultJavaScriptSetting},
+ prefs::kManagedDefaultJavaScriptSetting },
{ Value::TYPE_INTEGER, kPolicyDefaultPluginsSetting,
- prefs::kManagedDefaultPluginsSetting},
+ prefs::kManagedDefaultPluginsSetting },
{ Value::TYPE_INTEGER, kPolicyDefaultPopupsSetting,
- prefs::kManagedDefaultPopupsSetting},
+ prefs::kManagedDefaultPopupsSetting },
+ { Value::TYPE_INTEGER, kPolicyDefaultNotificationSetting,
+ prefs::kDesktopNotificationDefaultContentSetting },
+ { Value::TYPE_INTEGER, kPolicyDefaultGeolocationSetting,
+ prefs::kGeolocationDefaultContentSetting },
{ Value::TYPE_STRING, kPolicyAuthSchemes,
prefs::kAuthSchemes },
{ Value::TYPE_BOOLEAN, kPolicyDisableAuthNegotiateCnameLookup,
@@ -192,8 +237,8 @@ const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
#endif
};
-const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
- ConfigurationPolicyPrefStore::kDefaultSearchPolicyMap[] = {
+const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry
+ ConfigurationPolicyPrefKeeper::kDefaultSearchPolicyMap[] = {
{ Value::TYPE_BOOLEAN, kPolicyDefaultSearchProviderEnabled,
prefs::kDefaultSearchProviderEnabled },
{ Value::TYPE_STRING, kPolicyDefaultSearchProviderName,
@@ -210,137 +255,53 @@ const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
prefs::kDefaultSearchProviderEncodings },
};
-const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry
- ConfigurationPolicyPrefStore::kProxyPolicyMap[] = {
+const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry
+ ConfigurationPolicyPrefKeeper::kProxyPolicyMap[] = {
{ Value::TYPE_STRING, kPolicyProxyServer, prefs::kProxyServer },
{ Value::TYPE_STRING, kPolicyProxyPacUrl, prefs::kProxyPacUrl },
{ Value::TYPE_STRING, kPolicyProxyBypassList, prefs::kProxyBypassList }
};
-/* static */
-const ConfigurationPolicyProvider::PolicyDefinitionList*
-ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() {
- static ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[] = {
- { kPolicyHomePage, Value::TYPE_STRING, key::kHomepageLocation },
- { kPolicyHomepageIsNewTabPage, Value::TYPE_BOOLEAN,
- key::kHomepageIsNewTabPage },
- { kPolicyRestoreOnStartup, Value::TYPE_INTEGER, key::kRestoreOnStartup },
- { kPolicyURLsToRestoreOnStartup, Value::TYPE_LIST,
- key::kURLsToRestoreOnStartup },
- { kPolicyDefaultSearchProviderEnabled, Value::TYPE_BOOLEAN,
- key::kDefaultSearchProviderEnabled },
- { kPolicyDefaultSearchProviderName, Value::TYPE_STRING,
- key::kDefaultSearchProviderName },
- { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING,
- key::kDefaultSearchProviderKeyword },
- { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING,
- key::kDefaultSearchProviderSearchURL },
- { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING,
- key::kDefaultSearchProviderSuggestURL },
- { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING,
- key::kDefaultSearchProviderIconURL },
- { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING,
- key::kDefaultSearchProviderEncodings },
- { kPolicyProxyServerMode, Value::TYPE_INTEGER, key::kProxyServerMode },
- { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer },
- { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl },
- { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList },
- { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN,
- key::kAlternateErrorPagesEnabled },
- { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN,
- key::kSearchSuggestEnabled },
- { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN,
- key::kDnsPrefetchingEnabled },
- { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy },
- { kPolicySafeBrowsingEnabled, Value::TYPE_BOOLEAN,
- key::kSafeBrowsingEnabled },
- { kPolicyMetricsReportingEnabled, Value::TYPE_BOOLEAN,
- key::kMetricsReportingEnabled },
- { kPolicyPasswordManagerEnabled, Value::TYPE_BOOLEAN,
- key::kPasswordManagerEnabled },
- { kPolicyPasswordManagerAllowShowPasswords, Value::TYPE_BOOLEAN,
- key::kPasswordManagerAllowShowPasswords },
- { kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled },
- { kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins },
- { kPolicyApplicationLocale, Value::TYPE_STRING,
- key::kApplicationLocaleValue },
- { kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled },
- { kPolicyExtensionInstallAllowList, Value::TYPE_LIST,
- key::kExtensionInstallAllowList },
- { kPolicyExtensionInstallDenyList, Value::TYPE_LIST,
- key::kExtensionInstallDenyList },
- { kPolicyExtensionInstallForceList, Value::TYPE_LIST,
- key::kExtensionInstallForceList },
- { kPolicyShowHomeButton, Value::TYPE_BOOLEAN, key::kShowHomeButton },
- { kPolicyPrintingEnabled, Value::TYPE_BOOLEAN, key::kPrintingEnabled },
- { kPolicyJavascriptEnabled, Value::TYPE_BOOLEAN, key::kJavascriptEnabled },
- { kPolicySavingBrowserHistoryDisabled, Value::TYPE_BOOLEAN,
- key::kSavingBrowserHistoryDisabled },
- { kPolicyDeveloperToolsDisabled, Value::TYPE_BOOLEAN,
- key::kDeveloperToolsDisabled },
- { kPolicyBlockThirdPartyCookies, Value::TYPE_BOOLEAN,
- key::kBlockThirdPartyCookies },
- { kPolicyDefaultCookiesSetting, Value::TYPE_INTEGER,
- key::kDefaultCookiesSetting},
- { kPolicyDefaultImagesSetting, Value::TYPE_INTEGER,
- key::kDefaultImagesSetting},
- { kPolicyDefaultJavaScriptSetting, Value::TYPE_INTEGER,
- key::kDefaultJavaScriptSetting},
- { kPolicyDefaultPluginsSetting, Value::TYPE_INTEGER,
- key::kDefaultPluginsSetting},
- { kPolicyDefaultPopupsSetting, Value::TYPE_INTEGER,
- key::kDefaultPopupsSetting},
- { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes },
- { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN,
- key::kDisableAuthNegotiateCnameLookup },
- { kPolicyEnableAuthNegotiatePort, Value::TYPE_BOOLEAN,
- key::kEnableAuthNegotiatePort },
- { kPolicyAuthServerWhitelist, Value::TYPE_STRING,
- key::kAuthServerWhitelist },
- { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING,
- key::kAuthNegotiateDelegateWhitelist },
- { kPolicyGSSAPILibraryName, Value::TYPE_STRING,
- key::kGSSAPILibraryName },
- { kPolicyDisable3DAPIs, Value::TYPE_BOOLEAN,
- key::kDisable3DAPIs },
+ConfigurationPolicyPrefKeeper::ConfigurationPolicyPrefKeeper(
+ ConfigurationPolicyProvider* provider)
+ : lower_priority_proxy_settings_overridden_(false),
+ proxy_disabled_(false),
+ proxy_configuration_specified_(false),
+ use_system_proxy_(false) {
+ if (!provider->Provide(this))
+ LOG(WARNING) << "Failed to get policy from provider.";
+ FinalizeProxyPolicySettings();
+ FinalizeDefaultSearchPolicySettings();
+}
+ConfigurationPolicyPrefKeeper::~ConfigurationPolicyPrefKeeper() {
+ DCHECK(proxy_policies_.empty());
+}
-#if defined(OS_CHROMEOS)
- { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN,
- key::kChromeOsLockOnIdleSuspend },
-#endif
- };
+PrefStore::ReadResult
+ConfigurationPolicyPrefKeeper::GetValue(const std::string& key,
+ Value** result) const {
+ Value* stored_value = NULL;
+ if (!prefs_.GetValue(key, &stored_value))
+ return PrefStore::READ_NO_VALUE;
- static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = {
- entries,
- entries + arraysize(entries),
- };
- return &policy_list;
-}
+ // Check whether there's a default value, which indicates READ_USE_DEFAULT
+ // should be returned.
+ if (stored_value->IsType(Value::TYPE_NULL))
+ return PrefStore::READ_USE_DEFAULT;
-ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore(
- ConfigurationPolicyProvider* provider)
- : provider_(provider),
- prefs_(new DictionaryValue()),
- lower_priority_proxy_settings_overridden_(false),
- proxy_disabled_(false),
- proxy_configuration_specified_(false),
- use_system_proxy_(false) {
+ *result = stored_value;
+ return PrefStore::READ_OK;
}
-PrefStore::PrefReadError ConfigurationPolicyPrefStore::ReadPrefs() {
- proxy_disabled_ = false;
- proxy_configuration_specified_ = false;
- lower_priority_proxy_settings_overridden_ = false;
-
- const bool success = (provider_ == NULL || provider_->Provide(this));
- FinalizeDefaultSearchPolicySettings();
- return success ? PrefStore::PREF_READ_ERROR_NONE :
- PrefStore::PREF_READ_ERROR_OTHER;
+void ConfigurationPolicyPrefKeeper::GetDifferingPrefPaths(
+ const ConfigurationPolicyPrefKeeper* other,
+ std::vector<std::string>* differing_prefs) const {
+ prefs_.GetDifferingKeys(&other->prefs_, differing_prefs);
}
-void ConfigurationPolicyPrefStore::Apply(ConfigurationPolicyType policy,
- Value* value) {
+void ConfigurationPolicyPrefKeeper::Apply(ConfigurationPolicyType policy,
+ Value* value) {
if (ApplyProxyPolicy(policy, value))
return;
@@ -363,49 +324,8 @@ void ConfigurationPolicyPrefStore::Apply(ConfigurationPolicyType policy,
delete value;
}
-// static
-ConfigurationPolicyPrefStore*
-ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore() {
- ConfigurationPolicyProviderKeeper* keeper =
- Singleton<ConfigurationPolicyProviderKeeper>::get();
- return new ConfigurationPolicyPrefStore(keeper->managed_platform_provider());
-}
-
-// static
-ConfigurationPolicyPrefStore*
-ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
- Profile* profile) {
- ConfigurationPolicyProviderKeeper* keeper =
- Singleton<ConfigurationPolicyProviderKeeper>::get();
- ConfigurationPolicyProvider* provider = NULL;
- if (profile)
- provider = profile->GetPolicyContext()->GetDeviceManagementPolicyProvider();
- if (!provider)
- provider = keeper->device_management_provider();
- return new ConfigurationPolicyPrefStore(provider);
-}
-
-// static
-ConfigurationPolicyPrefStore*
-ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() {
- ConfigurationPolicyProviderKeeper* keeper =
- Singleton<ConfigurationPolicyProviderKeeper>::get();
- return new ConfigurationPolicyPrefStore(keeper->recommended_provider());
-}
-
-// static
-void ConfigurationPolicyPrefStore::GetProxyPreferenceSet(
- ProxyPreferenceSet* proxy_pref_set) {
- proxy_pref_set->clear();
- for (size_t current = 0; current < arraysize(kProxyPolicyMap); ++current) {
- proxy_pref_set->insert(kProxyPolicyMap[current].preference_path);
- }
- proxy_pref_set->insert(prefs::kNoProxyServer);
- proxy_pref_set->insert(prefs::kProxyAutoDetect);
-}
-
-const ConfigurationPolicyPrefStore::PolicyToPreferenceMapEntry*
-ConfigurationPolicyPrefStore::FindPolicyInMap(
+const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry*
+ConfigurationPolicyPrefKeeper::FindPolicyInMap(
ConfigurationPolicyType policy,
const PolicyToPreferenceMapEntry* map,
int table_size) const {
@@ -416,17 +336,17 @@ ConfigurationPolicyPrefStore::FindPolicyInMap(
return NULL;
}
-bool ConfigurationPolicyPrefStore::RemovePreferencesOfMap(
+bool ConfigurationPolicyPrefKeeper::RemovePreferencesOfMap(
const PolicyToPreferenceMapEntry* map, int table_size) {
bool found_any = false;
for (int i = 0; i < table_size; ++i) {
- if (prefs_->Remove(map[i].preference_path, NULL))
+ if (prefs_.RemoveValue(map[i].preference_path))
found_any = true;
}
return found_any;
}
-bool ConfigurationPolicyPrefStore::ApplyPolicyFromMap(
+bool ConfigurationPolicyPrefKeeper::ApplyPolicyFromMap(
ConfigurationPolicyType policy,
Value* value,
const PolicyToPreferenceMapEntry* map,
@@ -437,124 +357,37 @@ bool ConfigurationPolicyPrefStore::ApplyPolicyFromMap(
<< "mismatch in provided and expected policy value for preferences"
<< map[current].preference_path << ". expected = "
<< map[current].value_type << ", actual = "<< value->GetType();
- prefs_->Set(map[current].preference_path, value);
+ prefs_.SetValue(map[current].preference_path, value);
return true;
}
}
return false;
}
-bool ConfigurationPolicyPrefStore::ApplyProxyPolicy(
+bool ConfigurationPolicyPrefKeeper::ApplyProxyPolicy(
ConfigurationPolicyType policy,
Value* value) {
- bool result = false;
- bool warn_about_proxy_disable_config = false;
- bool warn_about_proxy_system_config = false;
-
- const PolicyToPreferenceMapEntry* match_entry =
- FindPolicyInMap(policy, kProxyPolicyMap, arraysize(kProxyPolicyMap));
-
- // When the first proxy-related policy is applied, ALL proxy-related
- // preferences that have been set by command-line switches, extensions,
- // user preferences or any other mechanism are overridden. Otherwise
- // it's possible for a user to interfere with proxy policy by setting
- // proxy-related command-line switches or set proxy-related prefs in an
- // extension that are related, but not identical, to the ones set through
- // policy.
- if (!lower_priority_proxy_settings_overridden_ &&
- (match_entry ||
- policy == kPolicyProxyServerMode)) {
- ProxyPreferenceSet proxy_preference_set;
- GetProxyPreferenceSet(&proxy_preference_set);
- for (ProxyPreferenceSet::const_iterator i = proxy_preference_set.begin();
- i != proxy_preference_set.end(); ++i) {
- prefs_->Set(*i, PrefStore::CreateUseDefaultSentinelValue());
- }
- lower_priority_proxy_settings_overridden_ = true;
- }
-
- // Translate the proxy policy into preferences.
- if (policy == kPolicyProxyServerMode) {
- int int_value;
- bool proxy_auto_detect = false;
- if (value->GetAsInteger(&int_value)) {
- result = true;
- switch (int_value) {
- case kPolicyNoProxyServerMode:
- if (!proxy_disabled_) {
- if (proxy_configuration_specified_)
- warn_about_proxy_disable_config = true;
- proxy_disabled_ = true;
- }
- break;
- case kPolicyAutoDetectProxyMode:
- proxy_auto_detect = true;
- break;
- case kPolicyManuallyConfiguredProxyMode:
- break;
- case kPolicyUseSystemProxyMode:
- if (!use_system_proxy_) {
- if (proxy_configuration_specified_)
- warn_about_proxy_system_config = true;
- use_system_proxy_ = true;
- }
- break;
- default:
- // Not a valid policy, don't assume ownership of |value|
- result = false;
- break;
- }
-
- if (int_value != kPolicyUseSystemProxyMode) {
- prefs_->Set(prefs::kNoProxyServer,
- Value::CreateBooleanValue(proxy_disabled_));
- prefs_->Set(prefs::kProxyAutoDetect,
- Value::CreateBooleanValue(proxy_auto_detect));
- }
- }
- } else if (match_entry) {
- // Determine if the applied proxy policy settings conflict and issue
- // a corresponding warning if they do.
- if (!proxy_configuration_specified_) {
- if (proxy_disabled_)
- warn_about_proxy_disable_config = true;
- if (use_system_proxy_)
- warn_about_proxy_system_config = true;
- proxy_configuration_specified_ = true;
- }
- if (!use_system_proxy_ && !proxy_disabled_) {
- prefs_->Set(match_entry->preference_path, value);
- // The ownership of value has been passed on to |prefs_|,
- // don't clean it up later.
- value = NULL;
- }
- result = true;
- }
-
- if (warn_about_proxy_disable_config) {
- LOG(WARNING) << "A centrally-administered policy disables the use of"
- << " a proxy but also specifies an explicit proxy"
- << " configuration.";
- }
-
- if (warn_about_proxy_system_config) {
- LOG(WARNING) << "A centrally-administered policy dictates that the"
- << " system proxy settings should be used but also specifies"
- << " an explicit proxy configuration.";
+ // We only collect the values until we have sufficient information when
+ // FinalizeProxyPolicySettings() is called to determine whether the presented
+ // values were correct and apply them in that case.
+ if (policy == kPolicyProxyMode ||
+ policy == kPolicyProxyServer ||
+ policy == kPolicyProxyPacUrl ||
+ policy == kPolicyProxyBypassList) {
+ delete proxy_policies_[policy];
+ proxy_policies_[policy] = value;
+ return true;
}
-
- // If the policy was a proxy policy, cleanup |value|.
- if (result && value)
- delete value;
- return result;
+ // We are not interested in this policy.
+ return false;
}
-bool ConfigurationPolicyPrefStore::ApplySyncPolicy(
+bool ConfigurationPolicyPrefKeeper::ApplySyncPolicy(
ConfigurationPolicyType policy, Value* value) {
if (policy == kPolicySyncDisabled) {
bool disable_sync;
if (value->GetAsBoolean(&disable_sync) && disable_sync)
- prefs_->Set(prefs::kSyncManaged, value);
+ prefs_.SetValue(prefs::kSyncManaged, value);
else
delete value;
return true;
@@ -562,23 +395,24 @@ bool ConfigurationPolicyPrefStore::ApplySyncPolicy(
return false;
}
-bool ConfigurationPolicyPrefStore::ApplyAutoFillPolicy(
+bool ConfigurationPolicyPrefKeeper::ApplyAutoFillPolicy(
ConfigurationPolicyType policy, Value* value) {
if (policy == kPolicyAutoFillEnabled) {
bool auto_fill_enabled;
if (value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled)
- prefs_->Set(prefs::kAutoFillEnabled, Value::CreateBooleanValue(false));
+ prefs_.SetValue(prefs::kAutoFillEnabled,
+ Value::CreateBooleanValue(false));
delete value;
return true;
}
return false;
}
-void ConfigurationPolicyPrefStore::EnsureStringPrefExists(
+void ConfigurationPolicyPrefKeeper::EnsureStringPrefExists(
const std::string& path) {
std::string value;
- if (!prefs_->GetString(path, &value))
- prefs_->SetString(path, value);
+ if (!prefs_.GetString(path, &value))
+ prefs_.SetString(path, value);
}
namespace {
@@ -604,24 +438,24 @@ class SearchTermsDataForValidation : public SearchTermsData {
DISALLOW_COPY_AND_ASSIGN(SearchTermsDataForValidation);
};
-} // namepsace
+} // namespace
-void ConfigurationPolicyPrefStore::FinalizeDefaultSearchPolicySettings() {
+void ConfigurationPolicyPrefKeeper::FinalizeDefaultSearchPolicySettings() {
bool enabled = true;
- if (prefs_->GetBoolean(prefs::kDefaultSearchProviderEnabled, &enabled) &&
+ if (prefs_.GetBoolean(prefs::kDefaultSearchProviderEnabled, &enabled) &&
!enabled) {
// If default search is disabled, we ignore the other fields.
- prefs_->SetString(prefs::kDefaultSearchProviderName, std::string());
- prefs_->SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
- prefs_->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
- prefs_->SetString(prefs::kDefaultSearchProviderIconURL, std::string());
- prefs_->SetString(prefs::kDefaultSearchProviderEncodings, std::string());
- prefs_->SetString(prefs::kDefaultSearchProviderKeyword, std::string());
+ prefs_.SetString(prefs::kDefaultSearchProviderName, std::string());
+ prefs_.SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
+ prefs_.SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
+ prefs_.SetString(prefs::kDefaultSearchProviderIconURL, std::string());
+ prefs_.SetString(prefs::kDefaultSearchProviderEncodings, std::string());
+ prefs_.SetString(prefs::kDefaultSearchProviderKeyword, std::string());
return;
}
std::string search_url;
// The search URL is required.
- if (prefs_->GetString(prefs::kDefaultSearchProviderSearchURL, &search_url) &&
+ if (prefs_.GetString(prefs::kDefaultSearchProviderSearchURL, &search_url) &&
!search_url.empty()) {
SearchTermsDataForValidation search_terms_data;
const TemplateURLRef search_url_ref(search_url, 0, 0);
@@ -636,14 +470,14 @@ void ConfigurationPolicyPrefStore::FinalizeDefaultSearchPolicySettings() {
// For the name, default to the host if not specified.
std::string name;
- if (!prefs_->GetString(prefs::kDefaultSearchProviderName, &name) ||
+ if (!prefs_.GetString(prefs::kDefaultSearchProviderName, &name) ||
name.empty())
- prefs_->SetString(prefs::kDefaultSearchProviderName,
+ prefs_.SetString(prefs::kDefaultSearchProviderName,
GURL(search_url).host());
// And clear the IDs since these are not specified via policy.
- prefs_->SetString(prefs::kDefaultSearchProviderID, std::string());
- prefs_->SetString(prefs::kDefaultSearchProviderPrepopulateID,
+ prefs_.SetString(prefs::kDefaultSearchProviderID, std::string());
+ prefs_.SetString(prefs::kDefaultSearchProviderPrepopulateID,
std::string());
return;
}
@@ -653,4 +487,419 @@ void ConfigurationPolicyPrefStore::FinalizeDefaultSearchPolicySettings() {
arraysize(kDefaultSearchPolicyMap));
}
+void ConfigurationPolicyPrefKeeper::FinalizeProxyPolicySettings() {
+ if (CheckProxySettings())
+ ApplyProxySettings();
+
+ STLDeleteContainerPairSecondPointers(proxy_policies_.begin(),
+ proxy_policies_.end());
+ proxy_policies_.clear();
+}
+
+bool ConfigurationPolicyPrefKeeper::CheckProxySettings() {
+ bool mode = HasProxyPolicy(kPolicyProxyMode);
+ bool server = HasProxyPolicy(kPolicyProxyServer);
+ bool pac_url = HasProxyPolicy(kPolicyProxyPacUrl);
+ bool bypass_list = HasProxyPolicy(kPolicyProxyBypassList);
+
+ if ((server || pac_url || bypass_list) && !mode) {
+ LOG(WARNING) << "A centrally-administered policy defines proxy setting"
+ << " details without setting a proxy mode.";
+ return false;
+ }
+
+ if (!mode)
+ return true;
+
+ int mode_value;
+ if (!proxy_policies_[kPolicyProxyMode]->GetAsInteger(&mode_value)) {
+ LOG(WARNING) << "Invalid proxy mode value.";
+ return false;
+ }
+
+ switch (mode_value) {
+ case kPolicyNoProxyServerMode:
+ if (server || pac_url || bypass_list) {
+ LOG(WARNING) << "A centrally-administered policy disables the use of"
+ << " a proxy but also specifies an explicit proxy"
+ << " configuration.";
+ return false;
+ }
+ break;
+ case kPolicyAutoDetectProxyMode:
+ if (server || bypass_list) {
+ LOG(WARNING) << "A centrally-administered policy dictates that a proxy"
+ << " shall be auto configured but specifies fixed proxy"
+ << " servers or a by-pass list.";
+ return false;
+ }
+ break;
+ case kPolicyManuallyConfiguredProxyMode:
+ if (!server) {
+ LOG(WARNING) << "A centrally-administered policy dictates that the"
+ << " system proxy settings should use fixed proxy servers"
+ << " without specifying which ones.";
+ return false;
+ }
+ if (pac_url) {
+ LOG(WARNING) << "A centrally-administered policy dictates that the"
+ << " system proxy settings should use fixed proxy servers"
+ << " but also specifies a PAC script.";
+ return false;
+ }
+ break;
+ case kPolicyUseSystemProxyMode:
+ if (server || pac_url || bypass_list) {
+ LOG(WARNING) << "A centrally-administered policy dictates that the"
+ << " system proxy settings should be used but also "
+ << " specifies an explicit proxy configuration.";
+ return false;
+ }
+ break;
+ default:
+ LOG(WARNING) << "Invalid proxy mode " << mode_value;
+ return false;
+ }
+ return true;
+}
+
+void ConfigurationPolicyPrefKeeper::ApplyProxySettings() {
+ if (!HasProxyPolicy(kPolicyProxyMode))
+ return;
+
+ int int_mode;
+ CHECK(proxy_policies_[kPolicyProxyMode]->GetAsInteger(&int_mode));
+ ProxyPrefs::ProxyMode mode;
+ switch (int_mode) {
+ case kPolicyNoProxyServerMode:
+ mode = ProxyPrefs::MODE_DIRECT;
+ break;
+ case kPolicyAutoDetectProxyMode:
+ mode = ProxyPrefs::MODE_AUTO_DETECT;
+ if (HasProxyPolicy(kPolicyProxyPacUrl))
+ mode = ProxyPrefs::MODE_PAC_SCRIPT;
+ break;
+ case kPolicyManuallyConfiguredProxyMode:
+ mode = ProxyPrefs::MODE_FIXED_SERVERS;
+ break;
+ case kPolicyUseSystemProxyMode:
+ mode = ProxyPrefs::MODE_SYSTEM;
+ break;
+ default:
+ mode = ProxyPrefs::MODE_DIRECT;
+ NOTREACHED();
+ }
+ prefs_.SetValue(prefs::kProxyMode, Value::CreateIntegerValue(mode));
+
+ if (HasProxyPolicy(kPolicyProxyServer)) {
+ prefs_.SetValue(prefs::kProxyServer, proxy_policies_[kPolicyProxyServer]);
+ proxy_policies_[kPolicyProxyServer] = NULL;
+ } else {
+ prefs_.SetValue(prefs::kProxyServer, Value::CreateNullValue());
+ }
+ if (HasProxyPolicy(kPolicyProxyPacUrl)) {
+ prefs_.SetValue(prefs::kProxyPacUrl, proxy_policies_[kPolicyProxyPacUrl]);
+ proxy_policies_[kPolicyProxyPacUrl] = NULL;
+ } else {
+ prefs_.SetValue(prefs::kProxyPacUrl, Value::CreateNullValue());
+ }
+ if (HasProxyPolicy(kPolicyProxyBypassList)) {
+ prefs_.SetValue(prefs::kProxyBypassList,
+ proxy_policies_[kPolicyProxyBypassList]);
+ proxy_policies_[kPolicyProxyBypassList] = NULL;
+ } else {
+ prefs_.SetValue(prefs::kProxyBypassList, Value::CreateNullValue());
+ }
+}
+
+bool ConfigurationPolicyPrefKeeper::HasProxyPolicy(
+ ConfigurationPolicyType policy) const {
+ std::map<ConfigurationPolicyType, Value*>::const_iterator iter;
+ iter = proxy_policies_.find(policy);
+ return iter != proxy_policies_.end() &&
+ iter->second && !iter->second->IsType(Value::TYPE_NULL);
+}
+
+namespace {
+
+// Manages the lifecycle of the shared platform-specific policy providers for
+// managed platform, device management and recommended policy. Instantiated as a
+// Singleton.
+class ConfigurationPolicyProviderKeeper {
+ public:
+ ConfigurationPolicyProviderKeeper()
+ : managed_platform_provider_(CreateManagedPlatformProvider()),
+ device_management_provider_(CreateDeviceManagementProvider()),
+ recommended_provider_(CreateRecommendedProvider()) {}
+ virtual ~ConfigurationPolicyProviderKeeper() {}
+
+ ConfigurationPolicyProvider* managed_platform_provider() const {
+ return managed_platform_provider_.get();
+ }
+
+ ConfigurationPolicyProvider* device_management_provider() const {
+ return device_management_provider_.get();
+ }
+
+ ConfigurationPolicyProvider* recommended_provider() const {
+ return recommended_provider_.get();
+ }
+
+ private:
+ scoped_ptr<ConfigurationPolicyProvider> managed_platform_provider_;
+ scoped_ptr<ConfigurationPolicyProvider> device_management_provider_;
+ scoped_ptr<ConfigurationPolicyProvider> recommended_provider_;
+
+ static ConfigurationPolicyProvider* CreateManagedPlatformProvider();
+ static ConfigurationPolicyProvider* CreateDeviceManagementProvider();
+ static ConfigurationPolicyProvider* CreateRecommendedProvider();
+
+ DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProviderKeeper);
+};
+
+static base::LazyInstance<ConfigurationPolicyProviderKeeper>
+ g_configuration_policy_provider_keeper(base::LINKER_INITIALIZED);
+
+ConfigurationPolicyProvider*
+ConfigurationPolicyProviderKeeper::CreateManagedPlatformProvider() {
+ const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list =
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
+#if defined(OS_WIN)
+ return new ConfigurationPolicyProviderWin(policy_list);
+#elif defined(OS_MACOSX)
+ return new ConfigurationPolicyProviderMac(policy_list);
+#elif defined(OS_POSIX)
+ FilePath config_dir_path;
+ if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
+ return new ConfigDirPolicyProvider(
+ policy_list,
+ config_dir_path.Append(FILE_PATH_LITERAL("managed")));
+ } else {
+ return new DummyConfigurationPolicyProvider(policy_list);
+ }
+#else
+ return new DummyConfigurationPolicyProvider(policy_list);
+#endif
+}
+
+ConfigurationPolicyProvider*
+ConfigurationPolicyProviderKeeper::CreateDeviceManagementProvider() {
+ return new DummyConfigurationPolicyProvider(
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList());
+}
+
+ConfigurationPolicyProvider*
+ConfigurationPolicyProviderKeeper::CreateRecommendedProvider() {
+ const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list =
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+ FilePath config_dir_path;
+ if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
+ return new ConfigDirPolicyProvider(
+ policy_list,
+ config_dir_path.Append(FILE_PATH_LITERAL("recommended")));
+ } else {
+ return new DummyConfigurationPolicyProvider(policy_list);
+ }
+#else
+ return new DummyConfigurationPolicyProvider(policy_list);
+#endif
+}
+
+} // namespace
+
+ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore(
+ ConfigurationPolicyProvider* provider)
+ : provider_(provider),
+ initialization_complete_(provider->IsInitializationComplete()) {
+ // Read initial policy.
+ policy_keeper_.reset(new ConfigurationPolicyPrefKeeper(provider));
+
+ registrar_.Init(provider_);
+ registrar_.AddObserver(this);
+}
+
+ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {
+}
+
+void ConfigurationPolicyPrefStore::AddObserver(PrefStore::Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void ConfigurationPolicyPrefStore::RemoveObserver(
+ PrefStore::Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+bool ConfigurationPolicyPrefStore::IsInitializationComplete() const {
+ return initialization_complete_;
+}
+
+PrefStore::ReadResult
+ConfigurationPolicyPrefStore::GetValue(const std::string& key,
+ Value** value) const {
+ return policy_keeper_->GetValue(key, value);
+}
+
+void ConfigurationPolicyPrefStore::OnUpdatePolicy() {
+ Refresh();
+}
+
+// static
+ConfigurationPolicyPrefStore*
+ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore() {
+ return new ConfigurationPolicyPrefStore(
+ g_configuration_policy_provider_keeper.Get().managed_platform_provider());
+}
+
+// static
+ConfigurationPolicyPrefStore*
+ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
+ Profile* profile) {
+ ConfigurationPolicyProviderKeeper* keeper =
+ g_configuration_policy_provider_keeper.Pointer();
+ ConfigurationPolicyProvider* provider = NULL;
+ if (profile)
+ provider = profile->GetPolicyContext()->GetDeviceManagementPolicyProvider();
+ if (!provider)
+ provider = keeper->device_management_provider();
+ return new ConfigurationPolicyPrefStore(provider);
+}
+
+// static
+ConfigurationPolicyPrefStore*
+ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore() {
+ return new ConfigurationPolicyPrefStore(
+ g_configuration_policy_provider_keeper.Get().recommended_provider());
+}
+
+/* static */
+const ConfigurationPolicyProvider::PolicyDefinitionList*
+ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() {
+ static ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[] = {
+ { kPolicyHomePage, Value::TYPE_STRING, key::kHomepageLocation },
+ { kPolicyHomepageIsNewTabPage, Value::TYPE_BOOLEAN,
+ key::kHomepageIsNewTabPage },
+ { kPolicyRestoreOnStartup, Value::TYPE_INTEGER, key::kRestoreOnStartup },
+ { kPolicyURLsToRestoreOnStartup, Value::TYPE_LIST,
+ key::kURLsToRestoreOnStartup },
+ { kPolicyDefaultSearchProviderEnabled, Value::TYPE_BOOLEAN,
+ key::kDefaultSearchProviderEnabled },
+ { kPolicyDefaultSearchProviderName, Value::TYPE_STRING,
+ key::kDefaultSearchProviderName },
+ { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING,
+ key::kDefaultSearchProviderKeyword },
+ { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING,
+ key::kDefaultSearchProviderSearchURL },
+ { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING,
+ key::kDefaultSearchProviderSuggestURL },
+ { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING,
+ key::kDefaultSearchProviderIconURL },
+ { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING,
+ key::kDefaultSearchProviderEncodings },
+ { kPolicyProxyMode, Value::TYPE_INTEGER, key::kProxyMode },
+ { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer },
+ { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl },
+ { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList },
+ { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN,
+ key::kAlternateErrorPagesEnabled },
+ { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN,
+ key::kSearchSuggestEnabled },
+ { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN,
+ key::kDnsPrefetchingEnabled },
+ { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy },
+ { kPolicySafeBrowsingEnabled, Value::TYPE_BOOLEAN,
+ key::kSafeBrowsingEnabled },
+ { kPolicyMetricsReportingEnabled, Value::TYPE_BOOLEAN,
+ key::kMetricsReportingEnabled },
+ { kPolicyPasswordManagerEnabled, Value::TYPE_BOOLEAN,
+ key::kPasswordManagerEnabled },
+ { kPolicyPasswordManagerAllowShowPasswords, Value::TYPE_BOOLEAN,
+ key::kPasswordManagerAllowShowPasswords },
+ { kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled },
+ { kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins },
+ { kPolicyApplicationLocale, Value::TYPE_STRING,
+ key::kApplicationLocaleValue },
+ { kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled },
+ { kPolicyExtensionInstallAllowList, Value::TYPE_LIST,
+ key::kExtensionInstallAllowList },
+ { kPolicyExtensionInstallDenyList, Value::TYPE_LIST,
+ key::kExtensionInstallDenyList },
+ { kPolicyExtensionInstallForceList, Value::TYPE_LIST,
+ key::kExtensionInstallForceList },
+ { kPolicyShowHomeButton, Value::TYPE_BOOLEAN, key::kShowHomeButton },
+ { kPolicyPrintingEnabled, Value::TYPE_BOOLEAN, key::kPrintingEnabled },
+ { kPolicyJavascriptEnabled, Value::TYPE_BOOLEAN, key::kJavascriptEnabled },
+ { kPolicySavingBrowserHistoryDisabled, Value::TYPE_BOOLEAN,
+ key::kSavingBrowserHistoryDisabled },
+ { kPolicyDeveloperToolsDisabled, Value::TYPE_BOOLEAN,
+ key::kDeveloperToolsDisabled },
+ { kPolicyBlockThirdPartyCookies, Value::TYPE_BOOLEAN,
+ key::kBlockThirdPartyCookies },
+ { kPolicyDefaultCookiesSetting, Value::TYPE_INTEGER,
+ key::kDefaultCookiesSetting },
+ { kPolicyDefaultImagesSetting, Value::TYPE_INTEGER,
+ key::kDefaultImagesSetting },
+ { kPolicyDefaultJavaScriptSetting, Value::TYPE_INTEGER,
+ key::kDefaultJavaScriptSetting },
+ { kPolicyDefaultPluginsSetting, Value::TYPE_INTEGER,
+ key::kDefaultPluginsSetting },
+ { kPolicyDefaultPopupsSetting, Value::TYPE_INTEGER,
+ key::kDefaultPopupsSetting },
+ { kPolicyDefaultNotificationSetting, Value::TYPE_INTEGER,
+ key::kDefaultNotificationSetting },
+ { kPolicyDefaultGeolocationSetting, Value::TYPE_INTEGER,
+ key::kDefaultGeolocationSetting },
+ { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes },
+ { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN,
+ key::kDisableAuthNegotiateCnameLookup },
+ { kPolicyEnableAuthNegotiatePort, Value::TYPE_BOOLEAN,
+ key::kEnableAuthNegotiatePort },
+ { kPolicyAuthServerWhitelist, Value::TYPE_STRING,
+ key::kAuthServerWhitelist },
+ { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING,
+ key::kAuthNegotiateDelegateWhitelist },
+ { kPolicyGSSAPILibraryName, Value::TYPE_STRING,
+ key::kGSSAPILibraryName },
+ { kPolicyDisable3DAPIs, Value::TYPE_BOOLEAN,
+ key::kDisable3DAPIs },
+
+#if defined(OS_CHROMEOS)
+ { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN,
+ key::kChromeOsLockOnIdleSuspend },
+#endif
+ };
+
+ static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = {
+ entries,
+ entries + arraysize(entries),
+ };
+ return &policy_list;
+}
+
+void ConfigurationPolicyPrefStore::Refresh() {
+ // Construct a new keeper, determine what changed and swap the keeper in.
+ scoped_ptr<ConfigurationPolicyPrefKeeper> new_keeper(
+ new ConfigurationPolicyPrefKeeper(provider_));
+ std::vector<std::string> changed_prefs;
+ new_keeper->GetDifferingPrefPaths(policy_keeper_.get(), &changed_prefs);
+ policy_keeper_.reset(new_keeper.release());
+
+ // Send out change notifications.
+ for (std::vector<std::string>::const_iterator pref(changed_prefs.begin());
+ pref != changed_prefs.end();
+ ++pref) {
+ FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
+ OnPrefValueChanged(*pref));
+ }
+
+ // Update the initialization flag.
+ if (!initialization_complete_ &&
+ provider_->IsInitializationComplete()) {
+ initialization_complete_ = true;
+ FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
+ OnInitializationCompleted());
+ }
+}
+
} // namespace policy
diff --git a/chrome/browser/policy/configuration_policy_pref_store.h b/chrome/browser/policy/configuration_policy_pref_store.h
index be898a8..526d884 100644
--- a/chrome/browser/policy/configuration_policy_pref_store.h
+++ b/chrome/browser/policy/configuration_policy_pref_store.h
@@ -10,7 +10,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/gtest_prod_util.h"
+#include "base/observer_list.h"
#include "base/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
@@ -21,24 +21,27 @@ class Profile;
namespace policy {
-// An implementation of the |PrefStore| that holds a Dictionary
-// created through applied policy.
-class ConfigurationPolicyPrefStore : public PrefStore,
- public ConfigurationPolicyStoreInterface {
- public:
- typedef std::set<const char*> ProxyPreferenceSet;
+class ConfigurationPolicyPrefKeeper;
+// An implementation of PrefStore that bridges policy settings as read from a
+// ConfigurationPolicyProvider to preferences.
+class ConfigurationPolicyPrefStore
+ : public PrefStore,
+ public ConfigurationPolicyProvider::Observer {
+ public:
// The ConfigurationPolicyPrefStore does not take ownership of the
// passed-in |provider|.
explicit ConfigurationPolicyPrefStore(ConfigurationPolicyProvider* provider);
- virtual ~ConfigurationPolicyPrefStore() {}
+ virtual ~ConfigurationPolicyPrefStore();
// PrefStore methods:
- virtual PrefReadError ReadPrefs();
- virtual DictionaryValue* prefs() const { return prefs_.get(); }
+ virtual void AddObserver(PrefStore::Observer* observer);
+ virtual void RemoveObserver(PrefStore::Observer* observer);
+ virtual bool IsInitializationComplete() const;
+ virtual ReadResult GetValue(const std::string& key, Value** result) const;
- // ConfigurationPolicyStore methods:
- virtual void Apply(ConfigurationPolicyType setting, Value* value);
+ // ConfigurationPolicyProvider::Observer methods:
+ virtual void OnUpdatePolicy();
// Creates a ConfigurationPolicyPrefStore that reads managed platform policy.
static ConfigurationPolicyPrefStore* CreateManagedPlatformPolicyPrefStore();
@@ -55,85 +58,27 @@ class ConfigurationPolicyPrefStore : public PrefStore,
static const ConfigurationPolicyProvider::PolicyDefinitionList*
GetChromePolicyDefinitionList();
- // Returns the set of preference paths that can be affected by a proxy
- // policy.
- static void GetProxyPreferenceSet(ProxyPreferenceSet* proxy_pref_set);
-
private:
- // Policies that map to a single preference are handled
- // by an automated converter. Each one of these policies
- // has an entry in |simple_policy_map_| with the following type.
- struct PolicyToPreferenceMapEntry {
- Value::ValueType value_type;
- ConfigurationPolicyType policy_type;
- const char* preference_path; // A DictionaryValue path, not a file path.
- };
-
- static const PolicyToPreferenceMapEntry kSimplePolicyMap[];
- static const PolicyToPreferenceMapEntry kProxyPolicyMap[];
- static const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[];
+ // Refreshes policy information, rereading policy from the provider and
+ // sending out change notifications as appropriate.
+ void Refresh();
+
static const ConfigurationPolicyProvider::PolicyDefinitionList
kPolicyDefinitionList;
+ // The policy provider from which policy settings are read.
ConfigurationPolicyProvider* provider_;
- scoped_ptr<DictionaryValue> prefs_;
-
- // Set to false until the first proxy-relevant policy is applied. At that
- // time, default values are provided for all proxy-relevant prefs
- // to override any values set from stores with a lower priority.
- bool lower_priority_proxy_settings_overridden_;
-
- // The following are used to track what proxy-relevant policy has been applied
- // accross calls to Apply to provide a warning if a policy specifies a
- // contradictory proxy configuration. |proxy_disabled_| is set to true if and
- // only if the kPolicyNoProxyServer has been applied,
- // |proxy_configuration_specified_| is set to true if and only if any other
- // proxy policy other than kPolicyNoProxyServer has been applied.
- bool proxy_disabled_;
- bool proxy_configuration_specified_;
-
- // Set to true if a the proxy mode policy has been set to force Chrome
- // to use the system proxy.
- bool use_system_proxy_;
-
- // Returns the map entry that corresponds to |policy| in the map.
- const PolicyToPreferenceMapEntry* FindPolicyInMap(
- ConfigurationPolicyType policy,
- const PolicyToPreferenceMapEntry* map,
- int size) const;
-
- // Remove the preferences found in the map from |prefs_|. Returns true if
- // any such preferences were found and removed.
- bool RemovePreferencesOfMap(const PolicyToPreferenceMapEntry* map,
- int table_size);
-
- bool ApplyPolicyFromMap(ConfigurationPolicyType policy,
- Value* value,
- const PolicyToPreferenceMapEntry* map,
- int size);
-
- // Processes proxy-specific policies. Returns true if the specified policy
- // is a proxy-related policy. ApplyProxyPolicy assumes the ownership
- // of |value| in the case that the policy is proxy-specific.
- bool ApplyProxyPolicy(ConfigurationPolicyType policy, Value* value);
-
- // Handles sync-related policies. Returns true if the policy was handled.
- // Assumes ownership of |value| in that case.
- bool ApplySyncPolicy(ConfigurationPolicyType policy, Value* value);
-
- // Handles policies that affect AutoFill. Returns true if the policy was
- // handled and assumes ownership of |value| in that case.
- bool ApplyAutoFillPolicy(ConfigurationPolicyType policy, Value* value);
-
- // Make sure that the |path| if present in |prefs_|. If not, set it to
- // a blank string.
- void EnsureStringPrefExists(const std::string& path);
-
- // If the required entries for default search are specified and valid,
- // finalizes the policy-specified configuration by initializing the
- // unspecified map entries. Otherwise wipes all default search related
- // map entries from |prefs_|.
- void FinalizeDefaultSearchPolicySettings();
+
+ // Initialization status as reported by the policy provider the last time we
+ // queried it.
+ bool initialization_complete_;
+
+ // Current policy preferences.
+ scoped_ptr<ConfigurationPolicyPrefKeeper> policy_keeper_;
+
+ ObserverList<PrefStore::Observer, true> observers_;
+
+ ConfigurationPolicyObserverRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyPrefStore);
};
diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
index af9f8e4..1896aaa 100644
--- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc
@@ -2,13 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <gtest/gtest.h>
-
#include "base/file_path.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
-#include "chrome/common/pref_names.h"
+#include "chrome/browser/prefs/proxy_prefs.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_store_observer_mock.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Mock;
namespace policy {
@@ -27,37 +33,38 @@ class TypeAndName {
const char* pref_name_;
};
+template<typename TESTBASE>
+class ConfigurationPolicyPrefStoreTestBase : public TESTBASE {
+ protected:
+ ConfigurationPolicyPrefStoreTestBase()
+ : provider_(),
+ store_(&provider_) {}
+
+ MockConfigurationPolicyProvider provider_;
+ ConfigurationPolicyPrefStore store_;
+};
+
// Test cases for list-valued policy settings.
class ConfigurationPolicyPrefStoreListTest
- : public testing::TestWithParam<TypeAndName> {
+ : public ConfigurationPolicyPrefStoreTestBase<
+ testing::TestWithParam<TypeAndName> > {
};
TEST_P(ConfigurationPolicyPrefStoreListTest, GetDefault) {
- ConfigurationPolicyPrefStore store(NULL);
- ListValue* list = NULL;
- EXPECT_FALSE(store.prefs()->GetList(GetParam().pref_name(), &list));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(GetParam().pref_name(), NULL));
}
TEST_P(ConfigurationPolicyPrefStoreListTest, SetValue) {
- ConfigurationPolicyPrefStore store(NULL);
ListValue* in_value = new ListValue();
in_value->Append(Value::CreateStringValue("test1"));
in_value->Append(Value::CreateStringValue("test2,"));
- store.Apply(GetParam().type(), in_value);
- ListValue* list = NULL;
- EXPECT_TRUE(store.prefs()->GetList(GetParam().pref_name(), &list));
- ListValue::const_iterator current(list->begin());
- const ListValue::const_iterator end(list->end());
- ASSERT_TRUE(current != end);
- std::string value;
- (*current)->GetAsString(&value);
- EXPECT_EQ("test1", value);
- ++current;
- ASSERT_TRUE(current != end);
- (*current)->GetAsString(&value);
- EXPECT_EQ("test2,", value);
- ++current;
- EXPECT_TRUE(current == end);
+ provider_.AddPolicy(GetParam().type(), in_value);
+ store_.OnUpdatePolicy();
+ Value* value;
+ EXPECT_EQ(PrefStore::READ_OK,
+ store_.GetValue(GetParam().pref_name(), &value));
+ EXPECT_TRUE(in_value->Equals(value));
}
INSTANTIATE_TEST_CASE_P(
@@ -75,22 +82,23 @@ INSTANTIATE_TEST_CASE_P(
// Test cases for string-valued policy settings.
class ConfigurationPolicyPrefStoreStringTest
- : public testing::TestWithParam<TypeAndName> {
+ : public ConfigurationPolicyPrefStoreTestBase<
+ testing::TestWithParam<TypeAndName> > {
};
TEST_P(ConfigurationPolicyPrefStoreStringTest, GetDefault) {
- ConfigurationPolicyPrefStore store(NULL);
- std::string result;
- EXPECT_FALSE(store.prefs()->GetString(GetParam().pref_name(), &result));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(GetParam().pref_name(), NULL));
}
TEST_P(ConfigurationPolicyPrefStoreStringTest, SetValue) {
- ConfigurationPolicyPrefStore store(NULL);
- store.Apply(GetParam().type(),
- Value::CreateStringValue("http://chromium.org"));
- std::string result;
- EXPECT_TRUE(store.prefs()->GetString(GetParam().pref_name(), &result));
- EXPECT_EQ(result, "http://chromium.org");
+ provider_.AddPolicy(GetParam().type(),
+ Value::CreateStringValue("http://chromium.org"));
+ store_.OnUpdatePolicy();
+ Value* value;
+ EXPECT_EQ(PrefStore::READ_OK,
+ store_.GetValue(GetParam().pref_name(), &value));
+ EXPECT_TRUE(StringValue("http://chromium.org").Equals(value));
}
INSTANTIATE_TEST_CASE_P(
@@ -99,12 +107,6 @@ INSTANTIATE_TEST_CASE_P(
testing::Values(
TypeAndName(kPolicyHomePage,
prefs::kHomePage),
- TypeAndName(kPolicyProxyServer,
- prefs::kProxyServer),
- TypeAndName(kPolicyProxyPacUrl,
- prefs::kProxyPacUrl),
- TypeAndName(kPolicyProxyBypassList,
- prefs::kProxyBypassList),
TypeAndName(kPolicyApplicationLocale,
prefs::kApplicationLocale),
TypeAndName(kPolicyApplicationLocale,
@@ -120,26 +122,30 @@ INSTANTIATE_TEST_CASE_P(
// Test cases for boolean-valued policy settings.
class ConfigurationPolicyPrefStoreBooleanTest
- : public testing::TestWithParam<TypeAndName> {
+ : public ConfigurationPolicyPrefStoreTestBase<
+ testing::TestWithParam<TypeAndName> > {
};
TEST_P(ConfigurationPolicyPrefStoreBooleanTest, GetDefault) {
- ConfigurationPolicyPrefStore store(NULL);
- bool result = false;
- EXPECT_FALSE(store.prefs()->GetBoolean(GetParam().pref_name(), &result));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(GetParam().pref_name(), NULL));
}
TEST_P(ConfigurationPolicyPrefStoreBooleanTest, SetValue) {
- ConfigurationPolicyPrefStore store(NULL);
- store.Apply(GetParam().type(), Value::CreateBooleanValue(false));
+ provider_.AddPolicy(GetParam().type(), Value::CreateBooleanValue(false));
+ store_.OnUpdatePolicy();
+ Value* value;
bool result = true;
- EXPECT_TRUE(store.prefs()->GetBoolean(GetParam().pref_name(), &result));
- EXPECT_FALSE(result);
+ EXPECT_EQ(PrefStore::READ_OK,
+ store_.GetValue(GetParam().pref_name(), &value));
+ EXPECT_TRUE(FundamentalValue(false).Equals(value));
- store.Apply(GetParam().type(), Value::CreateBooleanValue(true));
+ provider_.AddPolicy(GetParam().type(), Value::CreateBooleanValue(true));
+ store_.OnUpdatePolicy();
result = false;
- EXPECT_TRUE(store.prefs()->GetBoolean(GetParam().pref_name(), &result));
- EXPECT_TRUE(result);
+ EXPECT_EQ(PrefStore::READ_OK,
+ store_.GetValue(GetParam().pref_name(), &value));
+ EXPECT_TRUE(FundamentalValue(true).Equals(value));
}
INSTANTIATE_TEST_CASE_P(
@@ -192,21 +198,22 @@ INSTANTIATE_TEST_CASE_P(
// Test cases for integer-valued policy settings.
class ConfigurationPolicyPrefStoreIntegerTest
- : public testing::TestWithParam<TypeAndName> {
+ : public ConfigurationPolicyPrefStoreTestBase<
+ testing::TestWithParam<TypeAndName> > {
};
TEST_P(ConfigurationPolicyPrefStoreIntegerTest, GetDefault) {
- ConfigurationPolicyPrefStore store(NULL);
- int result = 0;
- EXPECT_FALSE(store.prefs()->GetInteger(GetParam().pref_name(), &result));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(GetParam().pref_name(), NULL));
}
TEST_P(ConfigurationPolicyPrefStoreIntegerTest, SetValue) {
- ConfigurationPolicyPrefStore store(NULL);
- store.Apply(GetParam().type(), Value::CreateIntegerValue(2));
- int result = 0;
- EXPECT_TRUE(store.prefs()->GetInteger(GetParam().pref_name(), &result));
- EXPECT_EQ(result, 2);
+ provider_.AddPolicy(GetParam().type(), Value::CreateIntegerValue(2));
+ store_.OnUpdatePolicy();
+ Value* value = NULL;
+ EXPECT_EQ(PrefStore::READ_OK,
+ store_.GetValue(GetParam().pref_name(), &value));
+ EXPECT_TRUE(FundamentalValue(2).Equals(value));
}
INSTANTIATE_TEST_CASE_P(
@@ -218,153 +225,133 @@ INSTANTIATE_TEST_CASE_P(
// Test cases for the proxy policy settings.
class ConfigurationPolicyPrefStoreProxyTest : public testing::Test {
+ protected:
+ // Verify that all the proxy prefs are set to the specified expected values.
+ static void VerifyProxyPrefs(
+ const ConfigurationPolicyPrefStore& store,
+ const std::string& expected_proxy_server,
+ const std::string& expected_proxy_pac_url,
+ const std::string& expected_proxy_bypass_list,
+ const ProxyPrefs::ProxyMode& expected_proxy_mode) {
+ Value* value = NULL;
+
+ if (expected_proxy_server.empty()) {
+ EXPECT_EQ(PrefStore::READ_USE_DEFAULT,
+ store.GetValue(prefs::kProxyServer, NULL));
+ } else {
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kProxyServer, &value));
+ EXPECT_TRUE(StringValue(expected_proxy_server).Equals(value));
+ }
+ if (expected_proxy_pac_url.empty()) {
+ EXPECT_EQ(PrefStore::READ_USE_DEFAULT,
+ store.GetValue(prefs::kProxyPacUrl, NULL));
+ } else {
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kProxyPacUrl, &value));
+ EXPECT_TRUE(StringValue(expected_proxy_pac_url).Equals(value));
+ }
+ if (expected_proxy_bypass_list.empty()) {
+ EXPECT_EQ(PrefStore::READ_USE_DEFAULT,
+ store.GetValue(prefs::kProxyBypassList, NULL));
+ } else {
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kProxyBypassList, &value));
+ EXPECT_TRUE(StringValue(expected_proxy_bypass_list).Equals(value));
+ }
+ EXPECT_EQ(PrefStore::READ_OK, store.GetValue(prefs::kProxyMode, &value));
+ EXPECT_TRUE(FundamentalValue(expected_proxy_mode).Equals(value));
+ }
};
TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptions) {
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(kPolicyProxyBypassList,
- Value::CreateStringValue("http://chromium.org/override"));
- provider->AddPolicy(kPolicyProxyPacUrl,
- Value::CreateStringValue("http://short.org/proxy.pac"));
- provider->AddPolicy(kPolicyProxyServer,
- Value::CreateStringValue("chromium.org"));
- provider->AddPolicy(kPolicyProxyServerMode,
- Value::CreateIntegerValue(
- kPolicyManuallyConfiguredProxyMode));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
-
- std::string string_result;
- EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyBypassList,
- &string_result));
- EXPECT_EQ("http://chromium.org/override", string_result);
- EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result));
- EXPECT_EQ("http://short.org/proxy.pac", string_result);
- EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyServer, &string_result));
- EXPECT_EQ("chromium.org", string_result);
- bool bool_result;
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result));
- EXPECT_FALSE(bool_result);
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result));
- EXPECT_FALSE(bool_result);
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyProxyBypassList,
+ Value::CreateStringValue("http://chromium.org/override"));
+ provider.AddPolicy(kPolicyProxyServer,
+ Value::CreateStringValue("chromium.org"));
+ provider.AddPolicy(kPolicyProxyMode,
+ Value::CreateIntegerValue(
+ kPolicyManuallyConfiguredProxyMode));
+
+ ConfigurationPolicyPrefStore store(&provider);
+ VerifyProxyPrefs(
+ store, "chromium.org", "", "http://chromium.org/override",
+ ProxyPrefs::MODE_FIXED_SERVERS);
}
-TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxy) {
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(kPolicyProxyBypassList,
- Value::CreateStringValue("http://chromium.org/override"));
- provider->AddPolicy(kPolicyProxyServerMode,
- Value::CreateIntegerValue(
- kPolicyNoProxyServerMode));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
-
- std::string string_result;
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList,
- &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result));
- bool bool_result;
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result));
- EXPECT_TRUE(bool_result);
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result));
- EXPECT_FALSE(bool_result);
+TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptionsReversedApplyOrder) {
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyProxyMode,
+ Value::CreateIntegerValue(
+ kPolicyManuallyConfiguredProxyMode));
+ provider.AddPolicy(kPolicyProxyBypassList,
+ Value::CreateStringValue("http://chromium.org/override"));
+ provider.AddPolicy(kPolicyProxyServer,
+ Value::CreateStringValue("chromium.org"));
+
+ ConfigurationPolicyPrefStore store(&provider);
+ VerifyProxyPrefs(
+ store, "chromium.org", "", "http://chromium.org/override",
+ ProxyPrefs::MODE_FIXED_SERVERS);
}
-TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxyReversedApplyOrder) {
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(kPolicyProxyServerMode,
- Value::CreateIntegerValue(
- kPolicyNoProxyServerMode));
- provider->AddPolicy(kPolicyProxyBypassList,
- Value::CreateStringValue("http://chromium.org/override"));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
-
- std::string string_result;
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList,
- &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result));
- bool bool_result;
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result));
- EXPECT_TRUE(bool_result);
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result));
- EXPECT_FALSE(bool_result);
+TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxy) {
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyProxyMode,
+ Value::CreateIntegerValue(kPolicyNoProxyServerMode));
+
+ ConfigurationPolicyPrefStore store(&provider);
+ VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_DIRECT);
}
TEST_F(ConfigurationPolicyPrefStoreProxyTest, AutoDetect) {
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(kPolicyProxyServerMode,
- Value::CreateIntegerValue(
- kPolicyAutoDetectProxyMode));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
-
- std::string string_result;
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList,
- &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result));
- bool bool_result;
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result));
- EXPECT_FALSE(bool_result);
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result));
- EXPECT_TRUE(bool_result);
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyProxyMode,
+ Value::CreateIntegerValue(kPolicyAutoDetectProxyMode));
+
+ ConfigurationPolicyPrefStore store(&provider);
+ VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_AUTO_DETECT);
+}
+
+TEST_F(ConfigurationPolicyPrefStoreProxyTest, AutoDetectPac) {
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyProxyPacUrl,
+ Value::CreateStringValue("http://short.org/proxy.pac"));
+ provider.AddPolicy(kPolicyProxyMode,
+ Value::CreateIntegerValue(kPolicyAutoDetectProxyMode));
+
+ ConfigurationPolicyPrefStore store(&provider);
+ VerifyProxyPrefs(
+ store, "", "http://short.org/proxy.pac", "", ProxyPrefs::MODE_PAC_SCRIPT);
}
TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystem) {
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(kPolicyProxyBypassList,
- Value::CreateStringValue("http://chromium.org/override"));
- provider->AddPolicy(kPolicyProxyServerMode,
- Value::CreateIntegerValue(
- kPolicyUseSystemProxyMode));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
-
- std::string string_result;
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList,
- &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result));
- bool bool_result;
- EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result));
- EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect,
- &bool_result));
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyProxyMode,
+ Value::CreateIntegerValue(kPolicyUseSystemProxyMode));
+
+ ConfigurationPolicyPrefStore store(&provider);
+ VerifyProxyPrefs(store, "", "", "", ProxyPrefs::MODE_SYSTEM);
}
-TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystemReversedApplyOrder) {
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(kPolicyProxyServerMode,
- Value::CreateIntegerValue(
- kPolicyUseSystemProxyMode));
- provider->AddPolicy(kPolicyProxyBypassList,
- Value::CreateStringValue("http://chromium.org/override"));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
-
- std::string string_result;
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList,
- &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyPacUrl, &string_result));
- EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyServer, &string_result));
- bool bool_result;
- EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &bool_result));
- EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect,
- &bool_result));
+TEST_F(ConfigurationPolicyPrefStoreProxyTest, ProxyInvalid) {
+ for (int i = 0; i < MODE_COUNT; ++i) {
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyProxyMode, Value::CreateIntegerValue(i));
+ // No mode expects all three parameters being set.
+ provider.AddPolicy(kPolicyProxyPacUrl,
+ Value::CreateStringValue("http://short.org/proxy.pac"));
+ provider.AddPolicy(kPolicyProxyBypassList,
+ Value::CreateStringValue(
+ "http://chromium.org/override"));
+ provider.AddPolicy(kPolicyProxyServer,
+ Value::CreateStringValue("chromium.org"));
+
+ ConfigurationPolicyPrefStore store(&provider);
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kProxyMode, NULL));
+ }
}
class ConfigurationPolicyPrefStoreDefaultSearchTest : public testing::Test {
@@ -374,44 +361,38 @@ class ConfigurationPolicyPrefStoreDefaultSearchTest : public testing::Test {
// search URL, that all the elements have been given proper defaults.
TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, MinimallyDefined) {
const char* const search_url = "http://test.com/search?t={searchTerms}";
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(
- kPolicyDefaultSearchProviderEnabled,
- Value::CreateBooleanValue(true));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderSearchURL,
- Value::CreateStringValue(search_url));
-
- ConfigurationPolicyPrefStore store(provider.get());
-
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
- const DictionaryValue* prefs = store.prefs();
-
- std::string string_result;
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderSearchURL,
- &string_result));
- EXPECT_EQ(string_result, search_url);
-
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderName,
- &string_result));
- EXPECT_EQ(string_result, "test.com");
-
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderKeyword,
- &string_result));
- EXPECT_EQ(string_result, std::string());
-
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderSuggestURL,
- &string_result));
- EXPECT_EQ(string_result, std::string());
-
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderIconURL,
- &string_result));
- EXPECT_EQ(string_result, std::string());
-
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderEncodings,
- &string_result));
- EXPECT_EQ(string_result, std::string());
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyDefaultSearchProviderEnabled,
+ Value::CreateBooleanValue(true));
+ provider.AddPolicy(kPolicyDefaultSearchProviderSearchURL,
+ Value::CreateStringValue(search_url));
+
+ ConfigurationPolicyPrefStore store(&provider);
+
+ Value* value = NULL;
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderSearchURL, &value));
+ EXPECT_TRUE(StringValue(search_url).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderName, &value));
+ EXPECT_TRUE(StringValue("test.com").Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderKeyword, &value));
+ EXPECT_TRUE(StringValue(std::string()).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderSuggestURL, &value));
+ EXPECT_TRUE(StringValue(std::string()).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderIconURL, &value));
+ EXPECT_TRUE(StringValue(std::string()).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderEncodings, &value));
+ EXPECT_TRUE(StringValue(std::string()).Equals(value));
}
// Checks that for a fully defined search policy, all elements have been
@@ -423,63 +404,48 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, FullyDefined) {
const char* const name = "MyName";
const char* const keyword = "MyKeyword";
const char* const encodings = "UTF-16;UTF-8";
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(
- kPolicyDefaultSearchProviderEnabled,
- Value::CreateBooleanValue(true));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderSearchURL,
- Value::CreateStringValue(search_url));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderName,
- Value::CreateStringValue(name));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderKeyword,
- Value::CreateStringValue(keyword));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderSuggestURL,
- Value::CreateStringValue(suggest_url));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderIconURL,
- Value::CreateStringValue(icon_url));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderEncodings,
- Value::CreateStringValue(encodings));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
- const DictionaryValue* prefs = store.prefs();
-
- std::string result_search_url;
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderSearchURL,
- &result_search_url));
- EXPECT_EQ(result_search_url, search_url);
-
- std::string result_name;
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderName,
- &result_name));
- EXPECT_EQ(result_name, name);
-
- std::string result_keyword;
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderKeyword,
- &result_keyword));
- EXPECT_EQ(result_keyword, keyword);
-
- std::string result_suggest_url;
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderSuggestURL,
- &result_suggest_url));
- EXPECT_EQ(result_suggest_url, suggest_url);
-
- std::string result_icon_url;
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderIconURL,
- &result_icon_url));
- EXPECT_EQ(result_icon_url, icon_url);
-
- std::string result_encodings;
- EXPECT_TRUE(prefs->GetString(prefs::kDefaultSearchProviderEncodings,
- &result_encodings));
- EXPECT_EQ(result_encodings, encodings);
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyDefaultSearchProviderEnabled,
+ Value::CreateBooleanValue(true));
+ provider.AddPolicy(kPolicyDefaultSearchProviderSearchURL,
+ Value::CreateStringValue(search_url));
+ provider.AddPolicy(kPolicyDefaultSearchProviderName,
+ Value::CreateStringValue(name));
+ provider.AddPolicy(kPolicyDefaultSearchProviderKeyword,
+ Value::CreateStringValue(keyword));
+ provider.AddPolicy(kPolicyDefaultSearchProviderSuggestURL,
+ Value::CreateStringValue(suggest_url));
+ provider.AddPolicy(kPolicyDefaultSearchProviderIconURL,
+ Value::CreateStringValue(icon_url));
+ provider.AddPolicy(kPolicyDefaultSearchProviderEncodings,
+ Value::CreateStringValue(encodings));
+
+ ConfigurationPolicyPrefStore store(&provider);
+
+ Value* value = NULL;
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderSearchURL, &value));
+ EXPECT_TRUE(StringValue(search_url).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderName, &value));
+ EXPECT_TRUE(StringValue(name).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderKeyword, &value));
+ EXPECT_TRUE(StringValue(keyword).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderSuggestURL, &value));
+ EXPECT_TRUE(StringValue(suggest_url).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderIconURL, &value));
+ EXPECT_TRUE(StringValue(icon_url).Equals(value));
+
+ EXPECT_EQ(PrefStore::READ_OK,
+ store.GetValue(prefs::kDefaultSearchProviderEncodings, &value));
+ EXPECT_TRUE(StringValue(encodings).Equals(value));
}
// Checks that if the default search policy is missing, that no elements of the
@@ -490,44 +456,34 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, MissingUrl) {
const char* const name = "MyName";
const char* const keyword = "MyKeyword";
const char* const encodings = "UTF-16;UTF-8";
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(
- kPolicyDefaultSearchProviderEnabled,
- Value::CreateBooleanValue(true));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderName,
- Value::CreateStringValue(name));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderKeyword,
- Value::CreateStringValue(keyword));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderSuggestURL,
- Value::CreateStringValue(suggest_url));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderIconURL,
- Value::CreateStringValue(icon_url));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderEncodings,
- Value::CreateStringValue(encodings));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
- const DictionaryValue* prefs = store.prefs();
-
- std::string string_result;
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderSearchURL,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderName,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderKeyword,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderSuggestURL,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderIconURL,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderEncodings,
- &string_result));
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyDefaultSearchProviderEnabled,
+ Value::CreateBooleanValue(true));
+ provider.AddPolicy(kPolicyDefaultSearchProviderName,
+ Value::CreateStringValue(name));
+ provider.AddPolicy(kPolicyDefaultSearchProviderKeyword,
+ Value::CreateStringValue(keyword));
+ provider.AddPolicy(kPolicyDefaultSearchProviderSuggestURL,
+ Value::CreateStringValue(suggest_url));
+ provider.AddPolicy(kPolicyDefaultSearchProviderIconURL,
+ Value::CreateStringValue(icon_url));
+ provider.AddPolicy(kPolicyDefaultSearchProviderEncodings,
+ Value::CreateStringValue(encodings));
+
+ ConfigurationPolicyPrefStore store(&provider);
+
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderSearchURL, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderName, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderKeyword, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderSuggestURL, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderIconURL, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderEncodings, NULL));
}
// Checks that if the default search policy is invalid, that no elements of the
@@ -539,103 +495,146 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, Invalid) {
const char* const name = "MyName";
const char* const keyword = "MyKeyword";
const char* const encodings = "UTF-16;UTF-8";
- scoped_ptr<MockConfigurationPolicyProvider> provider(
- new MockConfigurationPolicyProvider());
- provider->AddPolicy(
- kPolicyDefaultSearchProviderEnabled,
- Value::CreateBooleanValue(true));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderSearchURL,
- Value::CreateStringValue(bad_search_url));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderName,
- Value::CreateStringValue(name));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderKeyword,
- Value::CreateStringValue(keyword));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderSuggestURL,
- Value::CreateStringValue(suggest_url));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderIconURL,
- Value::CreateStringValue(icon_url));
- provider->AddPolicy(
- kPolicyDefaultSearchProviderEncodings,
- Value::CreateStringValue(encodings));
-
- ConfigurationPolicyPrefStore store(provider.get());
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
- const DictionaryValue* const prefs = store.prefs();
-
- std::string string_result;
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderEnabled,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderSearchURL,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderName,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderKeyword,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderSuggestURL,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderIconURL,
- &string_result));
- EXPECT_FALSE(prefs->GetString(prefs::kDefaultSearchProviderEncodings,
- &string_result));
+ MockConfigurationPolicyProvider provider;
+ provider.AddPolicy(kPolicyDefaultSearchProviderEnabled,
+ Value::CreateBooleanValue(true));
+ provider.AddPolicy(kPolicyDefaultSearchProviderSearchURL,
+ Value::CreateStringValue(bad_search_url));
+ provider.AddPolicy(kPolicyDefaultSearchProviderName,
+ Value::CreateStringValue(name));
+ provider.AddPolicy(kPolicyDefaultSearchProviderKeyword,
+ Value::CreateStringValue(keyword));
+ provider.AddPolicy(kPolicyDefaultSearchProviderSuggestURL,
+ Value::CreateStringValue(suggest_url));
+ provider.AddPolicy(kPolicyDefaultSearchProviderIconURL,
+ Value::CreateStringValue(icon_url));
+ provider.AddPolicy(kPolicyDefaultSearchProviderEncodings,
+ Value::CreateStringValue(encodings));
+
+ ConfigurationPolicyPrefStore store(&provider);
+
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderSearchURL, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderName, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderKeyword, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderSuggestURL, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderIconURL, NULL));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store.GetValue(prefs::kDefaultSearchProviderEncodings, NULL));
}
// Test cases for the Sync policy setting.
-class ConfigurationPolicyPrefStoreSyncTest : public testing::Test {
+class ConfigurationPolicyPrefStoreSyncTest
+ : public ConfigurationPolicyPrefStoreTestBase<testing::Test> {
};
TEST_F(ConfigurationPolicyPrefStoreSyncTest, Default) {
- ConfigurationPolicyPrefStore store(NULL);
- bool result = false;
- EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kSyncManaged, &result));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(prefs::kSyncManaged, NULL));
}
TEST_F(ConfigurationPolicyPrefStoreSyncTest, Enabled) {
- ConfigurationPolicyPrefStore store(NULL);
- store.Apply(kPolicySyncDisabled, Value::CreateBooleanValue(false));
+ provider_.AddPolicy(kPolicySyncDisabled, Value::CreateBooleanValue(false));
+ store_.OnUpdatePolicy();
// Enabling Sync should not set the pref.
- bool result = false;
- EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kSyncManaged, &result));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(prefs::kSyncManaged, NULL));
}
TEST_F(ConfigurationPolicyPrefStoreSyncTest, Disabled) {
- ConfigurationPolicyPrefStore store(NULL);
- store.Apply(kPolicySyncDisabled, Value::CreateBooleanValue(true));
+ provider_.AddPolicy(kPolicySyncDisabled, Value::CreateBooleanValue(true));
+ store_.OnUpdatePolicy();
// Sync should be flagged as managed.
- bool result = false;
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kSyncManaged, &result));
- EXPECT_TRUE(result);
+ Value* value = NULL;
+ EXPECT_EQ(PrefStore::READ_OK, store_.GetValue(prefs::kSyncManaged, &value));
+ ASSERT_TRUE(value != NULL);
+ EXPECT_TRUE(FundamentalValue(true).Equals(value));
}
// Test cases for the AutoFill policy setting.
-class ConfigurationPolicyPrefStoreAutoFillTest : public testing::Test {
+class ConfigurationPolicyPrefStoreAutoFillTest
+ : public ConfigurationPolicyPrefStoreTestBase<testing::Test> {
};
TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Default) {
- ConfigurationPolicyPrefStore store(NULL);
- bool result = false;
- EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(prefs::kSyncManaged, NULL));
}
TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Enabled) {
- ConfigurationPolicyPrefStore store(NULL);
- store.Apply(kPolicyAutoFillEnabled, Value::CreateBooleanValue(true));
+ provider_.AddPolicy(kPolicyAutoFillEnabled, Value::CreateBooleanValue(true));
+ store_.OnUpdatePolicy();
// Enabling AutoFill should not set the pref.
- bool result = false;
- EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result));
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(prefs::kSyncManaged, NULL));
}
TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Disabled) {
- ConfigurationPolicyPrefStore store(NULL);
- store.Apply(kPolicyAutoFillEnabled, Value::CreateBooleanValue(false));
+ provider_.AddPolicy(kPolicyAutoFillEnabled, Value::CreateBooleanValue(false));
+ store_.OnUpdatePolicy();
// Disabling AutoFill should switch the pref to managed.
- bool result = true;
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result));
- EXPECT_FALSE(result);
+ Value* value = NULL;
+ EXPECT_EQ(PrefStore::READ_OK,
+ store_.GetValue(prefs::kAutoFillEnabled, &value));
+ EXPECT_TRUE(FundamentalValue(false).Equals(value));
+}
+
+// Exercises the policy refresh mechanism.
+class ConfigurationPolicyPrefStoreRefreshTest
+ : public ConfigurationPolicyPrefStoreTestBase<testing::Test> {
+ protected:
+ virtual void SetUp() {
+ store_.AddObserver(&observer_);
+ }
+
+ virtual void TearDown() {
+ store_.RemoveObserver(&observer_);
+ }
+
+ PrefStoreObserverMock observer_;
+};
+
+TEST_F(ConfigurationPolicyPrefStoreRefreshTest, Refresh) {
+ Value* value = NULL;
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(prefs::kHomePage, NULL));
+
+ EXPECT_CALL(observer_, OnPrefValueChanged(prefs::kHomePage)).Times(1);
+ provider_.AddPolicy(kPolicyHomePage,
+ Value::CreateStringValue("http://www.chromium.org"));
+ store_.OnUpdatePolicy();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_EQ(PrefStore::READ_OK,
+ store_.GetValue(prefs::kHomePage, &value));
+ EXPECT_TRUE(StringValue("http://www.chromium.org").Equals(value));
+
+ EXPECT_CALL(observer_, OnPrefValueChanged(_)).Times(0);
+ store_.OnUpdatePolicy();
+ Mock::VerifyAndClearExpectations(&observer_);
+
+ EXPECT_CALL(observer_, OnPrefValueChanged(prefs::kHomePage)).Times(1);
+ provider_.RemovePolicy(kPolicyHomePage);
+ store_.OnUpdatePolicy();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_EQ(PrefStore::READ_NO_VALUE,
+ store_.GetValue(prefs::kHomePage, NULL));
+}
+
+TEST_F(ConfigurationPolicyPrefStoreRefreshTest, Initialization) {
+ EXPECT_FALSE(store_.IsInitializationComplete());
+
+ EXPECT_CALL(observer_, OnInitializationCompleted()).Times(1);
+
+ provider_.SetInitializationComplete(true);
+ EXPECT_FALSE(store_.IsInitializationComplete());
+
+ store_.OnUpdatePolicy();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_TRUE(store_.IsInitializationComplete());
}
} // namespace policy
diff --git a/chrome/browser/policy/configuration_policy_provider.cc b/chrome/browser/policy/configuration_policy_provider.cc
index ce7106f..2aee046 100644
--- a/chrome/browser/policy/configuration_policy_provider.cc
+++ b/chrome/browser/policy/configuration_policy_provider.cc
@@ -4,11 +4,45 @@
#include "chrome/browser/policy/configuration_policy_provider.h"
+#include <algorithm>
+
#include "base/values.h"
-#include "chrome/common/notification_service.h"
namespace policy {
+ConfigurationPolicyObserverRegistrar::ConfigurationPolicyObserverRegistrar() {}
+
+ConfigurationPolicyObserverRegistrar::~ConfigurationPolicyObserverRegistrar() {
+ RemoveAll();
+}
+
+void ConfigurationPolicyObserverRegistrar::Init(
+ ConfigurationPolicyProvider* provider) {
+ provider_ = provider;
+}
+
+void ConfigurationPolicyObserverRegistrar::AddObserver(
+ ConfigurationPolicyProvider::Observer* observer) {
+ observers_.push_back(observer);
+ provider_->AddObserver(observer);
+}
+
+void ConfigurationPolicyObserverRegistrar::RemoveObserver(
+ ConfigurationPolicyProvider::Observer* observer) {
+ std::remove(observers_.begin(), observers_.end(), observer);
+ provider_->RemoveObserver(observer);
+}
+
+void ConfigurationPolicyObserverRegistrar::RemoveAll() {
+ for (std::vector<ConfigurationPolicyProvider::Observer*>::iterator it =
+ observers_.begin(); it != observers_.end(); ++it) {
+ provider_->RemoveObserver(*it);
+ }
+ observers_.clear();
+}
+
+// Class ConfigurationPolicyProvider.
+
ConfigurationPolicyProvider::ConfigurationPolicyProvider(
const PolicyDefinitionList* policy_list)
: policy_definition_list_(policy_list) {
@@ -16,15 +50,8 @@ ConfigurationPolicyProvider::ConfigurationPolicyProvider(
ConfigurationPolicyProvider::~ConfigurationPolicyProvider() {}
-void ConfigurationPolicyProvider::NotifyStoreOfPolicyChange() {
- NotificationService::current()->Notify(
- NotificationType::POLICY_CHANGED,
- Source<ConfigurationPolicyProvider>(this),
- NotificationService::NoDetails());
-}
-
void ConfigurationPolicyProvider::DecodePolicyValueTree(
- DictionaryValue* policies,
+ const DictionaryValue* policies,
ConfigurationPolicyStoreInterface* store) {
const PolicyDefinitionList* policy_list(policy_definition_list());
for (const PolicyDefinitionList::Entry* i = policy_list->begin;
diff --git a/chrome/browser/policy/configuration_policy_provider.h b/chrome/browser/policy/configuration_policy_provider.h
index e3989b9..5639235 100644
--- a/chrome/browser/policy/configuration_policy_provider.h
+++ b/chrome/browser/policy/configuration_policy_provider.h
@@ -21,6 +21,12 @@ namespace policy {
// etc.) should implement a subclass of this class.
class ConfigurationPolicyProvider {
public:
+ class Observer {
+ public:
+ virtual ~Observer() {}
+ virtual void OnUpdatePolicy() = 0;
+ };
+
// Used for static arrays of policy values that is used to initialize an
// instance of the ConfigurationPolicyProvider.
struct PolicyDefinitionList {
@@ -38,29 +44,35 @@ class ConfigurationPolicyProvider {
virtual ~ConfigurationPolicyProvider();
- // Must be implemented by provider subclasses to specify the
- // provider-specific policy decisions. The preference service
- // invokes this |Provide| method when it needs a policy
- // provider to specify its policy choices. In |Provide|,
- // the |ConfigurationPolicyProvider| must make calls to the
- // |Apply| method of |store| to apply specific policies.
- // Returns true if the policy could be provided, otherwise false.
+ // Must be implemented by provider subclasses to specify the provider-specific
+ // policy decisions. The preference service invokes this |Provide| method when
+ // it needs a policy provider to specify its policy choices. In |Provide|, the
+ // |ConfigurationPolicyProvider| must make calls to the |Apply| method of
+ // |store| to apply specific policies. Returns true if the policy could be
+ // provided, otherwise false.
virtual bool Provide(ConfigurationPolicyStoreInterface* store) = 0;
- // Called by the subclass provider at any time to indicate that the currently
- // applied policy is not longer current. A policy refresh will be initiated as
- // soon as possible.
- virtual void NotifyStoreOfPolicyChange();
+ // Check whether this provider has completed initialization. This is used to
+ // detect whether initialization is done in case providers implementations
+ // need to do asynchronous operations for initialization.
+ virtual bool IsInitializationComplete() const { return true; }
+ protected:
// Decodes the value tree and writes the configuration to the given |store|.
- void DecodePolicyValueTree(DictionaryValue* policies,
+ void DecodePolicyValueTree(const DictionaryValue* policies,
ConfigurationPolicyStoreInterface* store);
- protected:
+
const PolicyDefinitionList* policy_definition_list() const {
return policy_definition_list_;
}
private:
+ friend class ConfigurationPolicyObserverRegistrar;
+
+ virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) = 0;
+ virtual void RemoveObserver(
+ ConfigurationPolicyProvider::Observer* observer) = 0;
+
// Contains the default mapping from policy values to the actual names.
const ConfigurationPolicyProvider::PolicyDefinitionList*
policy_definition_list_;
@@ -69,6 +81,22 @@ class ConfigurationPolicyProvider {
DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProvider);
};
+// Manages observers for a ConfigurationPolicyProvider. Is used to register
+// observers, and automatically removes them upon destruction.
+class ConfigurationPolicyObserverRegistrar {
+ public:
+ ConfigurationPolicyObserverRegistrar();
+ ~ConfigurationPolicyObserverRegistrar();
+ void Init(ConfigurationPolicyProvider* provider);
+ void AddObserver(ConfigurationPolicyProvider::Observer* observer);
+ void RemoveObserver(ConfigurationPolicyProvider::Observer* observer);
+ void RemoveAll();
+ private:
+ ConfigurationPolicyProvider* provider_;
+ std::vector<ConfigurationPolicyProvider::Observer*> observers_;
+ DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyObserverRegistrar);
+};
+
} // namespace policy
#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_H_
diff --git a/chrome/browser/policy/configuration_policy_provider_delegate_win.cc b/chrome/browser/policy/configuration_policy_provider_delegate_win.cc
new file mode 100644
index 0000000..68947de
--- /dev/null
+++ b/chrome/browser/policy/configuration_policy_provider_delegate_win.cc
@@ -0,0 +1,160 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/configuration_policy_provider_delegate_win.h"
+
+#include "base/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
+#include "base/win/registry.h"
+#include "chrome/common/policy_constants.h"
+
+using base::win::RegKey;
+
+namespace {
+
+bool ReadRegistryStringValue(RegKey* key, const string16& name,
+ string16* result) {
+ DWORD value_size = 0;
+ DWORD key_type = 0;
+ scoped_array<uint8> buffer;
+
+ if (!key->ReadValue(name.c_str(), 0, &value_size, &key_type))
+ return false;
+ if (key_type != REG_SZ)
+ return false;
+
+ // According to the Microsoft documentation, the string
+ // buffer may not be explicitly 0-terminated. Allocate a
+ // slightly larger buffer and pre-fill to zeros to guarantee
+ // the 0-termination.
+ buffer.reset(new uint8[value_size + 2]);
+ memset(buffer.get(), 0, value_size + 2);
+ key->ReadValue(name.c_str(), buffer.get(), &value_size, NULL);
+ result->assign(reinterpret_cast<const wchar_t*>(buffer.get()));
+ return true;
+}
+
+} // namespace
+
+namespace policy {
+
+ConfigurationPolicyProviderDelegateWin::ConfigurationPolicyProviderDelegateWin(
+ const ConfigurationPolicyProvider::PolicyDefinitionList*
+ policy_definition_list)
+ : policy_definition_list_(policy_definition_list) {
+}
+
+DictionaryValue* ConfigurationPolicyProviderDelegateWin::Load() {
+ DictionaryValue* result = new DictionaryValue();
+ const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current;
+ for (current = policy_definition_list_->begin;
+ current != policy_definition_list_->end;
+ ++current) {
+ const string16 name(ASCIIToUTF16(current->name));
+ switch (current->value_type) {
+ case Value::TYPE_STRING: {
+ string16 string_value;
+ if (GetRegistryPolicyString(name, &string_value)) {
+ result->SetString(current->name, string_value);
+ }
+ break;
+ }
+ case Value::TYPE_LIST: {
+ scoped_ptr<ListValue> list_value(new ListValue);
+ if (GetRegistryPolicyStringList(name, list_value.get()))
+ result->Set(current->name, list_value.release());
+ break;
+ }
+ case Value::TYPE_BOOLEAN: {
+ bool bool_value;
+ if (GetRegistryPolicyBoolean(name, &bool_value)) {
+ result->SetBoolean(current->name, bool_value);
+ }
+ break;
+ }
+ case Value::TYPE_INTEGER: {
+ uint32 int_value;
+ if (GetRegistryPolicyInteger(name, &int_value)) {
+ result->SetInteger(current->name, int_value);
+ }
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+ }
+ return result;
+}
+
+bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyString(
+ const string16& name, string16* result) const {
+ string16 path = string16(kRegistrySubKey);
+ RegKey policy_key;
+ // First try the global policy.
+ if (policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ)) {
+ if (ReadRegistryStringValue(&policy_key, name, result))
+ return true;
+ policy_key.Close();
+ }
+ // Fall back on user-specific policy.
+ if (!policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ))
+ return false;
+ return ReadRegistryStringValue(&policy_key, name, result);
+}
+
+bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyStringList(
+ const string16& key, ListValue* result) const {
+ string16 path = string16(kRegistrySubKey);
+ path += ASCIIToUTF16("\\") + key;
+ RegKey policy_key;
+ if (!policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ)) {
+ policy_key.Close();
+ // Fall back on user-specific policy.
+ if (!policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ))
+ return false;
+ }
+ string16 policy_string;
+ int index = 0;
+ while (ReadRegistryStringValue(&policy_key, base::IntToString16(++index),
+ &policy_string)) {
+ result->Append(Value::CreateStringValue(policy_string));
+ }
+ return true;
+}
+
+bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyBoolean(
+ const string16& value_name, bool* result) const {
+ DWORD value;
+ RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ);
+ if (hkcu_policy_key.ReadValueDW(value_name.c_str(), &value)) {
+ *result = value != 0;
+ return true;
+ }
+
+ RegKey hklm_policy_key(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ);
+ if (hklm_policy_key.ReadValueDW(value_name.c_str(), &value)) {
+ *result = value != 0;
+ return true;
+ }
+ return false;
+}
+
+bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyInteger(
+ const string16& value_name, uint32* result) const {
+ DWORD value;
+ RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ);
+ if (hkcu_policy_key.ReadValueDW(value_name.c_str(), &value)) {
+ *result = value;
+ return true;
+ }
+
+ RegKey hklm_policy_key(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ);
+ if (hklm_policy_key.ReadValueDW(value_name.c_str(), &value)) {
+ *result = value;
+ return true;
+ }
+ return false;
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/configuration_policy_provider_delegate_win.h b/chrome/browser/policy/configuration_policy_provider_delegate_win.h
new file mode 100644
index 0000000..63d36b2
--- /dev/null
+++ b/chrome/browser/policy/configuration_policy_provider_delegate_win.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_DELEGATE_WIN_H_
+#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_DELEGATE_WIN_H_
+#pragma once
+
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
+
+namespace policy {
+
+class ConfigurationPolicyProviderDelegateWin
+ : public AsynchronousPolicyProvider::Delegate {
+ public:
+ ConfigurationPolicyProviderDelegateWin(
+ const ConfigurationPolicyProvider::PolicyDefinitionList*
+ policy_definition_list);
+ virtual ~ConfigurationPolicyProviderDelegateWin() {}
+
+ // AsynchronousPolicyProvider::Delegate overrides:
+ virtual DictionaryValue* Load();
+
+ private:
+ // Methods to perform type-specific policy lookups in the registry.
+ // HKLM is checked first, then HKCU.
+
+ // Reads a string registry value |name| at the specified |key| and puts the
+ // resulting string in |result|.
+ bool GetRegistryPolicyString(const string16& name, string16* result) const;
+ // Gets a list value contained under |key| one level below the policy root.
+ bool GetRegistryPolicyStringList(const string16& key,
+ ListValue* result) const;
+ bool GetRegistryPolicyBoolean(const string16& value_name,
+ bool* result) const;
+ bool GetRegistryPolicyInteger(const string16& value_name,
+ uint32* result) const;
+
+ const ConfigurationPolicyProvider::PolicyDefinitionList*
+ policy_definition_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProviderDelegateWin);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_DELEGATE_WIN_H_
diff --git a/chrome/browser/policy/configuration_policy_provider_mac.cc b/chrome/browser/policy/configuration_policy_provider_mac.cc
index 62b7436..b8b6011 100644
--- a/chrome/browser/policy/configuration_policy_provider_mac.cc
+++ b/chrome/browser/policy/configuration_policy_provider_mac.cc
@@ -34,15 +34,15 @@ static FilePath GetManagedPolicyPath() {
return path.Append(base::SysCFStringRefToUTF8(bundle_id) + ".plist");
}
-MacPreferencesPolicyLoader::MacPreferencesPolicyLoader(
+MacPreferencesPolicyProviderDelegate::MacPreferencesPolicyProviderDelegate(
MacPreferences* preferences,
const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list)
- : FileBasedPolicyProvider::Delegate(GetManagedPolicyPath()),
+ : FileBasedPolicyProvider::ProviderDelegate(GetManagedPolicyPath()),
policy_list_(policy_list),
preferences_(preferences) {
}
-DictionaryValue* MacPreferencesPolicyLoader::Load() {
+DictionaryValue* MacPreferencesPolicyProviderDelegate::Load() {
preferences_->AppSynchronize(kCFPreferencesCurrentApplication);
DictionaryValue* policy = new DictionaryValue;
@@ -110,7 +110,7 @@ DictionaryValue* MacPreferencesPolicyLoader::Load() {
return policy;
}
-base::Time MacPreferencesPolicyLoader::GetLastModification() {
+base::Time MacPreferencesPolicyProviderDelegate::GetLastModification() {
base::PlatformFileInfo file_info;
if (!file_util::GetFileInfo(config_file_path(), &file_info) ||
file_info.is_directory) {
@@ -123,14 +123,16 @@ base::Time MacPreferencesPolicyLoader::GetLastModification() {
ConfigurationPolicyProviderMac::ConfigurationPolicyProviderMac(
const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list)
: FileBasedPolicyProvider(policy_list,
- new MacPreferencesPolicyLoader(new MacPreferences, policy_list)) {
+ new MacPreferencesPolicyProviderDelegate(new MacPreferences,
+ policy_list)) {
}
ConfigurationPolicyProviderMac::ConfigurationPolicyProviderMac(
const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list,
MacPreferences* preferences)
: FileBasedPolicyProvider(policy_list,
- new MacPreferencesPolicyLoader(preferences, policy_list)) {
+ new MacPreferencesPolicyProviderDelegate(preferences,
+ policy_list)) {
}
} // namespace policy
diff --git a/chrome/browser/policy/configuration_policy_provider_mac.h b/chrome/browser/policy/configuration_policy_provider_mac.h
index d804500..9332e2b 100644
--- a/chrome/browser/policy/configuration_policy_provider_mac.h
+++ b/chrome/browser/policy/configuration_policy_provider_mac.h
@@ -13,11 +13,12 @@
namespace policy {
-// A policy loader implementation that read Mac OS X's managed preferences.
-class MacPreferencesPolicyLoader : public FileBasedPolicyProvider::Delegate {
+// A provider delegate implementation that reads Mac OS X's managed preferences.
+class MacPreferencesPolicyProviderDelegate
+ : public FileBasedPolicyProvider::ProviderDelegate {
public:
// Takes ownership of |preferences|.
- MacPreferencesPolicyLoader(
+ MacPreferencesPolicyProviderDelegate(
MacPreferences* preferences,
const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list);
@@ -35,7 +36,7 @@ class MacPreferencesPolicyLoader : public FileBasedPolicyProvider::Delegate {
scoped_ptr<MacPreferences> preferences_;
- DISALLOW_COPY_AND_ASSIGN(MacPreferencesPolicyLoader);
+ DISALLOW_COPY_AND_ASSIGN(MacPreferencesPolicyProviderDelegate);
};
// An implementation of |ConfigurationPolicyProvider| using the mechanism
diff --git a/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc b/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc
index 5690375..345a3f6 100644
--- a/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_provider_mac_unittest.cc
@@ -233,8 +233,8 @@ INSTANTIATE_TEST_CASE_P(
kPolicyDefaultSearchProviderEncodings,
key::kDefaultSearchProviderEncodings),
PolicyTestParams::ForIntegerPolicy(
- kPolicyProxyServerMode,
- key::kProxyServerMode),
+ kPolicyProxyMode,
+ key::kProxyMode),
PolicyTestParams::ForStringPolicy(
kPolicyProxyServer,
key::kProxyServer),
diff --git a/chrome/browser/policy/configuration_policy_provider_win.cc b/chrome/browser/policy/configuration_policy_provider_win.cc
index 8f86973..df336d3 100644
--- a/chrome/browser/policy/configuration_policy_provider_win.cc
+++ b/chrome/browser/policy/configuration_policy_provider_win.cc
@@ -4,285 +4,22 @@
#include "chrome/browser/policy/configuration_policy_provider_win.h"
-#include <userenv.h>
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "base/object_watcher.h"
-#include "base/scoped_ptr.h"
-#include "base/string_number_conversions.h"
-#include "base/string_piece.h"
-#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#include "base/win/registry.h"
-#include "chrome/common/policy_constants.h"
-
-using base::win::RegKey;
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
+#include "chrome/browser/policy/configuration_policy_loader_win.h"
+#include "chrome/browser/policy/configuration_policy_provider_delegate_win.h"
namespace policy {
-namespace {
-
-bool ReadRegistryStringValue(RegKey* key, const string16& name,
- string16* result) {
- DWORD value_size = 0;
- DWORD key_type = 0;
- scoped_array<uint8> buffer;
-
- if (!key->ReadValue(name.c_str(), 0, &value_size, &key_type))
- return false;
- if (key_type != REG_SZ)
- return false;
-
- // According to the Microsoft documentation, the string
- // buffer may not be explicitly 0-terminated. Allocate a
- // slightly larger buffer and pre-fill to zeros to guarantee
- // the 0-termination.
- buffer.reset(new uint8[value_size + 2]);
- memset(buffer.get(), 0, value_size + 2);
- key->ReadValue(name.c_str(), buffer.get(), &value_size, NULL);
- result->assign(reinterpret_cast<const wchar_t*>(buffer.get()));
- return true;
-}
-
-} // namespace
-
// Period at which to run the reload task in case the group policy change
// watchers fail.
const int kReloadIntervalMinutes = 15;
-ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::
- GroupPolicyChangeWatcher(
- base::WeakPtr<ConfigurationPolicyProviderWin> provider,
- int reload_interval_minutes)
- : provider_(provider),
- user_policy_changed_event_(false, false),
- machine_policy_changed_event_(false, false),
- user_policy_watcher_failed_(false),
- machine_policy_watcher_failed_(false),
- reload_interval_minutes_(reload_interval_minutes),
- reload_task_(NULL) {
- if (!RegisterGPNotification(user_policy_changed_event_.handle(), false)) {
- PLOG(WARNING) << "Failed to register user group policy notification";
- user_policy_watcher_failed_ = true;
- }
- if (!RegisterGPNotification(machine_policy_changed_event_.handle(), true)) {
- PLOG(WARNING) << "Failed to register machine group policy notification.";
- machine_policy_watcher_failed_ = true;
- }
-}
-
-ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::
- ~GroupPolicyChangeWatcher() {
- if (MessageLoop::current())
- MessageLoop::current()->RemoveDestructionObserver(this);
- DCHECK(!reload_task_);
-}
-
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::Start() {
- MessageLoop::current()->AddDestructionObserver(this);
- SetupWatches();
-}
-
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::Stop() {
- user_policy_watcher_.StopWatching();
- machine_policy_watcher_.StopWatching();
- if (reload_task_) {
- reload_task_->Cancel();
- reload_task_ = NULL;
- }
-}
-
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::SetupWatches() {
- if (reload_task_) {
- reload_task_->Cancel();
- reload_task_ = NULL;
- }
-
- if (!user_policy_watcher_failed_) {
- if (!user_policy_watcher_.GetWatchedObject() &&
- !user_policy_watcher_.StartWatching(
- user_policy_changed_event_.handle(), this)) {
- LOG(WARNING) << "Failed to start watch for user policy change event";
- user_policy_watcher_failed_ = true;
- }
- }
- if (!machine_policy_watcher_failed_) {
- if (!machine_policy_watcher_.GetWatchedObject() &&
- !machine_policy_watcher_.StartWatching(
- machine_policy_changed_event_.handle(), this)) {
- LOG(WARNING) << "Failed to start watch for machine policy change event";
- machine_policy_watcher_failed_ = true;
- }
- }
-
- if (user_policy_watcher_failed_ || machine_policy_watcher_failed_) {
- reload_task_ =
- NewRunnableMethod(this, &GroupPolicyChangeWatcher::ReloadFromTask);
- int64 delay =
- base::TimeDelta::FromMinutes(reload_interval_minutes_).InMilliseconds();
- MessageLoop::current()->PostDelayedTask(FROM_HERE, reload_task_, delay);
- }
-}
-
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::Reload() {
- if (provider_.get())
- provider_->NotifyStoreOfPolicyChange();
- SetupWatches();
-}
-
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::
- ReloadFromTask() {
- // Make sure to not call Cancel() on the task, since it might hold the last
- // reference that keeps this object alive.
- reload_task_ = NULL;
- Reload();
-}
-
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::
- OnObjectSignaled(HANDLE object) {
- DCHECK(object == user_policy_changed_event_.handle() ||
- object == machine_policy_changed_event_.handle())
- << "unexpected object signaled policy reload, obj = "
- << std::showbase << std::hex << object;
- Reload();
-}
-
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::
- WillDestroyCurrentMessageLoop() {
- reload_task_ = NULL;
- MessageLoop::current()->RemoveDestructionObserver(this);
-}
-
ConfigurationPolicyProviderWin::ConfigurationPolicyProviderWin(
const PolicyDefinitionList* policy_list)
- : ConfigurationPolicyProvider(policy_list) {
- watcher_ = new GroupPolicyChangeWatcher(this->AsWeakPtr(),
- kReloadIntervalMinutes);
- watcher_->Start();
-}
-
-ConfigurationPolicyProviderWin::~ConfigurationPolicyProviderWin() {
- watcher_->Stop();
-}
-
-bool ConfigurationPolicyProviderWin::GetRegistryPolicyString(
- const string16& name, string16* result) const {
- string16 path = string16(kRegistrySubKey);
- RegKey policy_key;
- // First try the global policy.
- if (policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ)) {
- if (ReadRegistryStringValue(&policy_key, name, result))
- return true;
- policy_key.Close();
- }
- // Fall back on user-specific policy.
- if (!policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ))
- return false;
- return ReadRegistryStringValue(&policy_key, name, result);
-}
-
-bool ConfigurationPolicyProviderWin::GetRegistryPolicyStringList(
- const string16& key, ListValue* result) const {
- string16 path = string16(kRegistrySubKey);
- path += ASCIIToUTF16("\\") + key;
- RegKey policy_key;
- if (!policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ)) {
- policy_key.Close();
- // Fall back on user-specific policy.
- if (!policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ))
- return false;
- }
- string16 policy_string;
- int index = 0;
- while (ReadRegistryStringValue(&policy_key, base::IntToString16(++index),
- &policy_string)) {
- result->Append(Value::CreateStringValue(policy_string));
- }
- return true;
-}
-
-bool ConfigurationPolicyProviderWin::GetRegistryPolicyBoolean(
- const string16& value_name, bool* result) const {
- DWORD value;
- RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ);
- if (hkcu_policy_key.ReadValueDW(value_name.c_str(), &value)) {
- *result = value != 0;
- return true;
- }
-
- RegKey hklm_policy_key(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ);
- if (hklm_policy_key.ReadValueDW(value_name.c_str(), &value)) {
- *result = value != 0;
- return true;
- }
- return false;
-}
-
-bool ConfigurationPolicyProviderWin::GetRegistryPolicyInteger(
- const string16& value_name, uint32* result) const {
- DWORD value;
- RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ);
- if (hkcu_policy_key.ReadValueDW(value_name.c_str(), &value)) {
- *result = value;
- return true;
- }
-
- RegKey hklm_policy_key(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ);
- if (hklm_policy_key.ReadValueDW(value_name.c_str(), &value)) {
- *result = value;
- return true;
- }
- return false;
-}
-
-bool ConfigurationPolicyProviderWin::Provide(
- ConfigurationPolicyStoreInterface* store) {
- const PolicyDefinitionList* policy_list(policy_definition_list());
- for (const PolicyDefinitionList::Entry* current = policy_list->begin;
- current != policy_list->end; ++current) {
- std::wstring name = UTF8ToWide(current->name);
- switch (current->value_type) {
- case Value::TYPE_STRING: {
- std::wstring string_value;
- if (GetRegistryPolicyString(name.c_str(), &string_value)) {
- store->Apply(current->policy_type,
- Value::CreateStringValue(string_value));
- }
- break;
- }
- case Value::TYPE_LIST: {
- scoped_ptr<ListValue> list_value(new ListValue);
- if (GetRegistryPolicyStringList(name.c_str(), list_value.get()))
- store->Apply(current->policy_type, list_value.release());
- break;
- }
- case Value::TYPE_BOOLEAN: {
- bool bool_value;
- if (GetRegistryPolicyBoolean(name.c_str(), &bool_value)) {
- store->Apply(current->policy_type,
- Value::CreateBooleanValue(bool_value));
- }
- break;
- }
- case Value::TYPE_INTEGER: {
- uint32 int_value;
- if (GetRegistryPolicyInteger(name.c_str(), &int_value)) {
- store->Apply(current->policy_type,
- Value::CreateIntegerValue(int_value));
- }
- break;
- }
- default:
- NOTREACHED();
- return false;
- }
- }
-
- return true;
-}
+ : AsynchronousPolicyProvider(
+ policy_list,
+ new ConfigurationPolicyLoaderWin(
+ new ConfigurationPolicyProviderDelegateWin(policy_list),
+ kReloadIntervalMinutes)) {}
} // namespace policy
diff --git a/chrome/browser/policy/configuration_policy_provider_win.h b/chrome/browser/policy/configuration_policy_provider_win.h
index c2d5509..31e4a2b 100644
--- a/chrome/browser/policy/configuration_policy_provider_win.h
+++ b/chrome/browser/policy/configuration_policy_provider_win.h
@@ -6,19 +6,7 @@
#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_WIN_H_
#pragma once
-#include "base/object_watcher.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
-#include "base/waitable_event.h"
-#include "base/weak_ptr.h"
-#include "chrome/browser/policy/configuration_policy_store_interface.h"
-#include "chrome/browser/policy/configuration_policy_provider.h"
-
-namespace base {
-namespace win {
-class RegKey;
-} // namespace win
-} // namespace base
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
namespace policy {
@@ -28,89 +16,14 @@ namespace policy {
// On a managed machine in a domain, this portion of the registry is
// periodically updated by the Windows Group Policy machinery to contain
// the latest version of the policy set by administrators.
-class ConfigurationPolicyProviderWin
- : public ConfigurationPolicyProvider,
- public base::SupportsWeakPtr<ConfigurationPolicyProviderWin> {
+class ConfigurationPolicyProviderWin : public AsynchronousPolicyProvider {
public:
- // Keeps watch on Windows Group Policy notification event to trigger a policy
- // reload when Group Policy changes. This class is reference counted to
- // facilitate timer-based reloads through the message loop. It is not safe to
- // access GroupPolicyChangeWatcher concurrently from multiple threads.
- class GroupPolicyChangeWatcher
- : public base::ObjectWatcher::Delegate,
- public MessageLoop::DestructionObserver,
- public base::RefCountedThreadSafe<GroupPolicyChangeWatcher> {
- public:
- GroupPolicyChangeWatcher(
- base::WeakPtr<ConfigurationPolicyProviderWin> provider,
- int reload_interval_minutes);
- virtual ~GroupPolicyChangeWatcher();
-
- // Start watching.
- void Start();
-
- // Stop any pending watch activity in order to allow for timely shutdown.
- void Stop();
-
- private:
- // Updates the watchers and schedules the reload task if appropriate.
- void SetupWatches();
-
- // Post a reload notification and update the watch machinery.
- void Reload();
-
- // Called for timer-based refresh from the message loop.
- void ReloadFromTask();
-
- // ObjectWatcher::Delegate implementation:
- virtual void OnObjectSignaled(HANDLE object);
-
- // MessageLoop::DestructionObserver implementation:
- virtual void WillDestroyCurrentMessageLoop();
-
- base::WeakPtr<ConfigurationPolicyProviderWin> provider_;
- base::WaitableEvent user_policy_changed_event_;
- base::WaitableEvent machine_policy_changed_event_;
- base::ObjectWatcher user_policy_watcher_;
- base::ObjectWatcher machine_policy_watcher_;
- bool user_policy_watcher_failed_;
- bool machine_policy_watcher_failed_;
-
- // Period to schedule the reload task at.
- int reload_interval_minutes_;
-
- // A reference to a delayed task for timer-based reloading.
- CancelableTask* reload_task_;
- };
-
explicit ConfigurationPolicyProviderWin(
const PolicyDefinitionList* policy_list);
- virtual ~ConfigurationPolicyProviderWin();
-
- // ConfigurationPolicyProvider method overrides:
- virtual bool Provide(ConfigurationPolicyStoreInterface* store);
-
- protected:
- // The sub key path for Chromium's Group Policy information in the
- // Windows registry.
- static const wchar_t kPolicyRegistrySubKey[];
+ virtual ~ConfigurationPolicyProviderWin() {}
private:
- scoped_refptr<GroupPolicyChangeWatcher> watcher_;
-
- // Methods to perform type-specific policy lookups in the registry.
- // HKLM is checked first, then HKCU.
-
- // Reads a string registry value |name| at the specified |key| and puts the
- // resulting string in |result|.
- bool GetRegistryPolicyString(const string16& name, string16* result) const;
- // Gets a list value contained under |key| one level below the policy root.
- bool GetRegistryPolicyStringList(const string16& key,
- ListValue* result) const;
- bool GetRegistryPolicyBoolean(const string16& value_name,
- bool* result) const;
- bool GetRegistryPolicyInteger(const string16& value_name,
- uint32* result) const;
+ DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyProviderWin);
};
} // namespace policy
diff --git a/chrome/browser/policy/configuration_policy_provider_win_unittest.cc b/chrome/browser/policy/configuration_policy_provider_win_unittest.cc
index 39c4dce..beed450 100644
--- a/chrome/browser/policy/configuration_policy_provider_win_unittest.cc
+++ b/chrome/browser/policy/configuration_policy_provider_win_unittest.cc
@@ -3,15 +3,17 @@
// found in the LICENSE file.
#include <gtest/gtest.h>
-
#include <windows.h>
+#include "base/message_loop.h"
#include "base/scoped_ptr.h"
#include "base/stl_util-inl.h"
#include "base/string_number_conversions.h"
#include "base/string_piece.h"
#include "base/utf_string_conversions.h"
#include "base/win/registry.h"
+#include "chrome/browser/browser_thread.h"
+#include "chrome/browser/policy/asynchronous_policy_loader.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/configuration_policy_provider_win.h"
#include "chrome/browser/policy/mock_configuration_policy_store.h"
@@ -151,13 +153,16 @@ class ConfigurationPolicyProviderWinTest
scoped_ptr<MockConfigurationPolicyStore> store_;
scoped_ptr<ConfigurationPolicyProviderWin> provider_;
- private:
// A message loop must be declared and instantiated for these tests,
// because Windows policy provider create WaitableEvents and
// ObjectWatchers that require the tests to have a MessageLoop associated
// with the thread executing the tests.
MessageLoop loop_;
+ private:
+ BrowserThread ui_thread_;
+ BrowserThread file_thread_;
+
// Keys are created for the lifetime of a test to contain
// the sandboxed HKCU and HKLM hives, respectively.
RegKey temp_hkcu_hive_key_;
@@ -165,7 +170,9 @@ class ConfigurationPolicyProviderWinTest
};
ConfigurationPolicyProviderWinTest::ConfigurationPolicyProviderWinTest()
- : temp_hklm_hive_key_(HKEY_CURRENT_USER, kUnitTestMachineOverrideSubKey,
+ : ui_thread_(BrowserThread::UI, &loop_),
+ file_thread_(BrowserThread::FILE, &loop_),
+ temp_hklm_hive_key_(HKEY_CURRENT_USER, kUnitTestMachineOverrideSubKey,
KEY_READ),
temp_hkcu_hive_key_(HKEY_CURRENT_USER, kUnitTestUserOverrideSubKey,
KEY_READ) {
@@ -194,6 +201,7 @@ void ConfigurationPolicyProviderWinTest::SetUp() {
void ConfigurationPolicyProviderWinTest::TearDown() {
DeactivateOverrides();
DeleteRegistrySandbox();
+ loop_.RunAllPending();
}
void ConfigurationPolicyProviderWinTest::ActivateOverrides() {
@@ -299,6 +307,8 @@ TEST_P(ConfigurationPolicyProviderWinTest, InvalidValue) {
WriteInvalidValue(HKEY_CURRENT_USER,
GetParam().policy_name(),
GetParam().hkcu_value());
+ provider_->loader()->Reload();
+ loop_.RunAllPending();
provider_->Provide(store_.get());
EXPECT_TRUE(store_->policy_map().empty());
}
@@ -307,6 +317,8 @@ TEST_P(ConfigurationPolicyProviderWinTest, HKLM) {
WriteValue(HKEY_LOCAL_MACHINE,
GetParam().policy_name(),
GetParam().hklm_value());
+ provider_->loader()->Reload();
+ loop_.RunAllPending();
provider_->Provide(store_.get());
const Value* value = store_->Get(GetParam().type());
ASSERT_TRUE(value);
@@ -317,6 +329,8 @@ TEST_P(ConfigurationPolicyProviderWinTest, HKCU) {
WriteValue(HKEY_CURRENT_USER,
GetParam().policy_name(),
GetParam().hkcu_value());
+ provider_->loader()->Reload();
+ loop_.RunAllPending();
provider_->Provide(store_.get());
const Value* value = store_->Get(GetParam().type());
ASSERT_TRUE(value);
@@ -330,6 +344,8 @@ TEST_P(ConfigurationPolicyProviderWinTest, HKLMOverHKCU) {
WriteValue(HKEY_CURRENT_USER,
GetParam().policy_name(),
GetParam().hkcu_value());
+ provider_->loader()->Reload();
+ loop_.RunAllPending();
provider_->Provide(store_.get());
const Value* value = store_->Get(GetParam().type());
ASSERT_TRUE(value);
@@ -375,8 +391,8 @@ INSTANTIATE_TEST_CASE_P(
kPolicyDefaultSearchProviderEncodings,
key::kDefaultSearchProviderEncodings),
PolicyTestParams::ForIntegerPolicy(
- kPolicyProxyServerMode,
- key::kProxyServerMode),
+ kPolicyProxyMode,
+ key::kProxyMode),
PolicyTestParams::ForStringPolicy(
kPolicyProxyServer,
key::kProxyServer),
diff --git a/chrome/browser/policy/configuration_policy_store_interface.h b/chrome/browser/policy/configuration_policy_store_interface.h
index b47069e..b6d1f3b 100644
--- a/chrome/browser/policy/configuration_policy_store_interface.h
+++ b/chrome/browser/policy/configuration_policy_store_interface.h
@@ -25,7 +25,7 @@ enum ConfigurationPolicyType {
kPolicyDefaultSearchProviderIconURL,
kPolicyDefaultSearchProviderEncodings,
kPolicyDisableSpdy,
- kPolicyProxyServerMode,
+ kPolicyProxyMode,
kPolicyProxyServer,
kPolicyProxyPacUrl,
kPolicyProxyBypassList,
@@ -56,6 +56,8 @@ enum ConfigurationPolicyType {
kPolicyDefaultJavaScriptSetting,
kPolicyDefaultPluginsSetting,
kPolicyDefaultPopupsSetting,
+ kPolicyDefaultNotificationSetting,
+ kPolicyDefaultGeolocationSetting,
kPolicyExtensionInstallForceList,
kPolicyChromeOsLockOnIdleSuspend,
kPolicyAuthSchemes,
@@ -67,10 +69,24 @@ enum ConfigurationPolicyType {
kPolicyDisable3DAPIs
};
-static const int kPolicyNoProxyServerMode = 0;
-static const int kPolicyAutoDetectProxyMode = 1;
-static const int kPolicyManuallyConfiguredProxyMode = 2;
-static const int kPolicyUseSystemProxyMode = 3;
+
+// Constants for the "Proxy Server Mode" defined in the policies.
+// Note that these diverge from internal presentation defined in
+// ProxyPrefs::ProxyMode for legacy reasons. The following four
+// PolicyProxyModeType types were not very precise and had overlapping use
+// cases.
+enum PolicyProxyModeType {
+ // Disable Proxy, connect directly.
+ kPolicyNoProxyServerMode = 0,
+ // Auto detect proxy or use specific PAC script if given.
+ kPolicyAutoDetectProxyMode = 1,
+ // Use manually configured proxy servers (fixed servers).
+ kPolicyManuallyConfiguredProxyMode = 2,
+ // Use system proxy server.
+ kPolicyUseSystemProxyMode = 3,
+
+ MODE_COUNT
+};
// An abstract super class for policy stores that provides a method that can be
// called by a |ConfigurationPolicyProvider| to specify a policy.
diff --git a/chrome/browser/policy/device_management_policy_cache.cc b/chrome/browser/policy/device_management_policy_cache.cc
index 81af0f4..ab5dd15 100644
--- a/chrome/browser/policy/device_management_policy_cache.cc
+++ b/chrome/browser/policy/device_management_policy_cache.cc
@@ -70,6 +70,8 @@ DeviceManagementPolicyCache::DeviceManagementPolicyCache(
is_device_unmanaged_(false) {
}
+DeviceManagementPolicyCache::~DeviceManagementPolicyCache() {}
+
void DeviceManagementPolicyCache::LoadPolicyFromFile() {
if (!file_util::PathExists(backing_file_path_) || fresh_policy_)
return;
diff --git a/chrome/browser/policy/device_management_policy_cache.h b/chrome/browser/policy/device_management_policy_cache.h
index 86ae845..9c09a07 100644
--- a/chrome/browser/policy/device_management_policy_cache.h
+++ b/chrome/browser/policy/device_management_policy_cache.h
@@ -28,6 +28,7 @@ namespace em = enterprise_management;
class DeviceManagementPolicyCache {
public:
explicit DeviceManagementPolicyCache(const FilePath& backing_file_path);
+ ~DeviceManagementPolicyCache();
// Loads policy information from the backing file. Non-existing or erroneous
// cache files are ignored.
diff --git a/chrome/browser/policy/device_management_policy_provider.cc b/chrome/browser/policy/device_management_policy_provider.cc
index 9fa7f58..1a1f0c2 100644
--- a/chrome/browser/policy/device_management_policy_provider.cc
+++ b/chrome/browser/policy/device_management_policy_provider.cc
@@ -10,10 +10,10 @@
#include "base/rand_util.h"
#include "base/task.h"
#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/profile.h"
#include "chrome/browser/policy/device_management_backend.h"
#include "chrome/browser/policy/device_management_policy_cache.h"
#include "chrome/browser/policy/proto/device_management_constants.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
@@ -117,10 +117,14 @@ bool DeviceManagementPolicyProvider::Provide(
return true;
}
+bool DeviceManagementPolicyProvider::IsInitializationComplete() const {
+ return !waiting_for_initial_policies_;
+}
+
void DeviceManagementPolicyProvider::HandlePolicyResponse(
const em::DevicePolicyResponse& response) {
if (cache_->SetPolicy(response))
- NotifyStoreOfPolicyChange();
+ NotifyCloudPolicyUpdate();
policy_request_pending_ = false;
// Reset the error delay since policy fetching succeeded this time.
policy_refresh_error_delay_ms_ = kPolicyRefreshErrorDelayInMilliseconds;
@@ -185,6 +189,22 @@ void DeviceManagementPolicyProvider::Shutdown() {
token_fetcher_->Shutdown();
}
+void DeviceManagementPolicyProvider::AddObserver(
+ ConfigurationPolicyProvider::Observer* observer) {
+ observer_list_.AddObserver(observer);
+}
+
+void DeviceManagementPolicyProvider::RemoveObserver(
+ ConfigurationPolicyProvider::Observer* observer) {
+ observer_list_.RemoveObserver(observer);
+}
+
+void DeviceManagementPolicyProvider::NotifyCloudPolicyUpdate() {
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
+ observer_list_,
+ OnUpdatePolicy());
+}
+
void DeviceManagementPolicyProvider::Initialize(
DeviceManagementBackend* backend,
Profile* profile,
@@ -314,18 +334,10 @@ void DeviceManagementPolicyProvider::SetDeviceTokenFetcher(
void DeviceManagementPolicyProvider::StopWaitingForInitialPolicies() {
waiting_for_initial_policies_ = false;
- // Send a CLOUD_POLICY_UPDATE notification to unblock ChromeOS logins that
- // are waiting for an initial policy fetch to complete.
+ // Notify observers that initial policy fetch is complete.
NotifyCloudPolicyUpdate();
}
-void DeviceManagementPolicyProvider::NotifyCloudPolicyUpdate() const {
- NotificationService::current()->Notify(
- NotificationType::CLOUD_POLICY_UPDATE,
- Source<DeviceManagementPolicyProvider>(this),
- NotificationService::NoDetails());
-}
-
// static
std::string DeviceManagementPolicyProvider::GetDeviceManagementURL() {
return CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
diff --git a/chrome/browser/policy/device_management_policy_provider.h b/chrome/browser/policy/device_management_policy_provider.h
index c7cdcbc..17edf82 100644
--- a/chrome/browser/policy/device_management_policy_provider.h
+++ b/chrome/browser/policy/device_management_policy_provider.h
@@ -9,6 +9,7 @@
#include <string>
#include "base/file_path.h"
+#include "base/observer_list.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "base/weak_ptr.h"
@@ -41,6 +42,7 @@ class DeviceManagementPolicyProvider
// ConfigurationPolicyProvider implementation:
virtual bool Provide(ConfigurationPolicyStoreInterface* store);
+ virtual bool IsInitializationComplete() const;
// DevicePolicyResponseDelegate implementation:
virtual void HandlePolicyResponse(
@@ -48,17 +50,9 @@ class DeviceManagementPolicyProvider
virtual void OnError(DeviceManagementBackend::ErrorCode code);
// DeviceTokenFetcher::Observer implementation:
- void OnTokenSuccess();
- void OnTokenError();
- void OnNotManaged();
-
- // True if a policy request has been sent to the device management backend
- // server and no response or error has yet been received.
- bool IsPolicyRequestPending() const { return policy_request_pending_; }
-
- bool waiting_for_initial_policies() const {
- return waiting_for_initial_policies_;
- }
+ virtual void OnTokenSuccess();
+ virtual void OnTokenError();
+ virtual void OnNotManaged();
// Tells the provider that the passed in token service reference is about to
// become invalid.
@@ -96,6 +90,10 @@ class DeviceManagementPolicyProvider
// of initialization that requires the IOThread.
void InitializeAfterIOThreadExists();
+ // ConfigurationPolicyProvider overrides:
+ virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer);
+ virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer);
+
// Sends a request to the device manager backend to fetch policy if one isn't
// already outstanding.
void SendPolicyRequest();
@@ -112,8 +110,8 @@ class DeviceManagementPolicyProvider
void StopWaitingForInitialPolicies();
- // Send a CLOUD_POLICY_UPDATE notification.
- void NotifyCloudPolicyUpdate() const;
+ // Notify observers about a policy update.
+ void NotifyCloudPolicyUpdate();
// The path of the device token file.
FilePath GetTokenPath();
@@ -135,6 +133,7 @@ class DeviceManagementPolicyProvider
scoped_ptr<DeviceManagementPolicyCache> cache_;
scoped_refptr<DeviceTokenFetcher> token_fetcher_;
DeviceTokenFetcher::ObserverRegistrar registrar_;
+ ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_;
FilePath storage_dir_;
bool policy_request_pending_;
bool refresh_task_pending_;
diff --git a/chrome/browser/policy/device_management_policy_provider_unittest.cc b/chrome/browser/policy/device_management_policy_provider_unittest.cc
index 3269531..4886f9d 100644
--- a/chrome/browser/policy/device_management_policy_provider_unittest.cc
+++ b/chrome/browser/policy/device_management_policy_provider_unittest.cc
@@ -8,16 +8,18 @@
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/net/gaia/token_service.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
+#include "chrome/browser/policy/configuration_policy_provider.h"
#include "chrome/browser/policy/device_management_policy_cache.h"
#include "chrome/browser/policy/device_management_policy_provider.h"
#include "chrome/browser/policy/mock_configuration_policy_store.h"
#include "chrome/browser/policy/mock_device_management_backend.h"
#include "chrome/common/net/gaia/gaia_constants.h"
+#include "chrome/common/notification_observer_mock.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/policy_constants.h"
-#include "chrome/test/mock_notification_observer.h"
#include "chrome/test/testing_device_token_fetcher.h"
#include "chrome/test/testing_profile.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
const char kTestToken[] = "device_policy_provider_test_auth_token";
@@ -28,6 +30,12 @@ using ::testing::_;
using ::testing::InSequence;
using ::testing::Mock;
+class MockConfigurationPolicyObserver
+ : public ConfigurationPolicyProvider::Observer {
+ public:
+ MOCK_METHOD0(OnUpdatePolicy, void());
+};
+
class DeviceManagementPolicyProviderTest : public testing::Test {
public:
DeviceManagementPolicyProviderTest()
@@ -39,7 +47,7 @@ class DeviceManagementPolicyProviderTest : public testing::Test {
virtual void SetUp() {
profile_.reset(new TestingProfile);
CreateNewProvider();
- EXPECT_TRUE(provider_->waiting_for_initial_policies());
+ EXPECT_TRUE(waiting_for_initial_policies());
loop_.RunAllPending();
}
@@ -99,7 +107,7 @@ class DeviceManagementPolicyProviderTest : public testing::Test {
MockDeviceManagementBackendSucceedBooleanPolicy(
key::kDisableSpdy, true));
SimulateSuccessfulLoginAndRunPending();
- EXPECT_FALSE(provider_->waiting_for_initial_policies());
+ EXPECT_FALSE(waiting_for_initial_policies());
EXPECT_CALL(store, Apply(kPolicyDisableSpdy, _)).Times(1);
provider_->Provide(&store);
ASSERT_EQ(1U, store.policy_map().size());
@@ -111,6 +119,10 @@ class DeviceManagementPolicyProviderTest : public testing::Test {
loop_.RunAllPending();
}
+ bool waiting_for_initial_policies() const {
+ return provider_->waiting_for_initial_policies_;
+ }
+
MockDeviceManagementBackend* backend_; // weak
scoped_ptr<DeviceManagementPolicyProvider> provider_;
@@ -136,14 +148,14 @@ TEST_F(DeviceManagementPolicyProviderTest, InitialProvideNoLogin) {
EXPECT_CALL(store, Apply(_, _)).Times(0);
provider_->Provide(&store);
EXPECT_TRUE(store.policy_map().empty());
- EXPECT_TRUE(provider_->waiting_for_initial_policies());
+ EXPECT_TRUE(waiting_for_initial_policies());
}
// If the login is successful and there's no previously-fetched policy, the
// policy should be fetched from the server and should be available the first
// time the Provide method is called.
TEST_F(DeviceManagementPolicyProviderTest, InitialProvideWithLogin) {
- EXPECT_TRUE(provider_->waiting_for_initial_policies());
+ EXPECT_TRUE(waiting_for_initial_policies());
SimulateSuccessfulInitialPolicyFetch();
}
@@ -193,12 +205,11 @@ TEST_F(DeviceManagementPolicyProviderTest, SecondProvide) {
// When policy is successfully fetched from the device management server, it
// should force a policy refresh.
TEST_F(DeviceManagementPolicyProviderTest, FetchTriggersRefresh) {
- MockNotificationObserver observer;
- NotificationRegistrar registrar;
- registrar.Add(&observer,
- NotificationType::POLICY_CHANGED,
- NotificationService::AllSources());
- EXPECT_CALL(observer, Observe(_, _, _)).Times(1);
+ MockConfigurationPolicyObserver observer;
+ ConfigurationPolicyObserverRegistrar registrar;
+ registrar.Init(provider_.get());
+ registrar.AddObserver(&observer);
+ EXPECT_CALL(observer, OnUpdatePolicy()).Times(1);
SimulateSuccessfulInitialPolicyFetch();
}
@@ -305,7 +316,7 @@ TEST_F(DeviceManagementPolicyProviderTest, UnmanagedDevice) {
// (2) On restart, the provider should detect that this is not the first
// login.
CreateNewProvider(1000*1000, 0, 0, 0, 0);
- EXPECT_FALSE(provider_->waiting_for_initial_policies());
+ EXPECT_FALSE(waiting_for_initial_policies());
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
diff --git a/chrome/browser/policy/device_management_service.cc b/chrome/browser/policy/device_management_service.cc
index 05c8789..689c947 100644
--- a/chrome/browser/policy/device_management_service.cc
+++ b/chrome/browser/policy/device_management_service.cc
@@ -14,7 +14,6 @@
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_status.h"
-#include "chrome/browser/browser_process.h"
#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/chrome_net_log.h"
#include "chrome/browser/policy/device_management_backend_impl.h"
diff --git a/chrome/browser/policy/device_management_service_browsertest.cc b/chrome/browser/policy/device_management_service_browsertest.cc
index 6c07e9e..feed86f 100644
--- a/chrome/browser/policy/device_management_service_browsertest.cc
+++ b/chrome/browser/policy/device_management_service_browsertest.cc
@@ -3,11 +3,10 @@
// found in the LICENSE file.
#include "base/message_loop.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/policy/device_management_backend_mock.h"
#include "chrome/browser/policy/device_management_service.h"
#include "chrome/browser/policy/proto/device_management_constants.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/in_process_browser_test.h"
#include "net/test/test_server.h"
@@ -43,22 +42,22 @@ const char kServiceResponseUnregister[] =
#define PROTO_STRING(name) (std::string(name, arraysize(name) - 1))
// Interceptor implementation that returns test data back to the service.
-class CannedResponseInterceptor : public URLRequest::Interceptor {
+class CannedResponseInterceptor : public net::URLRequest::Interceptor {
public:
CannedResponseInterceptor(const GURL& service_url,
const std::string& response_data)
: service_url_(service_url),
response_data_(response_data) {
- URLRequest::RegisterRequestInterceptor(this);
+ net::URLRequest::RegisterRequestInterceptor(this);
}
virtual ~CannedResponseInterceptor() {
- URLRequest::UnregisterRequestInterceptor(this);
+ net::URLRequest::UnregisterRequestInterceptor(this);
}
private:
- // URLRequest::Interceptor overrides.
- virtual URLRequestJob* MaybeIntercept(URLRequest* request) {
+ // net::URLRequest::Interceptor overrides.
+ virtual net::URLRequestJob* MaybeIntercept(net::URLRequest* request) {
if (request->url().GetOrigin() == service_url_.GetOrigin() &&
request->url().path() == service_url_.path()) {
return new URLRequestTestJob(request,
diff --git a/chrome/browser/policy/device_token_fetcher.cc b/chrome/browser/policy/device_token_fetcher.cc
index 8f42544..678c90f 100644
--- a/chrome/browser/policy/device_token_fetcher.cc
+++ b/chrome/browser/policy/device_token_fetcher.cc
@@ -8,11 +8,11 @@
#include "base/path_service.h"
#include "base/singleton.h"
#include "base/string_util.h"
-#include "chrome/browser/guid.h"
#include "chrome/browser/net/gaia/token_service.h"
#include "chrome/browser/policy/proto/device_management_local.pb.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/guid.h"
#include "chrome/common/net/gaia/gaia_constants.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_service.h"
@@ -57,6 +57,31 @@ namespace policy {
namespace em = enterprise_management;
+DeviceTokenFetcher::ObserverRegistrar::ObserverRegistrar() {}
+
+DeviceTokenFetcher::ObserverRegistrar::~ObserverRegistrar() {
+ RemoveAll();
+}
+
+void DeviceTokenFetcher::ObserverRegistrar::Init(
+ DeviceTokenFetcher* token_fetcher) {
+ token_fetcher_ = token_fetcher;
+}
+
+void DeviceTokenFetcher::ObserverRegistrar::AddObserver(
+ DeviceTokenFetcher::Observer* observer) {
+ observers_.push_back(observer);
+ token_fetcher_->AddObserver(observer);
+}
+
+void DeviceTokenFetcher::ObserverRegistrar::RemoveAll() {
+ for (std::vector<DeviceTokenFetcher::Observer*>::iterator it =
+ observers_.begin(); it != observers_.end(); ++it) {
+ token_fetcher_->RemoveObserver(*it);
+ }
+ observers_.clear();
+}
+
DeviceTokenFetcher::DeviceTokenFetcher(
DeviceManagementBackend* backend,
Profile* profile,
@@ -88,6 +113,8 @@ DeviceTokenFetcher::DeviceTokenFetcher(
#endif
}
+DeviceTokenFetcher::~DeviceTokenFetcher() {}
+
void DeviceTokenFetcher::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
diff --git a/chrome/browser/policy/device_token_fetcher.h b/chrome/browser/policy/device_token_fetcher.h
index 9b991de..c36af5b 100644
--- a/chrome/browser/policy/device_token_fetcher.h
+++ b/chrome/browser/policy/device_token_fetcher.h
@@ -43,23 +43,12 @@ class DeviceTokenFetcher
class ObserverRegistrar {
public:
- void Init(DeviceTokenFetcher* token_fetcher) {
- token_fetcher_ = token_fetcher;
- }
- ~ObserverRegistrar() {
- RemoveAll();
- }
- void AddObserver(DeviceTokenFetcher::Observer* observer) {
- observers_.push_back(observer);
- token_fetcher_->AddObserver(observer);
- }
- void RemoveAll() {
- for (std::vector<DeviceTokenFetcher::Observer*>::iterator it =
- observers_.begin(); it != observers_.end(); ++it) {
- token_fetcher_->RemoveObserver(*it);
- }
- observers_.clear();
- }
+ ObserverRegistrar();
+ ~ObserverRegistrar();
+
+ void Init(DeviceTokenFetcher* token_fetcher);
+ void AddObserver(DeviceTokenFetcher::Observer* observer);
+ void RemoveAll();
private:
DeviceTokenFetcher* token_fetcher_;
std::vector<DeviceTokenFetcher::Observer*> observers_;
@@ -71,7 +60,7 @@ class DeviceTokenFetcher
DeviceTokenFetcher(DeviceManagementBackend* backend,
Profile* profile,
const FilePath& token_path);
- virtual ~DeviceTokenFetcher() {}
+ virtual ~DeviceTokenFetcher();
// NotificationObserver method overrides:
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/policy/device_token_fetcher_unittest.cc b/chrome/browser/policy/device_token_fetcher_unittest.cc
index e8c2c92..f4a7e23 100644
--- a/chrome/browser/policy/device_token_fetcher_unittest.cc
+++ b/chrome/browser/policy/device_token_fetcher_unittest.cc
@@ -12,7 +12,6 @@
#include "chrome/browser/policy/device_token_fetcher.h"
#include "chrome/browser/policy/mock_device_management_backend.h"
#include "chrome/common/net/gaia/gaia_constants.h"
-#include "chrome/common/notification_service.h"
#include "chrome/test/testing_device_token_fetcher.h"
#include "chrome/test/testing_profile.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/policy/dummy_configuration_policy_provider.cc b/chrome/browser/policy/dummy_configuration_policy_provider.cc
new file mode 100644
index 0000000..9a8f491
--- /dev/null
+++ b/chrome/browser/policy/dummy_configuration_policy_provider.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/dummy_configuration_policy_provider.h"
+
+namespace policy {
+
+DummyConfigurationPolicyProvider::DummyConfigurationPolicyProvider(
+ const PolicyDefinitionList* policy_list)
+ : ConfigurationPolicyProvider(policy_list) {
+}
+
+DummyConfigurationPolicyProvider::~DummyConfigurationPolicyProvider() {
+}
+
+bool DummyConfigurationPolicyProvider::Provide(
+ ConfigurationPolicyStoreInterface* store) {
+ return true;
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/dummy_configuration_policy_provider.h b/chrome/browser/policy/dummy_configuration_policy_provider.h
index 2c519cb..22ca152 100644
--- a/chrome/browser/policy/dummy_configuration_policy_provider.h
+++ b/chrome/browser/policy/dummy_configuration_policy_provider.h
@@ -6,24 +6,26 @@
#define CHROME_BROWSER_POLICY_DUMMY_CONFIGURATION_POLICY_PROVIDER_H_
#pragma once
-#include "chrome/browser/policy/configuration_policy_store_interface.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
namespace policy {
+class ConfigurationPolicyStoreInterface;
+
class DummyConfigurationPolicyProvider : public ConfigurationPolicyProvider {
public:
explicit DummyConfigurationPolicyProvider(
- const PolicyDefinitionList* policy_list)
- : ConfigurationPolicyProvider(policy_list) {
- }
- virtual ~DummyConfigurationPolicyProvider() {}
+ const PolicyDefinitionList* policy_list);
+ virtual ~DummyConfigurationPolicyProvider();
- virtual bool Provide(ConfigurationPolicyStoreInterface* store) {
- return true;
- }
+ virtual bool Provide(ConfigurationPolicyStoreInterface* store);
private:
+ // ConfigurationPolicyProvider overrides:
+ virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) {}
+ virtual void RemoveObserver(
+ ConfigurationPolicyProvider::Observer* observer) {}
+
DISALLOW_COPY_AND_ASSIGN(DummyConfigurationPolicyProvider);
};
diff --git a/chrome/browser/policy/file_based_policy_loader.cc b/chrome/browser/policy/file_based_policy_loader.cc
new file mode 100644
index 0000000..cc89d13
--- /dev/null
+++ b/chrome/browser/policy/file_based_policy_loader.cc
@@ -0,0 +1,144 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/file_based_policy_loader.h"
+
+namespace {
+
+// Amount of time we wait for the files on disk to settle before trying to load
+// them. This alleviates the problem of reading partially written files and
+// makes it possible to batch quasi-simultaneous changes.
+const int kSettleIntervalSeconds = 5;
+
+// The time interval for rechecking policy. This is our fallback in case the
+// delegate never reports a change to the ReloadObserver.
+const int kReloadIntervalMinutes = 15;
+
+} // namespace
+
+namespace policy {
+
+FileBasedPolicyLoader::FileBasedPolicyLoader(
+ FileBasedPolicyProvider::ProviderDelegate* provider_delegate)
+ : AsynchronousPolicyLoader(provider_delegate,
+ kReloadIntervalMinutes),
+ config_file_path_(provider_delegate->config_file_path()),
+ settle_interval_(base::TimeDelta::FromSeconds(kSettleIntervalSeconds)) {
+}
+
+FileBasedPolicyLoader::~FileBasedPolicyLoader() {}
+
+class FileBasedPolicyWatcherDelegate : public FilePathWatcher::Delegate {
+ public:
+ explicit FileBasedPolicyWatcherDelegate(
+ scoped_refptr<FileBasedPolicyLoader> loader)
+ : loader_(loader) {}
+ virtual ~FileBasedPolicyWatcherDelegate() {}
+
+ // FilePathWatcher::Delegate implementation:
+ void OnFilePathChanged(const FilePath& path) {
+ loader_->OnFilePathChanged(path);
+ }
+
+ void OnError() {
+ loader_->OnError();
+ }
+
+ private:
+ scoped_refptr<FileBasedPolicyLoader> loader_;
+ DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyWatcherDelegate);
+};
+
+void FileBasedPolicyLoader::OnFilePathChanged(
+ const FilePath& path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ Reload();
+}
+
+void FileBasedPolicyLoader::OnError() {
+ LOG(ERROR) << "FilePathWatcher on " << config_file_path().value()
+ << " failed.";
+}
+
+void FileBasedPolicyLoader::Reload() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ if (!delegate())
+ return;
+
+ // Check the directory time in order to see whether a reload is required.
+ base::TimeDelta delay;
+ base::Time now = base::Time::Now();
+ if (!IsSafeToReloadPolicy(now, &delay)) {
+ ScheduleReloadTask(delay);
+ return;
+ }
+
+ // Load the policy definitions.
+ scoped_ptr<DictionaryValue> new_policy(delegate()->Load());
+
+ // Check again in case the directory has changed while reading it.
+ if (!IsSafeToReloadPolicy(now, &delay)) {
+ ScheduleReloadTask(delay);
+ return;
+ }
+
+ PostUpdatePolicyTask(new_policy.release());
+
+ ScheduleFallbackReloadTask();
+}
+
+void FileBasedPolicyLoader::InitOnFileThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ watcher_.reset(new FilePathWatcher);
+ if (!config_file_path().empty() &&
+ !watcher_->Watch(config_file_path(),
+ new FileBasedPolicyWatcherDelegate(this))) {
+ OnError();
+ }
+
+ // There might have been changes to the directory in the time between
+ // construction of the loader and initialization of the watcher. Call reload
+ // to detect if that is the case.
+ Reload();
+
+ ScheduleFallbackReloadTask();
+}
+
+void FileBasedPolicyLoader::StopOnFileThread() {
+ watcher_.reset();
+ AsynchronousPolicyLoader::StopOnFileThread();
+}
+
+bool FileBasedPolicyLoader::IsSafeToReloadPolicy(
+ const base::Time& now,
+ base::TimeDelta* delay) {
+ DCHECK(delay);
+
+ // A null modification time indicates there's no data.
+ FileBasedPolicyProvider::ProviderDelegate* provider_delegate =
+ static_cast<FileBasedPolicyProvider::ProviderDelegate*>(delegate());
+ base::Time last_modification(provider_delegate->GetLastModification());
+ if (last_modification.is_null())
+ return true;
+
+ // If there was a change since the last recorded modification, wait some more.
+ if (last_modification != last_modification_file_) {
+ last_modification_file_ = last_modification;
+ last_modification_clock_ = now;
+ *delay = settle_interval_;
+ return false;
+ }
+
+ // Check whether the settle interval has elapsed.
+ base::TimeDelta age = now - last_modification_clock_;
+ if (age < settle_interval_) {
+ *delay = settle_interval_ - age;
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/file_based_policy_loader.h b/chrome/browser/policy/file_based_policy_loader.h
new file mode 100644
index 0000000..97c3198
--- /dev/null
+++ b/chrome/browser/policy/file_based_policy_loader.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_FILE_BASED_POLICY_LOADER_H_
+#define CHROME_BROWSER_POLICY_FILE_BASED_POLICY_LOADER_H_
+#pragma once
+
+#include "chrome/browser/file_path_watcher/file_path_watcher.h"
+#include "chrome/browser/policy/asynchronous_policy_loader.h"
+#include "chrome/browser/policy/file_based_policy_provider.h"
+
+namespace policy {
+
+// A customized asynchronous policy loader that handles loading policy from a
+// file using a FilePathWatcher. The loader creates a fallback task to load
+// policy periodically in case the watcher fails and retries policy loads when
+// the watched file is in flux.
+class FileBasedPolicyLoader : public AsynchronousPolicyLoader {
+ public:
+ FileBasedPolicyLoader(
+ FileBasedPolicyProvider::ProviderDelegate* provider_delegate);
+
+ // AsynchronousPolicyLoader overrides:
+ virtual void Reload();
+
+ void OnFilePathChanged(const FilePath& path);
+ void OnError();
+
+ protected:
+ // FileBasedPolicyLoader objects should only be deleted by
+ // RefCountedThreadSafe.
+ friend class base::RefCountedThreadSafe<AsynchronousPolicyLoader>;
+ virtual ~FileBasedPolicyLoader();
+
+ const FilePath& config_file_path() { return config_file_path_; }
+
+ // AsynchronousPolicyLoader overrides:
+
+ // Creates the file path watcher and configures it to watch
+ // |config_file_path_|. Must be called on the file thread.
+ virtual void InitOnFileThread();
+ virtual void StopOnFileThread();
+
+ private:
+ // Checks whether policy information is safe to read. If not, returns false
+ // and then delays until it is considered safe to reload in |delay|.
+ // Must be called on the file thread.
+ bool IsSafeToReloadPolicy(const base::Time& now, base::TimeDelta* delay);
+
+ // The path at which we look for configuration files.
+ const FilePath config_file_path_;
+
+ // Managed with a scoped_ptr rather than being declared as an inline member to
+ // decouple the watcher's life cycle from the loader's. This decoupling makes
+ // it possible to destroy the watcher before the loader's destructor is called
+ // (e.g. during Stop), since |watcher_| internally holds a reference to the
+ // loader and keeps it alive.
+ scoped_ptr<FilePathWatcher> watcher_;
+
+ // Settle interval.
+ const base::TimeDelta settle_interval_;
+
+ // Records last known modification timestamp of |config_file_path_|.
+ base::Time last_modification_file_;
+
+ // The wall clock time at which the last modification timestamp was
+ // recorded. It's better to not assume the file notification time and the
+ // wall clock times come from the same source, just in case there is some
+ // non-local filesystem involved.
+ base::Time last_modification_clock_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyLoader);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_FILE_BASED_POLICY_LOADER_H_
diff --git a/chrome/browser/policy/file_based_policy_provider.cc b/chrome/browser/policy/file_based_policy_provider.cc
index 578277d..488f19f 100644
--- a/chrome/browser/policy/file_based_policy_provider.cc
+++ b/chrome/browser/policy/file_based_policy_provider.cc
@@ -4,241 +4,21 @@
#include "chrome/browser/policy/file_based_policy_provider.h"
-#include <set>
-
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/task.h"
-#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/browser_thread.h"
-#include "chrome/common/json_value_serializer.h"
+#include "chrome/browser/policy/file_based_policy_loader.h"
namespace policy {
-// Amount of time we wait for the files on disk to settle before trying to load
-// it. This alleviates the problem of reading partially written files and allows
-// to batch quasi-simultaneous changes.
-const int kSettleIntervalSeconds = 5;
-
-// The time interval for rechecking policy. This is our fallback in case the
-// file path watch fails or doesn't report a change.
-const int kReloadIntervalMinutes = 15;
-
-// FileBasedPolicyProvider implementation:
+FileBasedPolicyProvider::ProviderDelegate::ProviderDelegate(
+ const FilePath& config_file_path)
+ : config_file_path_(config_file_path) {}
-FileBasedPolicyProvider::Delegate::~Delegate() {
-}
-
-FileBasedPolicyProvider::Delegate::Delegate(const FilePath& config_file_path)
- : config_file_path_(config_file_path) {
-}
+FileBasedPolicyProvider::ProviderDelegate::~ProviderDelegate() {}
FileBasedPolicyProvider::FileBasedPolicyProvider(
const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list,
- FileBasedPolicyProvider::Delegate* delegate)
- : ConfigurationPolicyProvider(policy_list) {
- loader_ = new FileBasedPolicyLoader(AsWeakPtr(),
- delegate,
- kSettleIntervalSeconds,
- kReloadIntervalMinutes);
- watcher_ = new FileBasedPolicyWatcher;
- watcher_->Init(loader_.get());
-}
-
-FileBasedPolicyProvider::~FileBasedPolicyProvider() {
- loader_->Stop();
-}
-
-bool FileBasedPolicyProvider::Provide(
- ConfigurationPolicyStoreInterface* store) {
- scoped_ptr<DictionaryValue> policy(loader_->GetPolicy());
- DCHECK(policy.get());
- DecodePolicyValueTree(policy.get(), store);
- return true;
-}
-
-// FileBasedPolicyLoader implementation:
-
-FileBasedPolicyLoader::FileBasedPolicyLoader(
- base::WeakPtr<ConfigurationPolicyProvider> provider,
- FileBasedPolicyProvider::Delegate* delegate,
- int settle_interval_seconds,
- int reload_interval_minutes)
- : delegate_(delegate),
- provider_(provider),
- origin_loop_(MessageLoop::current()),
- reload_task_(NULL),
- settle_interval_seconds_(settle_interval_seconds),
- reload_interval_minutes_(reload_interval_minutes) {
- // Force an initial load, so GetPolicy() works.
- policy_.reset(delegate_->Load());
- DCHECK(policy_.get());
-}
-
-void FileBasedPolicyLoader::Stop() {
- if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &FileBasedPolicyLoader::Stop));
- return;
- }
-
- if (reload_task_) {
- reload_task_->Cancel();
- reload_task_ = NULL;
- }
-}
-
-void FileBasedPolicyLoader::Reload() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- // Check the directory time in order to see whether a reload is required.
- base::TimeDelta delay;
- base::Time now = base::Time::Now();
- if (!IsSafeToReloadPolicy(now, &delay)) {
- ScheduleReloadTask(delay);
- return;
- }
-
- // Load the policy definitions.
- scoped_ptr<DictionaryValue> new_policy(delegate_->Load());
-
- // Check again in case the directory has changed while reading it.
- if (!IsSafeToReloadPolicy(now, &delay)) {
- ScheduleReloadTask(delay);
- return;
- }
-
- // Replace policy definition.
- bool changed = false;
- {
- AutoLock lock(lock_);
- changed = !policy_->Equals(new_policy.get());
- policy_.reset(new_policy.release());
- }
-
- // There's a change, report it!
- if (changed) {
- VLOG(0) << "Policy reload from " << config_file_path().value()
- << " succeeded.";
- origin_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &FileBasedPolicyLoader::NotifyPolicyChanged));
- }
-
- // As a safeguard in case the file watcher fails, schedule a reload task
- // that'll make us recheck after a reasonable interval.
- ScheduleReloadTask(base::TimeDelta::FromMinutes(reload_interval_minutes_));
-}
-
-DictionaryValue* FileBasedPolicyLoader::GetPolicy() {
- AutoLock lock(lock_);
- return static_cast<DictionaryValue*>(policy_->DeepCopy());
-}
-
-void FileBasedPolicyLoader::OnFilePathChanged(const FilePath& path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- Reload();
-}
-
-void FileBasedPolicyLoader::OnError() {
- LOG(ERROR) << "FilePathWatcher on " << config_file_path().value()
- << " failed.";
-}
-
-FileBasedPolicyLoader::~FileBasedPolicyLoader() {
-}
-
-bool FileBasedPolicyLoader::IsSafeToReloadPolicy(const base::Time& now,
- base::TimeDelta* delay) {
- DCHECK(delay);
-
- // A null modification time indicates there's no data.
- base::Time last_modification(delegate_->GetLastModification());
- if (last_modification.is_null())
- return true;
-
- // If there was a change since the last recorded modification, wait some more.
- base::TimeDelta settleInterval(
- base::TimeDelta::FromSeconds(settle_interval_seconds_));
- if (last_modification != last_modification_file_) {
- last_modification_file_ = last_modification;
- last_modification_clock_ = now;
- *delay = settleInterval;
- return false;
- }
-
- // Check whether the settle interval has elapsed.
- base::TimeDelta age = now - last_modification_clock_;
- if (age < settleInterval) {
- *delay = settleInterval - age;
- return false;
- }
-
- return true;
-}
-
-void FileBasedPolicyLoader::ScheduleReloadTask(const base::TimeDelta& delay) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- if (reload_task_)
- reload_task_->Cancel();
-
- reload_task_ =
- NewRunnableMethod(this, &FileBasedPolicyLoader::ReloadFromTask);
- BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, reload_task_,
- delay.InMilliseconds());
-}
-
-void FileBasedPolicyLoader::NotifyPolicyChanged() {
- DCHECK_EQ(origin_loop_, MessageLoop::current());
- if (provider_)
- provider_->NotifyStoreOfPolicyChange();
-}
-
-void FileBasedPolicyLoader::ReloadFromTask() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- // Drop the reference to the reload task, since the task might be the only
- // referer that keeps us alive, so we should not Cancel() it.
- reload_task_ = NULL;
-
- Reload();
-}
-
-// FileBasedPolicyWatcher implementation:
-
-FileBasedPolicyWatcher::FileBasedPolicyWatcher() {
-}
-
-void FileBasedPolicyWatcher::Init(FileBasedPolicyLoader* loader) {
- // Initialization can happen early when the file thread is not yet available.
- // So post a task to ourselves on the UI thread which will run after threading
- // is up and schedule watch initialization on the file thread.
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this,
- &FileBasedPolicyWatcher::InitWatcher,
- scoped_refptr<FileBasedPolicyLoader>(loader)));
-}
-
-FileBasedPolicyWatcher::~FileBasedPolicyWatcher() {
-}
-
-void FileBasedPolicyWatcher::InitWatcher(
- const scoped_refptr<FileBasedPolicyLoader>& loader) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &FileBasedPolicyWatcher::InitWatcher, loader));
- return;
- }
-
- if (!loader->config_file_path().empty() &&
- !watcher_.Watch(loader->config_file_path(), loader.get()))
- loader->OnError();
-
- // There might have been changes to the directory in the time between
- // construction of the loader and initialization of the watcher. Call reload
- // to detect if that is the case.
- loader->Reload();
-}
+ FileBasedPolicyProvider::ProviderDelegate* delegate)
+ : AsynchronousPolicyProvider(
+ policy_list,
+ new FileBasedPolicyLoader(delegate)) {}
} // namespace policy
diff --git a/chrome/browser/policy/file_based_policy_provider.h b/chrome/browser/policy/file_based_policy_provider.h
index a4e989d..c94e1d4 100644
--- a/chrome/browser/policy/file_based_policy_provider.h
+++ b/chrome/browser/policy/file_based_policy_provider.h
@@ -6,39 +6,25 @@
#define CHROME_BROWSER_POLICY_FILE_BASED_POLICY_PROVIDER_H_
#pragma once
-#include "base/basictypes.h"
#include "base/file_path.h"
-#include "base/lock.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
#include "base/time.h"
-#include "base/weak_ptr.h"
-#include "chrome/browser/file_path_watcher.h"
-#include "chrome/browser/policy/configuration_policy_provider.h"
-
-class CancelableTask;
-class DictionaryValue;
-class MessageLoop;
+#include "chrome/browser/policy/asynchronous_policy_provider.h"
namespace policy {
-class FileBasedPolicyLoader;
-class FileBasedPolicyWatcher;
-
// File based policy provider that coordinates watching and reloading policy
// information from the configuration path. Actual logic for loading policy
// information is handled by a delegate passed at construction time.
-class FileBasedPolicyProvider
- : public ConfigurationPolicyProvider,
- public base::SupportsWeakPtr<FileBasedPolicyProvider> {
+class FileBasedPolicyProvider : public AsynchronousPolicyProvider {
public:
+
// Delegate interface for actual policy loading from the system.
- class Delegate {
+ class ProviderDelegate : public AsynchronousPolicyProvider::Delegate {
public:
- virtual ~Delegate();
+ explicit ProviderDelegate(const FilePath& config_file_path);
+ virtual ~ProviderDelegate();
- // Loads the policy information. Ownership of the return value is
- // transferred to the caller.
+ // AsynchronousPolicyProvider::Delegate implementation:
virtual DictionaryValue* Load() = 0;
// Gets the last modification timestamp for the policy information from the
@@ -48,152 +34,21 @@ class FileBasedPolicyProvider
const FilePath& config_file_path() { return config_file_path_; }
- protected:
- explicit Delegate(const FilePath& config_file_path);
-
private:
- // The path at which we look for configuration files.
const FilePath config_file_path_;
- DISALLOW_COPY_AND_ASSIGN(Delegate);
+ DISALLOW_COPY_AND_ASSIGN(ProviderDelegate);
};
// Assumes ownership of |delegate|.
FileBasedPolicyProvider(const PolicyDefinitionList* policy_list,
- Delegate* delegate);
- virtual ~FileBasedPolicyProvider();
-
- // ConfigurationPolicyProvider implementation.
- virtual bool Provide(ConfigurationPolicyStoreInterface* store);
+ ProviderDelegate* delegate);
+ virtual ~FileBasedPolicyProvider() {}
private:
- // Watches for changes to the configuration directory.
- scoped_refptr<FileBasedPolicyWatcher> watcher_;
-
- // The loader object we use internally.
- scoped_refptr<FileBasedPolicyLoader> loader_;
-
DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyProvider);
};
-// FilePathWatcher delegate implementation that handles change notifications for
-// the configuration file or directory. It keeps the authorative version of the
-// currently effective policy dictionary and updates it as appropriate. The
-// actual loading logic is handled by a delegate.
-class FileBasedPolicyLoader : public FilePathWatcher::Delegate {
- public:
- // Creates a new loader that'll load its data from |config_file_path|.
- // Assumes ownership of |delegate|, which provides the actual loading logic.
- // The parameters |settle_interval_seconds| and |reload_interval_minutes|
- // specify the time to wait before reading the file contents after a change
- // and the period for checking |config_file_path| for changes, respectively.
- FileBasedPolicyLoader(base::WeakPtr<ConfigurationPolicyProvider> provider,
- FileBasedPolicyProvider::Delegate* delegate,
- int settle_interval_seconds,
- int reload_interval_minutes);
-
- // Stops any pending reload tasks.
- void Stop();
-
- // Reloads the policies and sends out a notification, if appropriate. Must be
- // called on the file thread.
- void Reload();
-
- // Gets the current dictionary value object. Ownership of the returned value
- // is transferred to the caller.
- DictionaryValue* GetPolicy();
-
- const FilePath& config_file_path() { return delegate_->config_file_path(); }
-
- // FilePathWatcher::Delegate implementation:
- void OnFilePathChanged(const FilePath& path);
- void OnError();
-
- private:
- // FileBasedPolicyLoader objects should only be deleted by
- // RefCountedThreadSafe.
- friend class base::RefCountedThreadSafe<FileBasedPolicyLoader>;
- virtual ~FileBasedPolicyLoader();
-
- // Checks whether reading policy information is safe to do. If not, returns
- // false and the delay until it is considered safe to reload in |delay|.
- bool IsSafeToReloadPolicy(const base::Time& now, base::TimeDelta* delay);
-
- // Schedules a reload task to run when |delay| expires. Must be called on the
- // file thread.
- void ScheduleReloadTask(const base::TimeDelta& delay);
-
- // Notifies the policy provider to send out a policy changed notification.
- // Must be called on |origin_loop_|.
- void NotifyPolicyChanged();
-
- // Invoked from the reload task on the file thread.
- void ReloadFromTask();
-
- // The delegate.
- scoped_ptr<FileBasedPolicyProvider::Delegate> delegate_;
-
- // The provider this loader is associated with. Access only on the thread that
- // called the constructor. See |origin_loop_| below.
- base::WeakPtr<ConfigurationPolicyProvider> provider_;
-
- // The message loop on which this object was constructed and |provider_|
- // received on. Recorded so we can call back into the non thread safe provider
- // to fire the notification.
- MessageLoop* origin_loop_;
-
- // Records last known modification timestamp of |config_file_path_|.
- base::Time last_modification_file_;
-
- // The wall clock time at which the last modification timestamp was recorded.
- // It's better to not assume the file notification time and the wall clock
- // times come from the same source, just in case there is some non-local
- // filesystem involved.
- base::Time last_modification_clock_;
-
- // Protects |policy_|.
- Lock lock_;
-
- // The current policy definition.
- scoped_ptr<DictionaryValue> policy_;
-
- // The reload task. Access only on the file thread. Holds a reference to the
- // currently posted task, so we can cancel and repost it if necessary.
- CancelableTask* reload_task_;
-
- // Settle and reload intervals.
- const int settle_interval_seconds_;
- const int reload_interval_minutes_;
-
- DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyLoader);
-};
-
-// Wraps a FilePathWatcher for the configuration path and takes care of
-// initializing the watcher object on the file thread.
-class FileBasedPolicyWatcher
- : public base::RefCountedThreadSafe<FileBasedPolicyWatcher> {
- public:
- FileBasedPolicyWatcher();
-
- // Runs initialization. This is in a separate method since we need to post a
- // task (which cannot be done from the constructor).
- void Init(FileBasedPolicyLoader* loader);
-
- private:
- // FileBasedPolicyWatcher objects should only be deleted by
- // RefCountedThreadSafe.
- friend class base::RefCountedThreadSafe<FileBasedPolicyWatcher>;
- virtual ~FileBasedPolicyWatcher();
-
- // Actually sets up the watch with the FilePathWatcher code.
- void InitWatcher(const scoped_refptr<FileBasedPolicyLoader>& loader);
-
- // Wrapped watcher that takes care of the actual watching.
- FilePathWatcher watcher_;
-
- DISALLOW_COPY_AND_ASSIGN(FileBasedPolicyWatcher);
-};
-
} // namespace policy
#endif // CHROME_BROWSER_POLICY_FILE_BASED_POLICY_PROVIDER_H_
diff --git a/chrome/browser/policy/file_based_policy_provider_unittest.cc b/chrome/browser/policy/file_based_policy_provider_unittest.cc
index c78c586..1bb2185 100644
--- a/chrome/browser/policy/file_based_policy_provider_unittest.cc
+++ b/chrome/browser/policy/file_based_policy_provider_unittest.cc
@@ -2,130 +2,80 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chrome/browser/policy/asynchronous_policy_loader.h"
+#include "chrome/browser/policy/asynchronous_policy_test_base.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
+#include "chrome/browser/policy/configuration_policy_store_interface.h"
#include "chrome/browser/policy/file_based_policy_provider.h"
+#include "chrome/common/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-using testing::Mock;
+using testing::_;
+using testing::InSequence;
+using testing::Return;
namespace policy {
-// Shorter reload intervals for testing FileBasedPolicyLoader.
-const int kSettleIntervalSecondsForTesting = 0;
-const int kReloadIntervalMinutesForTesting = 1;
-
-// A delegate for testing that can feed arbitrary information to the loader.
-class TestDelegate : public FileBasedPolicyProvider::Delegate {
- public:
- TestDelegate()
- : FileBasedPolicyProvider::Delegate(FilePath(FILE_PATH_LITERAL("fake"))) {
- }
-
- // FileBasedPolicyProvider::Delegate implementation:
- virtual DictionaryValue* Load() {
- return static_cast<DictionaryValue*>(dict_.DeepCopy());
- }
-
- virtual base::Time GetLastModification() {
- return last_modification_;
- }
-
- DictionaryValue* dict() { return &dict_; }
- void set_last_modification(const base::Time& last_modification) {
- last_modification_ = last_modification;
- }
-
- private:
- DictionaryValue dict_;
- base::Time last_modification_;
-};
-
-// A mock provider that allows us to capture reload notifications.
-class MockPolicyProvider : public ConfigurationPolicyProvider,
- public base::SupportsWeakPtr<MockPolicyProvider> {
+class FileBasedPolicyProviderDelegateMock
+ : public FileBasedPolicyProvider::ProviderDelegate {
public:
- explicit MockPolicyProvider()
- : ConfigurationPolicyProvider(
- ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()) {
- }
-
- virtual bool Provide(ConfigurationPolicyStoreInterface* store) {
- return true;
- }
-
- MOCK_METHOD0(NotifyStoreOfPolicyChange, void());
+ FileBasedPolicyProviderDelegateMock()
+ : FileBasedPolicyProvider::ProviderDelegate(FilePath()) {}
+ MOCK_METHOD0(Load, DictionaryValue*());
+ MOCK_METHOD0(GetLastModification, base::Time());
};
-class FileBasedPolicyLoaderTest : public testing::Test {
- protected:
- FileBasedPolicyLoaderTest()
- : ui_thread_(BrowserThread::UI, &loop_),
- file_thread_(BrowserThread::FILE, &loop_) {}
-
- virtual void TearDown() {
- loop_.RunAllPending();
- }
-
- MessageLoop loop_;
-
- private:
- BrowserThread ui_thread_;
- BrowserThread file_thread_;
-};
-
-TEST_F(FileBasedPolicyLoaderTest, BasicLoad) {
- TestDelegate* test_delegate = new TestDelegate;
- test_delegate->dict()->SetString("HomepageLocation", "http://www.google.com");
-
- scoped_refptr<FileBasedPolicyLoader> loader(
- new FileBasedPolicyLoader(base::WeakPtr<FileBasedPolicyProvider>(),
- test_delegate,
- kSettleIntervalSecondsForTesting,
- kReloadIntervalMinutesForTesting));
- scoped_ptr<DictionaryValue> policy(loader->GetPolicy());
- EXPECT_TRUE(policy.get());
- EXPECT_EQ(1U, policy->size());
-
- std::string str_value;
- EXPECT_TRUE(policy->GetString("HomepageLocation", &str_value));
- EXPECT_EQ("http://www.google.com", str_value);
-
- loader->Stop();
+TEST_F(AsynchronousPolicyTestBase, ProviderInit) {
+ base::Time last_modified;
+ FileBasedPolicyProviderDelegateMock* provider_delegate =
+ new FileBasedPolicyProviderDelegateMock();
+ EXPECT_CALL(*provider_delegate, GetLastModification()).WillRepeatedly(
+ Return(last_modified));
+ InSequence s;
+ EXPECT_CALL(*provider_delegate, Load()).WillOnce(Return(
+ new DictionaryValue));
+ DictionaryValue* policies = new DictionaryValue();
+ policies->SetBoolean(policy::key::kSyncDisabled, true);
+ // A second call to Load gets triggered during the provider's construction
+ // when the file watcher is initialized, since this file may have changed
+ // between the initial load and creating watcher.
+ EXPECT_CALL(*provider_delegate, Load()).WillOnce(Return(policies));
+ FileBasedPolicyProvider provider(
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
+ provider_delegate);
+ loop_.RunAllPending();
+ EXPECT_CALL(*store_, Apply(policy::kPolicySyncDisabled, _)).Times(1);
+ provider.Provide(store_.get());
}
-TEST_F(FileBasedPolicyLoaderTest, TestRefresh) {
- MockPolicyProvider provider;
- TestDelegate* test_delegate = new TestDelegate;
-
- scoped_refptr<FileBasedPolicyLoader> loader(
- new FileBasedPolicyLoader(provider.AsWeakPtr(),
- test_delegate,
- kSettleIntervalSecondsForTesting,
- kReloadIntervalMinutesForTesting));
- scoped_ptr<DictionaryValue> policy(loader->GetPolicy());
- EXPECT_TRUE(policy.get());
- EXPECT_EQ(0U, policy->size());
-
- test_delegate->dict()->SetString("HomepageLocation", "http://www.google.com");
-
- EXPECT_CALL(provider, NotifyStoreOfPolicyChange()).Times(1);
- loader->OnFilePathChanged(FilePath(FILE_PATH_LITERAL("fake")));
-
- // Run the loop. The refresh should be handled immediately since the settle
- // interval has been disabled.
+TEST_F(AsynchronousPolicyTestBase, ProviderRefresh) {
+ base::Time last_modified;
+ FileBasedPolicyProviderDelegateMock* provider_delegate =
+ new FileBasedPolicyProviderDelegateMock();
+ EXPECT_CALL(*provider_delegate, GetLastModification()).WillRepeatedly(
+ Return(last_modified));
+ InSequence s;
+ EXPECT_CALL(*provider_delegate, Load()).WillOnce(Return(
+ new DictionaryValue));
+ FileBasedPolicyProvider file_based_provider(
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
+ provider_delegate);
+ // A second call to Load gets triggered during the provider's construction
+ // when the file watcher is initialized, since this file may have changed
+ // between the initial load and creating watcher.
+ EXPECT_CALL(*provider_delegate, Load()).WillOnce(Return(
+ new DictionaryValue));
loop_.RunAllPending();
- Mock::VerifyAndClearExpectations(&provider);
-
- policy.reset(loader->GetPolicy());
- EXPECT_TRUE(policy.get());
- EXPECT_EQ(1U, policy->size());
-
- std::string str_value;
- EXPECT_TRUE(policy->GetString("HomepageLocation", &str_value));
- EXPECT_EQ("http://www.google.com", str_value);
-
- loader->Stop();
+ // A third and final call to Load is made by the explicit Reload. This
+ // should be the one that provides the current policy.
+ DictionaryValue* policies = new DictionaryValue();
+ policies->SetBoolean(policy::key::kSyncDisabled, true);
+ EXPECT_CALL(*provider_delegate, Load()).WillOnce(Return(policies));
+ file_based_provider.loader()->Reload();
+ loop_.RunAllPending();
+ EXPECT_CALL(*store_, Apply(policy::kPolicySyncDisabled, _)).Times(1);
+ file_based_provider.Provide(store_.get());
}
} // namespace policy
diff --git a/chrome/browser/policy/managed_prefs_banner_base.cc b/chrome/browser/policy/managed_prefs_banner_base.cc
index 1351da4..7c20a09 100644
--- a/chrome/browser/policy/managed_prefs_banner_base.cc
+++ b/chrome/browser/policy/managed_prefs_banner_base.cc
@@ -84,8 +84,7 @@ void ManagedPrefsBannerBase::Init(PrefService* local_state,
#if defined(GOOGLE_CHROME_BUILD)
AddLocalStatePref(prefs::kMetricsReportingEnabled);
#endif
- AddUserPref(prefs::kNoProxyServer);
- AddUserPref(prefs::kProxyAutoDetect);
+ AddUserPref(prefs::kProxyMode);
AddUserPref(prefs::kProxyServer);
AddUserPref(prefs::kProxyPacUrl);
AddUserPref(prefs::kProxyBypassList);
diff --git a/chrome/browser/policy/managed_prefs_banner_base.h b/chrome/browser/policy/managed_prefs_banner_base.h
index e087cb1..40b798e 100644
--- a/chrome/browser/policy/managed_prefs_banner_base.h
+++ b/chrome/browser/policy/managed_prefs_banner_base.h
@@ -8,7 +8,7 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
-#include "chrome/browser/options_window.h"
+#include "chrome/browser/ui/options/options_window.h"
#include "chrome/common/notification_observer.h"
class PrefService;
diff --git a/chrome/browser/policy/managed_prefs_banner_base_unittest.cc b/chrome/browser/policy/managed_prefs_banner_base_unittest.cc
index 35425b1..3f2569d 100644
--- a/chrome/browser/policy/managed_prefs_banner_base_unittest.cc
+++ b/chrome/browser/policy/managed_prefs_banner_base_unittest.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "chrome/browser/policy/managed_prefs_banner_base.h"
-#include "chrome/browser/prefs/dummy_pref_store.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/policy/mock_configuration_policy_provider.cc b/chrome/browser/policy/mock_configuration_policy_provider.cc
index 4f11497..a2566b0 100644
--- a/chrome/browser/policy/mock_configuration_policy_provider.cc
+++ b/chrome/browser/policy/mock_configuration_policy_provider.cc
@@ -4,13 +4,15 @@
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
+#include "base/stl_util-inl.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
namespace policy {
MockConfigurationPolicyProvider::MockConfigurationPolicyProvider()
: ConfigurationPolicyProvider(
- ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()) {
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()),
+ initialization_complete_(false) {
}
MockConfigurationPolicyProvider::~MockConfigurationPolicyProvider() {
@@ -23,6 +25,20 @@ void MockConfigurationPolicyProvider::AddPolicy(ConfigurationPolicyType policy,
delete value;
}
+void MockConfigurationPolicyProvider::RemovePolicy(
+ ConfigurationPolicyType policy) {
+ const PolicyMap::iterator entry = policy_map_.find(policy);
+ if (entry != policy_map_.end()) {
+ delete entry->second;
+ policy_map_.erase(entry);
+ }
+}
+
+void MockConfigurationPolicyProvider::SetInitializationComplete(
+ bool initialization_complete) {
+ initialization_complete_ = initialization_complete;
+}
+
bool MockConfigurationPolicyProvider::Provide(
ConfigurationPolicyStoreInterface* store) {
for (PolicyMap::const_iterator current = policy_map_.begin();
@@ -32,4 +48,8 @@ bool MockConfigurationPolicyProvider::Provide(
return true;
}
+bool MockConfigurationPolicyProvider::IsInitializationComplete() const {
+ return initialization_complete_;
+}
+
}
diff --git a/chrome/browser/policy/mock_configuration_policy_provider.h b/chrome/browser/policy/mock_configuration_policy_provider.h
index 8ba8a88..5620f81 100644
--- a/chrome/browser/policy/mock_configuration_policy_provider.h
+++ b/chrome/browser/policy/mock_configuration_policy_provider.h
@@ -9,8 +9,8 @@
#include <map>
#include <utility>
-#include "base/stl_util-inl.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
+#include "testing/gmock/include/gmock/gmock.h"
namespace policy {
@@ -22,14 +22,24 @@ class MockConfigurationPolicyProvider : public ConfigurationPolicyProvider {
virtual ~MockConfigurationPolicyProvider();
void AddPolicy(ConfigurationPolicyType policy, Value* value);
+ void RemovePolicy(ConfigurationPolicyType policy);
+
+ void SetInitializationComplete(bool initialization_complete);
// ConfigurationPolicyProvider method overrides.
virtual bool Provide(ConfigurationPolicyStoreInterface* store);
+ virtual bool IsInitializationComplete() const;
private:
+ // ConfigurationPolicyProvider overrides:
+ virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) {}
+ virtual void RemoveObserver(
+ ConfigurationPolicyProvider::Observer* observer) {}
+
typedef std::map<ConfigurationPolicyType, Value*> PolicyMap;
PolicyMap policy_map_;
+ bool initialization_complete_;
};
} // namespace policy
diff --git a/chrome/browser/policy/profile_policy_context.cc b/chrome/browser/policy/profile_policy_context.cc
index 0882ab4..c4b6e5b 100644
--- a/chrome/browser/policy/profile_policy_context.cc
+++ b/chrome/browser/policy/profile_policy_context.cc
@@ -7,7 +7,7 @@
#include "chrome/browser/policy/device_management_policy_provider.h"
#include "chrome/browser/policy/device_management_service.h"
#include "chrome/browser/policy/profile_policy_context.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
namespace policy {