diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-09 18:14:21 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-09 18:14:21 +0000 |
commit | a4179c2ab89873eb1aaf999bd67185568ed0a7eb (patch) | |
tree | e4a09652fae0190e51fa938a7dfe9a46bca751cd | |
parent | c033c5087d504ce089ec51763292b11bc1c6850d (diff) | |
download | chromium_src-a4179c2ab89873eb1aaf999bd67185568ed0a7eb.zip chromium_src-a4179c2ab89873eb1aaf999bd67185568ed0a7eb.tar.gz chromium_src-a4179c2ab89873eb1aaf999bd67185568ed0a7eb.tar.bz2 |
Introduced the PolicyService.
The PolicyService is owned by the BrowserPolicyConnector, and isn't yet used
anywhere. The next step is to make the ConfigurationPolicyPrefStores get their
policies from the PolicyService instead of the providers directly. The providers
then can also be modified to provide both mandatory and recommended policies,
and 3rd party policies.
BUG=108999
TEST=All works as before; unit_tests green
Review URL: http://codereview.chromium.org/9325066
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121249 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser_process.h | 6 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 14 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.h | 3 | ||||
-rw-r--r-- | chrome/browser/policy/browser_policy_connector.cc | 13 | ||||
-rw-r--r-- | chrome/browser/policy/browser_policy_connector.h | 6 | ||||
-rw-r--r-- | chrome/browser/policy/policy_service.h | 59 | ||||
-rw-r--r-- | chrome/browser/policy/policy_service_impl.cc | 136 | ||||
-rw-r--r-- | chrome/browser/policy/policy_service_impl.h | 81 | ||||
-rw-r--r-- | chrome/browser/policy/policy_service_unittest.cc | 153 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 3 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rw-r--r-- | chrome/test/base/testing_browser_process.cc | 18 | ||||
-rw-r--r-- | chrome/test/base/testing_browser_process.h | 3 |
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_; |