summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_process.h6
-rw-r--r--chrome/browser/browser_process_impl.cc14
-rw-r--r--chrome/browser/browser_process_impl.h3
-rw-r--r--chrome/browser/policy/browser_policy_connector.cc13
-rw-r--r--chrome/browser/policy/browser_policy_connector.h6
-rw-r--r--chrome/browser/policy/policy_service.h59
-rw-r--r--chrome/browser/policy/policy_service_impl.cc136
-rw-r--r--chrome/browser/policy/policy_service_impl.h81
-rw-r--r--chrome/browser/policy/policy_service_unittest.cc153
-rw-r--r--chrome/chrome_browser.gypi3
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/test/base/testing_browser_process.cc18
-rw-r--r--chrome/test/base/testing_browser_process.h3
13 files changed, 496 insertions, 0 deletions
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index 27ec3064..ae13a4c 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -66,6 +66,7 @@ class PrintPreviewTabController;
namespace policy {
class BrowserPolicyConnector;
+class PolicyService;
}
namespace safe_browsing {
@@ -123,8 +124,13 @@ class BrowserProcess {
// Returns the thread that is used for health check of all browser threads.
virtual WatchDogThread* watchdog_thread() = 0;
+ // Starts and manages the policy system.
virtual policy::BrowserPolicyConnector* browser_policy_connector() = 0;
+ // This is the main interface for chromium components to retrieve policy
+ // information from the policy system.
+ virtual policy::PolicyService* policy_service() = 0;
+
virtual IconManager* icon_manager() = 0;
virtual ThumbnailGenerator* GetThumbnailGenerator() = 0;
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 40aa7f4..3e861a1 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -42,6 +42,7 @@
#include "chrome/browser/net/sdch_dictionary_fetcher.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/policy_service_impl.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prerender/prerender_tracker.h"
@@ -401,6 +402,19 @@ policy::BrowserPolicyConnector* BrowserProcessImpl::browser_policy_connector() {
return browser_policy_connector_.get();
}
+policy::PolicyService* BrowserProcessImpl::policy_service() {
+#if defined(ENABLE_CONFIGURATION_POLICY)
+ return browser_policy_connector()->GetPolicyService();
+#else
+ // Return a dummy instance that doesn't serve any policies.
+ if (!policy_service_.get()) {
+ policy::PolicyService::Providers emptyProviders;
+ policy_service_.reset(new policy::PolicyServiceImpl(emptyProviders));
+ }
+ return policy_service_.get();
+#endif
+}
+
IconManager* BrowserProcessImpl::icon_manager() {
DCHECK(CalledOnValidThread());
if (!created_icon_manager_)
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index 8c03cbb..32be939 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -35,6 +35,7 @@ class TabCloseableStateWatcher;
namespace policy {
class BrowserPolicyConnector;
+class PolicyService;
};
// Real implementation of BrowserProcess that creates and returns the services.
@@ -77,6 +78,7 @@ class BrowserProcessImpl : public BrowserProcess,
extension_event_router_forwarder() OVERRIDE;
virtual NotificationUIManager* notification_ui_manager() OVERRIDE;
virtual policy::BrowserPolicyConnector* browser_policy_connector() OVERRIDE;
+ virtual policy::PolicyService* policy_service() OVERRIDE;
virtual IconManager* icon_manager() OVERRIDE;
virtual ThumbnailGenerator* GetThumbnailGenerator() OVERRIDE;
virtual AutomationProviderList* GetAutomationProviderList() OVERRIDE;
@@ -175,6 +177,7 @@ class BrowserProcessImpl : public BrowserProcess,
bool created_browser_policy_connector_;
scoped_ptr<policy::BrowserPolicyConnector> browser_policy_connector_;
+ scoped_ptr<policy::PolicyService> policy_service_;
scoped_refptr<printing::PrintPreviewTabController>
print_preview_tab_controller_;
diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc
index 4a88c93..bb6a250 100644
--- a/chrome/browser/policy/browser_policy_connector.cc
+++ b/chrome/browser/policy/browser_policy_connector.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/policy/cloud_policy_subsystem.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
#include "chrome/browser/policy/network_configuration_updater.h"
+#include "chrome/browser/policy/policy_service_impl.h"
#include "chrome/browser/policy/user_policy_cache.h"
#include "chrome/browser/policy/user_policy_token_cache.h"
#include "chrome/browser/signin/token_service.h"
@@ -114,6 +115,14 @@ void BrowserPolicyConnector::Init() {
GetChromePolicyDefinitionList(),
POLICY_LEVEL_RECOMMENDED));
+ // |providers| in decreasing order of priority.
+ PolicyServiceImpl::Providers providers;
+ providers.push_back(managed_platform_provider_.get());
+ providers.push_back(managed_cloud_provider_.get());
+ providers.push_back(recommended_platform_provider_.get());
+ providers.push_back(recommended_cloud_provider_.get());
+ policy_service_.reset(new PolicyServiceImpl(providers));
+
#if defined(OS_CHROMEOS)
InitializeDevicePolicy();
@@ -146,6 +155,10 @@ ConfigurationPolicyProvider*
return recommended_cloud_provider_.get();
}
+PolicyService* BrowserPolicyConnector::GetPolicyService() const {
+ return policy_service_.get();
+}
+
void BrowserPolicyConnector::RegisterForDevicePolicy(
const std::string& owner_email,
const std::string& token,
diff --git a/chrome/browser/policy/browser_policy_connector.h b/chrome/browser/policy/browser_policy_connector.h
index adb0c8c..ef98482 100644
--- a/chrome/browser/policy/browser_policy_connector.h
+++ b/chrome/browser/policy/browser_policy_connector.h
@@ -26,6 +26,8 @@ class CloudPolicyProvider;
class CloudPolicySubsystem;
class ConfigurationPolicyProvider;
class NetworkConfigurationUpdater;
+class PolicyService;
+class PolicyServiceImpl;
class UserPolicyTokenCache;
// Manages the lifecycle of browser-global policy infrastructure, such as the
@@ -49,6 +51,8 @@ class BrowserPolicyConnector : public content::NotificationObserver {
ConfigurationPolicyProvider* GetRecommendedPlatformProvider() const;
ConfigurationPolicyProvider* GetRecommendedCloudProvider() const;
+ PolicyService* GetPolicyService() const;
+
// Returns a weak pointer to the CloudPolicySubsystem corresponding to the
// device policy managed by this policy connector, or NULL if no such
// subsystem exists (i.e. when running outside ChromeOS).
@@ -151,6 +155,8 @@ class BrowserPolicyConnector : public content::NotificationObserver {
scoped_ptr<CloudPolicyProvider> managed_cloud_provider_;
scoped_ptr<CloudPolicyProvider> recommended_cloud_provider_;
+ scoped_ptr<PolicyServiceImpl> policy_service_;
+
#if defined(OS_CHROMEOS)
scoped_ptr<CloudPolicyDataStore> device_data_store_;
scoped_ptr<CloudPolicySubsystem> device_cloud_policy_subsystem_;
diff --git a/chrome/browser/policy/policy_service.h b/chrome/browser/policy/policy_service.h
new file mode 100644
index 0000000..a3d8ad1
--- /dev/null
+++ b/chrome/browser/policy/policy_service.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_POLICY_SERVICE_H_
+#define CHROME_BROWSER_POLICY_POLICY_SERVICE_H_
+#pragma once
+
+#include <string>
+
+#include "chrome/browser/policy/policy_map.h"
+
+namespace policy {
+
+// Policies are namespaced by a (PolicyDomain, ID) pair. The meaning of the ID
+// string depends on the domain; for example, if the PolicyDomain is
+// "extensions" then the ID identifies the extension that the policies control.
+// Currently CHROME is the only domain available, and its ID is always the empty
+// string.
+enum PolicyDomain {
+ POLICY_DOMAIN_CHROME,
+};
+
+// The PolicyService merges policies from all available sources, taking into
+// account their priorities. Policy clients can retrieve policy for their domain
+// and register for notifications on policy updates.
+//
+// The PolicyService is available from BrowserProcess as a global singleton.
+class PolicyService {
+ public:
+ class Observer {
+ public:
+ virtual ~Observer() {}
+ // Invoked whenever policies for the |domain|, |component_id| namespace are
+ // modified. This is only invoked for changes that happen after AddObserver
+ // is called.
+ virtual void OnPolicyUpdated(PolicyDomain domain,
+ const std::string& component_id) = 0;
+ };
+
+ virtual ~PolicyService() {}
+
+ virtual void AddObserver(PolicyDomain domain,
+ const std::string& component_id,
+ Observer* observer) = 0;
+
+ virtual void RemoveObserver(PolicyDomain domain,
+ const std::string& component_id,
+ Observer* observer) = 0;
+
+ // Returns NULL if no policies are available for |domain|, | component_id|.
+ virtual const PolicyMap* GetPolicies(
+ PolicyDomain domain,
+ const std::string& component_id) const = 0;
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_POLICY_SERVICE_H_
diff --git a/chrome/browser/policy/policy_service_impl.cc b/chrome/browser/policy/policy_service_impl.cc
new file mode 100644
index 0000000..fd7a558
--- /dev/null
+++ b/chrome/browser/policy/policy_service_impl.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/policy_service_impl.h"
+
+#include "base/observer_list.h"
+#include "base/stl_util.h"
+
+namespace policy {
+
+struct PolicyServiceImpl::Entry {
+ PolicyMap policies;
+ ObserverList<PolicyService::Observer, true> observers;
+};
+
+struct PolicyServiceImpl::ProviderData {
+ ConfigurationPolicyProvider* provider;
+ ConfigurationPolicyObserverRegistrar registrar;
+ PolicyMap policies;
+};
+
+PolicyServiceImpl::PolicyServiceImpl(const Providers& providers) {
+ for (size_t i = 0; i < providers.size(); ++i) {
+ ConfigurationPolicyProvider* provider = providers[i];
+ ProviderData* data = new ProviderData;
+ data->provider = provider;
+ data->registrar.Init(provider, this);
+ if (provider->IsInitializationComplete())
+ provider->Provide(&data->policies);
+ providers_.push_back(data);
+ }
+ // There are no observers yet, but calls to GetPolicies() should already get
+ // the processed policy values.
+ MergeAndTriggerUpdates();
+}
+
+PolicyServiceImpl::~PolicyServiceImpl() {
+ STLDeleteElements(&providers_);
+ STLDeleteValues(&entries_);
+}
+
+void PolicyServiceImpl::AddObserver(PolicyDomain domain,
+ const std::string& component_id,
+ PolicyService::Observer* observer) {
+ PolicyNamespace ns = std::make_pair(domain, component_id);
+ GetOrCreate(ns)->observers.AddObserver(observer);
+}
+
+void PolicyServiceImpl::RemoveObserver(PolicyDomain domain,
+ const std::string& component_id,
+ PolicyService::Observer* observer) {
+ PolicyNamespace ns = std::make_pair(domain, component_id);
+ EntryMap::const_iterator it = entries_.find(ns);
+ if (it == entries_.end()) {
+ NOTREACHED();
+ return;
+ }
+ it->second->observers.RemoveObserver(observer);
+ MaybeCleanup(ns);
+}
+
+const PolicyMap* PolicyServiceImpl::GetPolicies(
+ PolicyDomain domain,
+ const std::string& component_id) const {
+ PolicyNamespace ns = std::make_pair(domain, component_id);
+ EntryMap::const_iterator it = entries_.find(ns);
+ return it == entries_.end() ? NULL : &it->second->policies;
+}
+
+void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) {
+ ProviderList::iterator it = GetProviderData(provider);
+ if (it == providers_.end())
+ return;
+ provider->Provide(&(*it)->policies);
+ MergeAndTriggerUpdates();
+}
+
+void PolicyServiceImpl::OnProviderGoingAway(
+ ConfigurationPolicyProvider* provider) {
+ ProviderList::iterator it = GetProviderData(provider);
+ if (it == providers_.end())
+ return;
+ delete *it;
+ providers_.erase(it);
+ MergeAndTriggerUpdates();
+}
+
+PolicyServiceImpl::Entry* PolicyServiceImpl::GetOrCreate(
+ const PolicyNamespace& ns) {
+ Entry*& entry = entries_[ns];
+ if (!entry)
+ entry = new Entry;
+ return entry;
+}
+
+PolicyServiceImpl::ProviderList::iterator PolicyServiceImpl::GetProviderData(
+ ConfigurationPolicyProvider* provider) {
+ for (ProviderList::iterator it = providers_.begin();
+ it != providers_.end(); ++it) {
+ if ((*it)->provider == provider)
+ return it;
+ }
+ NOTREACHED();
+ return providers_.end();
+}
+
+void PolicyServiceImpl::MaybeCleanup(const PolicyNamespace& ns) {
+ EntryMap::iterator it = entries_.find(ns);
+ if (it != entries_.end() &&
+ it->second->policies.empty() &&
+ it->second->observers.size() == 0) {
+ delete it->second;
+ entries_.erase(it);
+ }
+}
+
+void PolicyServiceImpl::MergeAndTriggerUpdates() {
+ // TODO(joaodasilva): do this for each namespace once the providers also
+ // provide policy for more namespaces.
+ PolicyMap new_policies;
+ for (ProviderList::iterator it = providers_.begin();
+ it != providers_.end(); ++it) {
+ new_policies.MergeFrom((*it)->policies);
+ }
+
+ Entry* entry = GetOrCreate(std::make_pair(POLICY_DOMAIN_CHROME, ""));
+ if (!new_policies.Equals(entry->policies)) {
+ entry->policies.Swap(&new_policies);
+ FOR_EACH_OBSERVER(PolicyService::Observer,
+ entry->observers,
+ OnPolicyUpdated(POLICY_DOMAIN_CHROME, ""));
+ }
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/policy_service_impl.h b/chrome/browser/policy/policy_service_impl.h
new file mode 100644
index 0000000..7903938
--- /dev/null
+++ b/chrome/browser/policy/policy_service_impl.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_POLICY_SERVICE_IMPL_H_
+#define CHROME_BROWSER_POLICY_POLICY_SERVICE_IMPL_H_
+#pragma once
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "chrome/browser/policy/configuration_policy_provider.h"
+#include "chrome/browser/policy/policy_map.h"
+#include "chrome/browser/policy/policy_service.h"
+
+namespace policy {
+
+class PolicyServiceImpl : public PolicyService,
+ public ConfigurationPolicyProvider::Observer {
+ public:
+ typedef std::vector<ConfigurationPolicyProvider*> Providers;
+
+ // The PolicyServiceImpl will merge policies from |providers|. |providers|
+ // must be sorted in decreasing order of priority; the first provider will
+ // have the highest priority. The PolicyServiceImpl does not take ownership of
+ // the providers, but handles OnProviderGoingAway() if they are destroyed.
+ explicit PolicyServiceImpl(const Providers& providers);
+ virtual ~PolicyServiceImpl();
+
+ // PolicyService overrides:
+ virtual void AddObserver(PolicyDomain domain,
+ const std::string& component_id,
+ PolicyService::Observer* observer) OVERRIDE;
+
+ virtual void RemoveObserver(PolicyDomain domain,
+ const std::string& component_id,
+ PolicyService::Observer* observer) OVERRIDE;
+
+ virtual const PolicyMap* GetPolicies(
+ PolicyDomain domain,
+ const std::string& component_id) const OVERRIDE;
+
+ private:
+ struct Entry;
+ struct ProviderData;
+
+ typedef std::pair<PolicyDomain, std::string> PolicyNamespace;
+ typedef std::map<PolicyNamespace, Entry*> EntryMap;
+ typedef std::vector<ProviderData*> ProviderList;
+
+ // ConfigurationPolicyProvider::Observer overrides:
+ virtual void OnUpdatePolicy(ConfigurationPolicyProvider* provider) OVERRIDE;
+ virtual void OnProviderGoingAway(
+ ConfigurationPolicyProvider* provider) OVERRIDE;
+
+ Entry* GetOrCreate(const PolicyNamespace& ns);
+ ProviderList::iterator GetProviderData(ConfigurationPolicyProvider* provider);
+
+ // Erases the entry for |ns|, if it has no observers and no policies.
+ void MaybeCleanup(const PolicyNamespace& ns);
+
+ // Combines the policies from all the providers, and notifies the observers
+ // of namespaces whose policies have been modified.
+ void MergeAndTriggerUpdates();
+
+ // Contains all the providers together with a cached copy of their policies
+ // and their registrars.
+ ProviderList providers_;
+
+ // Maps each policy namespace to its current policies.
+ EntryMap entries_;
+
+ DISALLOW_COPY_AND_ASSIGN(PolicyServiceImpl);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_POLICY_SERVICE_IMPL_H_
diff --git a/chrome/browser/policy/policy_service_unittest.cc b/chrome/browser/policy/policy_service_unittest.cc
new file mode 100644
index 0000000..ad99a7b
--- /dev/null
+++ b/chrome/browser/policy/policy_service_unittest.cc
@@ -0,0 +1,153 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/policy_service_impl.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chrome/browser/policy/mock_configuration_policy_provider.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::AnyNumber;
+using ::testing::Mock;
+using ::testing::_;
+
+namespace policy {
+
+namespace {
+
+class MockPolicyServiceObserver : public PolicyService::Observer {
+ public:
+ virtual ~MockPolicyServiceObserver() {}
+ MOCK_METHOD2(OnPolicyUpdated, void(PolicyDomain, const std::string&));
+};
+
+class PolicyServiceTest : public testing::Test {
+ public:
+ PolicyServiceTest() {}
+
+ void SetUp() OVERRIDE {
+ provider0_.AddMandatoryPolicy("pre", base::Value::CreateIntegerValue(13));
+ provider0_.SetInitializationComplete(true);
+ provider1_.SetInitializationComplete(true);
+ provider2_.SetInitializationComplete(true);
+ PolicyServiceImpl::Providers providers;
+ providers.push_back(&provider0_);
+ providers.push_back(&provider1_);
+ providers.push_back(&provider2_);
+ policy_service_.reset(new PolicyServiceImpl(providers));
+ policy_service_->AddObserver(POLICY_DOMAIN_CHROME, "", &observer_);
+ }
+
+ void TearDown() OVERRIDE {
+ policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, "", &observer_);
+ }
+
+ // Returns true if the policies for |domain|, |component_id| match |expected|.
+ bool VerifyPolicies(PolicyDomain domain,
+ const std::string& component_id,
+ const PolicyMap& expected) {
+ const PolicyMap* policies =
+ policy_service_->GetPolicies(domain, component_id);
+ return policies && policies->Equals(expected);
+ }
+
+ protected:
+ MockConfigurationPolicyProvider provider0_;
+ MockConfigurationPolicyProvider provider1_;
+ MockConfigurationPolicyProvider provider2_;
+ scoped_ptr<PolicyServiceImpl> policy_service_;
+ MockPolicyServiceObserver observer_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PolicyServiceTest);
+};
+
+TEST_F(PolicyServiceTest, LoadsPoliciesBeforeProvidersRefresh) {
+ PolicyMap expected;
+ expected.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(13));
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+}
+
+TEST_F(PolicyServiceTest, NotifyObservers) {
+ PolicyMap expected;
+ expected.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(13));
+
+ expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(123));
+ provider0_.AddMandatoryPolicy("aaa", base::Value::CreateIntegerValue(123));
+ EXPECT_CALL(observer_, OnPolicyUpdated(POLICY_DOMAIN_CHROME, "")).Times(1);
+ provider0_.RefreshPolicies();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+ // No changes.
+ EXPECT_CALL(observer_, OnPolicyUpdated(_, _)).Times(0);
+ provider0_.RefreshPolicies();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+ // New policy.
+ expected.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(456));
+ provider0_.AddMandatoryPolicy("bbb", base::Value::CreateIntegerValue(456));
+ EXPECT_CALL(observer_, OnPolicyUpdated(POLICY_DOMAIN_CHROME, "")).Times(1);
+ provider0_.RefreshPolicies();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+ // Removed policy.
+ expected.Erase("bbb");
+ provider0_.RemovePolicy("bbb");
+ EXPECT_CALL(observer_, OnPolicyUpdated(POLICY_DOMAIN_CHROME, "")).Times(1);
+ provider0_.RefreshPolicies();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+ // Changed policy.
+ expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(789));
+ provider0_.AddMandatoryPolicy("aaa", base::Value::CreateIntegerValue(789));
+ EXPECT_CALL(observer_, OnPolicyUpdated(POLICY_DOMAIN_CHROME, "")).Times(1);
+ provider0_.RefreshPolicies();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+ // No changes again.
+ EXPECT_CALL(observer_, OnPolicyUpdated(_, _)).Times(0);
+ provider0_.RefreshPolicies();
+ Mock::VerifyAndClearExpectations(&observer_);
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+}
+
+TEST_F(PolicyServiceTest, Priorities) {
+ PolicyMap expected;
+ expected.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(13));
+ EXPECT_CALL(observer_, OnPolicyUpdated(_, _)).Times(AnyNumber());
+
+ expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(0));
+ provider0_.AddMandatoryPolicy("aaa", base::Value::CreateIntegerValue(0));
+ provider1_.AddMandatoryPolicy("aaa", base::Value::CreateIntegerValue(1));
+ provider2_.AddMandatoryPolicy("aaa", base::Value::CreateIntegerValue(2));
+ provider0_.RefreshPolicies();
+ provider1_.RefreshPolicies();
+ provider2_.RefreshPolicies();
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+
+ expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(1));
+ provider0_.RemovePolicy("aaa");
+ provider0_.RefreshPolicies();
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+
+ expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ base::Value::CreateIntegerValue(2));
+ provider1_.AddRecommendedPolicy("aaa", base::Value::CreateIntegerValue(1));
+ provider1_.RefreshPolicies();
+ EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected));
+}
+
+} // namespace
+
+} // namespace policy
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 8f59c18..1aa03a3 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1890,6 +1890,9 @@
'browser/policy/policy_path_parser_mac.mm',
'browser/policy/policy_path_parser_linux.cc',
'browser/policy/policy_path_parser_win.cc',
+ 'browser/policy/policy_service.h',
+ 'browser/policy/policy_service_impl.cc',
+ 'browser/policy/policy_service_impl.h',
'browser/policy/policy_status_info.cc',
'browser/policy/policy_status_info.h',
'browser/policy/url_blacklist_manager.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 2129fb2..0cb1b43 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1595,6 +1595,7 @@
'browser/policy/network_configuration_updater_unittest.cc',
'browser/policy/policy_map_unittest.cc',
'browser/policy/policy_path_parser_unittest.cc',
+ 'browser/policy/policy_service_unittest.cc',
'browser/policy/testing_cloud_policy_subsystem.cc',
'browser/policy/testing_cloud_policy_subsystem.h',
'browser/policy/testing_policy_url_fetcher_factory.cc',
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index ef97f73..6a949e7 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/google/google_url_tracker.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/policy_service_impl.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prerender/prerender_tracker.h"
#include "chrome/browser/printing/background_printing_manager.h"
@@ -69,6 +70,23 @@ policy::BrowserPolicyConnector*
return browser_policy_connector_.get();
}
+policy::PolicyService* TestingBrowserProcess::policy_service() {
+ policy::PolicyService* service = NULL;
+#if defined(ENABLE_CONFIGURATION_POLICY)
+ policy::BrowserPolicyConnector* connector = browser_policy_connector();
+ if (connector)
+ service = connector->GetPolicyService();
+#else
+ // Return a dummy instance that doesn't serve any policies.
+ if (!policy_service_.get()) {
+ policy::PolicyService::Providers emptyProviders;
+ policy_service_.reset(new policy::PolicyServiceImpl(emptyProviders));
+ }
+ return policy_service_.get();
+#endif
+ return service;
+}
+
IconManager* TestingBrowserProcess::icon_manager() {
return NULL;
}
diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h
index db62178..8853df6 100644
--- a/chrome/test/base/testing_browser_process.h
+++ b/chrome/test/base/testing_browser_process.h
@@ -32,6 +32,7 @@ class NotificationService;
namespace policy {
class BrowserPolicyConnector;
+class PolicyService;
}
namespace prerender {
@@ -55,6 +56,7 @@ class TestingBrowserProcess : public BrowserProcess {
virtual ProfileManager* profile_manager() OVERRIDE;
virtual PrefService* local_state() OVERRIDE;
virtual policy::BrowserPolicyConnector* browser_policy_connector() OVERRIDE;
+ virtual policy::PolicyService* policy_service() OVERRIDE;
virtual IconManager* icon_manager() OVERRIDE;
virtual ThumbnailGenerator* GetThumbnailGenerator() OVERRIDE;
virtual TabCloseableStateWatcher* tab_closeable_state_watcher() OVERRIDE;
@@ -123,6 +125,7 @@ class TestingBrowserProcess : public BrowserProcess {
// Weak pointer.
PrefService* local_state_;
scoped_ptr<policy::BrowserPolicyConnector> browser_policy_connector_;
+ scoped_ptr<policy::PolicyService> policy_service_;
scoped_ptr<GoogleURLTracker> google_url_tracker_;
scoped_ptr<ProfileManager> profile_manager_;
scoped_ptr<NotificationUIManager> notification_ui_manager_;