summaryrefslogtreecommitdiffstats
path: root/chrome/browser/policy/configuration_policy_pref_store.cc
blob: 9c5e2214b6f7e51bfea958da2a15d3c2ed2fff72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// 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/configuration_policy_pref_store.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_value_map.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/policy/configuration_policy_handler_list.h"
#include "components/policy/core/browser/policy_error_map.h"

namespace policy {

namespace {

// Policies are loaded early on startup, before PolicyErrorMaps are ready to
// be retrieved. This function is posted to UI to log any errors found on
// Refresh below.
void LogErrors(PolicyErrorMap* errors) {
  PolicyErrorMap::const_iterator iter;
  for (iter = errors->begin(); iter != errors->end(); ++iter) {
    string16 policy = ASCIIToUTF16(iter->first);
    DLOG(WARNING) << "Policy " << policy << ": " << iter->second;
  }
}

}  // namespace

ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore(
    PolicyService* service,
    const ConfigurationPolicyHandlerList* handler_list,
    PolicyLevel level)
    : policy_service_(service),
      handler_list_(handler_list),
      level_(level) {
  // Read initial policy.
  prefs_.reset(CreatePreferencesFromPolicies());
  policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
}

void ConfigurationPolicyPrefStore::AddObserver(PrefStore::Observer* observer) {
  observers_.AddObserver(observer);
}

void ConfigurationPolicyPrefStore::RemoveObserver(
    PrefStore::Observer* observer) {
  observers_.RemoveObserver(observer);
}

bool ConfigurationPolicyPrefStore::HasObservers() const {
  return observers_.might_have_observers();
}

bool ConfigurationPolicyPrefStore::IsInitializationComplete() const {
  return policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME);
}

bool ConfigurationPolicyPrefStore::GetValue(const std::string& key,
                                            const Value** value) const {
  const Value* stored_value = NULL;
  if (!prefs_.get() || !prefs_->GetValue(key, &stored_value))
    return false;

  if (value)
    *value = stored_value;
  return true;
}

void ConfigurationPolicyPrefStore::OnPolicyUpdated(
    const PolicyNamespace& ns,
    const PolicyMap& previous,
    const PolicyMap& current) {
  DCHECK_EQ(POLICY_DOMAIN_CHROME, ns.domain);
  DCHECK(ns.component_id.empty());
  Refresh();
}

void ConfigurationPolicyPrefStore::OnPolicyServiceInitialized(
    PolicyDomain domain) {
  if (domain == POLICY_DOMAIN_CHROME) {
    FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
                      OnInitializationCompleted(true));
  }
}

ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {
  policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
}

void ConfigurationPolicyPrefStore::Refresh() {
  scoped_ptr<PrefValueMap> new_prefs(CreatePreferencesFromPolicies());
  std::vector<std::string> changed_prefs;
  new_prefs->GetDifferingKeys(prefs_.get(), &changed_prefs);
  prefs_.swap(new_prefs);

  // Send out change notifications.
  for (std::vector<std::string>::const_iterator pref(changed_prefs.begin());
       pref != changed_prefs.end();
       ++pref) {
    FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
                      OnPrefValueChanged(*pref));
  }
}

PrefValueMap* ConfigurationPolicyPrefStore::CreatePreferencesFromPolicies() {
  scoped_ptr<PrefValueMap> prefs(new PrefValueMap);
  PolicyMap filtered_policies;
  filtered_policies.CopyFrom(policy_service_->GetPolicies(
      PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())));
  filtered_policies.FilterLevel(level_);

  scoped_ptr<PolicyErrorMap> errors(new PolicyErrorMap);

  handler_list_->ApplyPolicySettings(filtered_policies,
                                     prefs.get(),
                                     errors.get());

  // Retrieve and log the errors once the UI loop is ready. This is only an
  // issue during startup.
  base::MessageLoop::current()->PostTask(
      FROM_HERE, base::Bind(&LogErrors, base::Owned(errors.release())));

  return prefs.release();
}

}  // namespace policy