1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "components/policy/core/browser/configuration_policy_pref_store.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/bind.h" 11 #include "base/logging.h" 12 #include "base/message_loop/message_loop.h" 13 #include "base/prefs/pref_value_map.h" 14 #include "base/strings/string16.h" 15 #include "base/strings/utf_string_conversions.h" 16 #include "components/policy/core/browser/configuration_policy_handler_list.h" 17 #include "components/policy/core/browser/policy_error_map.h" 18 19 namespace policy { 20 21 namespace { 22 23 // Policies are loaded early on startup, before PolicyErrorMaps are ready to 24 // be retrieved. This function is posted to UI to log any errors found on 25 // Refresh below. 26 void LogErrors(PolicyErrorMap* errors) { 27 PolicyErrorMap::const_iterator iter; 28 for (iter = errors->begin(); iter != errors->end(); ++iter) { 29 base::string16 policy = base::ASCIIToUTF16(iter->first); 30 DLOG(WARNING) << "Policy " << policy << ": " << iter->second; 31 } 32 } 33 34 } // namespace 35 36 ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( 37 PolicyService* service, 38 const ConfigurationPolicyHandlerList* handler_list, 39 PolicyLevel level) 40 : policy_service_(service), 41 handler_list_(handler_list), 42 level_(level) { 43 // Read initial policy. 44 prefs_.reset(CreatePreferencesFromPolicies()); 45 policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this); 46 } 47 48 void ConfigurationPolicyPrefStore::AddObserver(PrefStore::Observer* observer) { 49 observers_.AddObserver(observer); 50 } 51 52 void ConfigurationPolicyPrefStore::RemoveObserver( 53 PrefStore::Observer* observer) { 54 observers_.RemoveObserver(observer); 55 } 56 57 bool ConfigurationPolicyPrefStore::HasObservers() const { 58 return observers_.might_have_observers(); 59 } 60 61 bool ConfigurationPolicyPrefStore::IsInitializationComplete() const { 62 return policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME); 63 } 64 65 bool ConfigurationPolicyPrefStore::GetValue(const std::string& key, 66 const base::Value** value) const { 67 const base::Value* stored_value = NULL; 68 if (!prefs_.get() || !prefs_->GetValue(key, &stored_value)) 69 return false; 70 71 if (value) 72 *value = stored_value; 73 return true; 74 } 75 76 void ConfigurationPolicyPrefStore::OnPolicyUpdated( 77 const PolicyNamespace& ns, 78 const PolicyMap& previous, 79 const PolicyMap& current) { 80 DCHECK_EQ(POLICY_DOMAIN_CHROME, ns.domain); 81 DCHECK(ns.component_id.empty()); 82 Refresh(); 83 } 84 85 void ConfigurationPolicyPrefStore::OnPolicyServiceInitialized( 86 PolicyDomain domain) { 87 if (domain == POLICY_DOMAIN_CHROME) { 88 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, 89 OnInitializationCompleted(true)); 90 } 91 } 92 93 ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() { 94 policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this); 95 } 96 97 void ConfigurationPolicyPrefStore::Refresh() { 98 scoped_ptr<PrefValueMap> new_prefs(CreatePreferencesFromPolicies()); 99 std::vector<std::string> changed_prefs; 100 new_prefs->GetDifferingKeys(prefs_.get(), &changed_prefs); 101 prefs_.swap(new_prefs); 102 103 // Send out change notifications. 104 for (std::vector<std::string>::const_iterator pref(changed_prefs.begin()); 105 pref != changed_prefs.end(); 106 ++pref) { 107 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, 108 OnPrefValueChanged(*pref)); 109 } 110 } 111 112 PrefValueMap* ConfigurationPolicyPrefStore::CreatePreferencesFromPolicies() { 113 scoped_ptr<PrefValueMap> prefs(new PrefValueMap); 114 PolicyMap filtered_policies; 115 filtered_policies.CopyFrom(policy_service_->GetPolicies( 116 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))); 117 filtered_policies.FilterLevel(level_); 118 119 scoped_ptr<PolicyErrorMap> errors(new PolicyErrorMap); 120 121 handler_list_->ApplyPolicySettings(filtered_policies, 122 prefs.get(), 123 errors.get()); 124 125 // Retrieve and log the errors once the UI loop is ready. This is only an 126 // issue during startup. 127 base::MessageLoop::current()->PostTask( 128 FROM_HERE, base::Bind(&LogErrors, base::Owned(errors.release()))); 129 130 return prefs.release(); 131 } 132 133 } // namespace policy 134