Chromium Code Reviews| Index: chrome/browser/policy/configuration_policy_reader.cc |
| diff --git a/chrome/browser/policy/configuration_policy_reader.cc b/chrome/browser/policy/configuration_policy_reader.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..bc1a2f57b51d3e8b48850e68ee848436effb48a9 |
| --- /dev/null |
| +++ b/chrome/browser/policy/configuration_policy_reader.cc |
| @@ -0,0 +1,274 @@ |
| +// Copyright (c) 2011 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_reader.h" |
| + |
| +#include <map> |
| +#include <set> |
| +#include <vector> |
| + |
| +#include "base/utf_string_conversions.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/policy/browser_policy_connector.h" |
| +#include "chrome/browser/policy/configuration_policy_pref_store.h" |
| +#include "chrome/browser/policy/configuration_policy_store_interface.h" |
| + |
| +namespace policy { |
| + |
| +// This class functions as a container for policy status information used by the |
| +// ConfigurationPolicyReader class. It obtains policy values from a |
| +// ConfigurationPolicyProvider and maps them to their status information. |
| +class ConfigurationPolicyStatusKeeper |
| + : public ConfigurationPolicyStoreInterface { |
| + public: |
|
Mattias Nissler (ping if slow)
2011/08/12 09:42:05
indentation
simo
2011/08/16 17:36:34
Done.
|
| + ConfigurationPolicyStatusKeeper(ConfigurationPolicyProvider* provider, |
| + PolicyStatusInfo::PolicyLevel policy_level); |
| + virtual ~ConfigurationPolicyStatusKeeper(); |
| + |
| + // ConfigurationPolicyStoreInterface methods. |
| + virtual void Apply(ConfigurationPolicyType policy, base::Value* value); |
| + |
| + // Returns a pointer to a DictionaryValue containing the status information |
| + // of the policy |policy|. The caller acquires ownership of the returned |
| + // value. Returns NULL if no such policy is stored in this keeper. |
| + DictionaryValue* GetPolicyStatus(ConfigurationPolicyType policy) const; |
| + |
| + private: |
| + typedef std::map<ConfigurationPolicyType, PolicyStatusInfo> |
| + PolicyStatusMapType; |
|
Mattias Nissler (ping if slow)
2011/08/12 09:42:05
you can remove the Type suffix, we usually don't p
simo
2011/08/16 17:36:34
Done.
|
| + typedef std::map<ConfigurationPolicyType, string16> PolicyNameMapType; |
| + typedef ConfigurationPolicyProvider::PolicyDefinitionList |
| + PolicyDefinitionList; |
| + |
| + // Mapping from ConfigurationPolicyType to PolicyStatusInfo. |
| + PolicyStatusMapType policy_map_; |
| + |
| + // Mapping from ConfigurationPolicyType to policy names. |
| + PolicyNameMapType policy_name_map_; |
| + |
| + // The level of the policies stored in this keeper (mandatory or |
| + // recommended). |
| + PolicyStatusInfo::PolicyLevel policy_level_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyStatusKeeper); |
| +}; |
| + |
| +// ConfigurationPolicyStatusKeeper |
| +ConfigurationPolicyStatusKeeper::ConfigurationPolicyStatusKeeper( |
| + ConfigurationPolicyProvider* provider, |
| + PolicyStatusInfo::PolicyLevel policy_level) : policy_level_(policy_level) { |
| + const PolicyDefinitionList* policy_definition_list = |
| + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); |
|
Mattias Nissler (ping if slow)
2011/08/12 09:42:05
I think you should get this pointer from the provi
simo
2011/08/16 17:36:34
Done.
|
| + |
| + // Create a mapping from ConfigurationPolicyTypes to actual policy names. |
|
Mattias Nissler (ping if slow)
2011/08/12 09:42:05
Hm, so we do this and store the mapping for every
simo
2011/08/16 17:36:34
I have added a static method to PolicyStatus that
|
| + const PolicyDefinitionList::Entry* entry = policy_definition_list->begin; |
| + for ( ; entry != policy_definition_list->end; ++entry) |
| + policy_name_map_[entry->policy_type] = ASCIIToUTF16(entry->name); |
| + |
| + if (!provider->Provide(this)) |
| + LOG(WARNING) << "Failed to get policy from provider."; |
| +} |
| + |
| +ConfigurationPolicyStatusKeeper::~ConfigurationPolicyStatusKeeper() { |
| + policy_map_.clear(); |
| + policy_name_map_.clear(); |
| +} |
| + |
| +void ConfigurationPolicyStatusKeeper::Apply( |
| + ConfigurationPolicyType policy, base::Value* value) { |
| + |
|
Mattias Nissler (ping if slow)
2011/08/12 09:42:05
no newline
simo
2011/08/16 17:36:34
Done.
|
| + PolicyNameMapType::const_iterator entry = policy_name_map_.find(policy); |
| + |
| + // This should never happen. |
| + if (entry == policy_name_map_.end()) { |
| + LOG(WARNING) << "Received unknown policy from provider."; |
| + return; |
| + } |
| + |
| + // TODO(simo) actually determine whether the policy is a user or a device one |
| + // and whether the policy could be enforced or not once this information |
| + // is available. |
| + PolicyStatusInfo info(entry->second, |
| + PolicyStatusInfo::USER, |
| + policy_level_, |
| + value, |
| + PolicyStatusInfo::ENFORCED, |
| + string16()); |
| + policy_map_[policy] = info; |
| +} |
| + |
| +DictionaryValue* ConfigurationPolicyStatusKeeper::GetPolicyStatus( |
| + ConfigurationPolicyType policy) const { |
| + PolicyStatusMapType::const_iterator entry = policy_map_.find(policy); |
| + return entry != policy_map_.end() ? |
| + (entry->second).GetDictionaryValue() : NULL; |
| +} |
| + |
| +// ConfigurationPolicyReader |
| +ConfigurationPolicyReader::~ConfigurationPolicyReader() { |
| +} |
| + |
| +bool ConfigurationPolicyReader::IsInitializationComplete() const { |
|
Mattias Nissler (ping if slow)
2011/08/12 09:42:05
Do you actually need that whole initialization com
simo
2011/08/16 17:36:34
Done.
|
| + return initialization_complete_; |
| +} |
| + |
| +void ConfigurationPolicyReader::OnUpdatePolicy() { |
| + Refresh(); |
| +} |
| + |
| +void ConfigurationPolicyReader::OnProviderGoingAway() { |
| + provider_ = NULL; |
| +} |
| + |
| +// static |
| +ConfigurationPolicyReader* |
| + ConfigurationPolicyReader::CreateManagedPlatformPolicyReader( |
| + PolicyStatusInfo::PolicyLevel policy_level) { |
| + BrowserPolicyConnector* connector = |
|
Mattias Nissler (ping if slow)
2011/08/12 09:42:05
indentation
simo
2011/08/16 17:36:34
Done.
|
| + g_browser_process->browser_policy_connector(); |
| + return new ConfigurationPolicyReader( |
| + connector->GetManagedPlatformProvider(), policy_level); |
| +} |
| + |
| +// static |
| +ConfigurationPolicyReader* |
| + ConfigurationPolicyReader::CreateManagedCloudPolicyReader( |
| + PolicyStatusInfo::PolicyLevel policy_level) { |
| + BrowserPolicyConnector* connector = |
| + g_browser_process->browser_policy_connector(); |
| + return new ConfigurationPolicyReader( |
| + connector->GetManagedCloudProvider(), policy_level); |
| +} |
| + |
| +// static |
| +ConfigurationPolicyReader* |
| + ConfigurationPolicyReader::CreateRecommendedPlatformPolicyReader( |
| + PolicyStatusInfo::PolicyLevel policy_level) { |
| + BrowserPolicyConnector* connector = |
| + g_browser_process->browser_policy_connector(); |
| + return new ConfigurationPolicyReader( |
| + connector->GetRecommendedPlatformProvider(), policy_level); |
| +} |
| + |
| +// static |
| +ConfigurationPolicyReader* |
| + ConfigurationPolicyReader::CreateRecommendedCloudPolicyReader( |
| + PolicyStatusInfo::PolicyLevel policy_level) { |
| + BrowserPolicyConnector* connector = |
| + g_browser_process->browser_policy_connector(); |
| + return new ConfigurationPolicyReader( |
| + connector->GetRecommendedCloudProvider(), policy_level); |
| +} |
| + |
| +DictionaryValue* ConfigurationPolicyReader::GetPolicyStatus( |
| + ConfigurationPolicyType policy) const { |
| + return policy_keeper_->GetPolicyStatus(policy); |
| +} |
| + |
| +ConfigurationPolicyReader::ConfigurationPolicyReader( |
| + ConfigurationPolicyProvider* provider, |
| + PolicyStatusInfo::PolicyLevel policy_level) |
| + : provider_(provider), |
| + initialization_complete_(false), |
| + policy_level_(policy_level) { |
| + if (provider_) { |
| + // Read initial policy. |
| + policy_keeper_.reset( |
| + new ConfigurationPolicyStatusKeeper(provider, policy_level)); |
| + registrar_.Init(provider_, this); |
| + initialization_complete_ = provider->IsInitializationComplete(); |
| + } else { |
| + initialization_complete_ = true; |
| + } |
| +} |
| + |
| +void ConfigurationPolicyReader::Refresh() { |
| + if (!provider_) |
|
Mattias Nissler (ping if slow)
2011/08/12 09:42:05
indentation
simo
2011/08/16 17:36:34
Done.
|
| + return; |
| + |
| + // Read policy state into a new keeper and swap out old keeper. |
| + scoped_ptr<ConfigurationPolicyStatusKeeper> new_keeper( |
| + new ConfigurationPolicyStatusKeeper(provider_, policy_level_)); |
| + policy_keeper_.reset(new_keeper.release()); |
| + |
| + // TODO(simo) create an observer class which PolicyStatus can implement so |
| + // that it can be notified of changes. |
| +} |
| + |
| +// PolicyStatus |
| +PolicyStatus::PolicyStatus() { |
| + managed_platform_.reset( |
| + ConfigurationPolicyReader::CreateManagedPlatformPolicyReader( |
| + PolicyStatusInfo::MANDATORY)); |
| + managed_cloud_.reset( |
| + ConfigurationPolicyReader::CreateManagedCloudPolicyReader( |
| + PolicyStatusInfo::MANDATORY)); |
| + recommended_platform_.reset( |
| + ConfigurationPolicyReader::CreateRecommendedPlatformPolicyReader( |
| + PolicyStatusInfo::RECOMMENDED)); |
| + recommended_cloud_.reset( |
| + ConfigurationPolicyReader::CreateRecommendedCloudPolicyReader( |
| + PolicyStatusInfo::RECOMMENDED)); |
| +} |
| + |
| +PolicyStatus::~PolicyStatus() { |
| +} |
| + |
| +ListValue* PolicyStatus::GetPolicyStatusList(bool& any_policies_sent) const { |
| + ListValue* result = new ListValue(); |
| + std::vector<PolicyStatusInfo> unsent_policies; |
| + |
| + any_policies_sent = false; |
| + const PolicyDefinitionList* supported_policies = |
| + ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); |
| + const PolicyDefinitionList::Entry* policy = supported_policies->begin; |
| + for ( ; policy != supported_policies->end; ++policy) { |
| + if (!AddPolicyFromReaders(policy->policy_type, result)) { |
| + PolicyStatusInfo info(ASCIIToUTF16(policy->name), |
| + PolicyStatusInfo::SOURCE_TYPE_UNDEFINED, |
| + PolicyStatusInfo::LEVEL_UNDEFINED, |
| + Value::CreateNullValue(), |
| + PolicyStatusInfo::STATUS_UNDEFINED, |
| + string16()); |
| + unsent_policies.push_back(info); |
| + } else { |
| + any_policies_sent = true; |
| + } |
| + } |
| + |
| + // Add policies that weren't actually sent from providers to list. |
| + std::vector<PolicyStatusInfo>::const_iterator info = unsent_policies.begin(); |
| + for ( ; info != unsent_policies.end(); ++info) |
| + result->Append((*info).GetDictionaryValue()); |
| + |
| + unsent_policies.clear(); |
| + return result; |
| +} |
| + |
| +bool PolicyStatus::AddPolicyFromReaders( |
| + ConfigurationPolicyType policy, ListValue* list) const { |
| + DictionaryValue* mp_policy = |
| + managed_platform_->GetPolicyStatus(policy); |
| + DictionaryValue* mc_policy = |
| + managed_cloud_->GetPolicyStatus(policy); |
| + DictionaryValue* rp_policy = |
| + recommended_platform_->GetPolicyStatus(policy); |
| + DictionaryValue* rc_policy = |
| + recommended_cloud_->GetPolicyStatus(policy); |
| + |
| + bool added_policy = mp_policy || mc_policy || rp_policy || rc_policy; |
| + |
| + if (mp_policy) |
| + list->Append(mp_policy); |
| + if (mc_policy) |
| + list->Append(mc_policy); |
| + if (rp_policy) |
| + list->Append(rp_policy); |
| + if (rc_policy) |
| + list->Append(rc_policy); |
| + |
| + return added_policy; |
| +} |
| + |
| +} // namespace policy |