Home | History | Annotate | Download | only in browser
      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