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
134
135
136
137
138
139
140
141
142
143
144
145
146
|
// 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_provider.h"
#include <string>
#include "chrome/browser/policy/policy_map.h"
#include "policy/policy_constants.h"
namespace policy {
namespace {
const char* kProxyPolicies[] = {
key::kProxyMode,
key::kProxyServerMode,
key::kProxyServer,
key::kProxyPacUrl,
key::kProxyBypassList,
};
// Helper that converts deprecated chrome policies into their corresponding
// actual policies.
void FixDeprecatedPolicies(PolicyMap* policies) {
// Proxy settings have been configured by 5 policies that didn't mix well
// together, and maps of policies had to take this into account when merging
// policy sources. The proxy settings will eventually be configured by a
// single Dictionary policy when all providers have support for that. For
// now, the individual policies are mapped here to a single Dictionary policy
// that the rest of the policy machinery uses.
// The highest (level, scope) pair for an existing proxy policy is determined
// first, and then only policies with those exact attributes are merged.
PolicyMap::Entry current_priority; // Defaults to the lowest priority.
scoped_ptr<DictionaryValue> proxy_settings(new DictionaryValue);
for (size_t i = 0; i < arraysize(kProxyPolicies); ++i) {
const PolicyMap::Entry* entry = policies->Get(kProxyPolicies[i]);
if (entry) {
if (entry->has_higher_priority_than(current_priority)) {
proxy_settings->Clear();
current_priority = *entry;
}
if (!entry->has_higher_priority_than(current_priority) &&
!current_priority.has_higher_priority_than(*entry)) {
proxy_settings->Set(kProxyPolicies[i], entry->value->DeepCopy());
}
policies->Erase(kProxyPolicies[i]);
}
}
// Sets the new |proxy_settings| if kProxySettings isn't set yet, or if the
// new priority is higher.
const PolicyMap::Entry* existing = policies->Get(key::kProxySettings);
if (!proxy_settings->empty() &&
(!existing || current_priority.has_higher_priority_than(*existing))) {
policies->Set(key::kProxySettings,
current_priority.level,
current_priority.scope,
proxy_settings.release());
}
}
} // namespace
ConfigurationPolicyProvider::Observer::~Observer() {}
void ConfigurationPolicyProvider::Observer::OnProviderGoingAway(
ConfigurationPolicyProvider* provider) {}
ConfigurationPolicyProvider::ConfigurationPolicyProvider() {}
ConfigurationPolicyProvider::~ConfigurationPolicyProvider() {
FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
observer_list_,
OnProviderGoingAway(this));
}
bool ConfigurationPolicyProvider::IsInitializationComplete() const {
return true;
}
void ConfigurationPolicyProvider::UpdatePolicy(
scoped_ptr<PolicyBundle> bundle) {
if (bundle.get())
policy_bundle_.Swap(bundle.get());
else
policy_bundle_.Clear();
FixDeprecatedPolicies(
&policy_bundle_.Get(POLICY_DOMAIN_CHROME, std::string()));
FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
observer_list_,
OnUpdatePolicy(this));
}
void ConfigurationPolicyProvider::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void ConfigurationPolicyProvider::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
ConfigurationPolicyObserverRegistrar::ConfigurationPolicyObserverRegistrar()
: provider_(NULL),
observer_(NULL) {}
ConfigurationPolicyObserverRegistrar::~ConfigurationPolicyObserverRegistrar() {
// Subtle: see the comment in OnProviderGoingAway().
if (observer_)
provider_->RemoveObserver(this);
}
void ConfigurationPolicyObserverRegistrar::Init(
ConfigurationPolicyProvider* provider,
ConfigurationPolicyProvider::Observer* observer) {
// Must be either both NULL or both not NULL.
DCHECK(provider);
DCHECK(observer);
provider_ = provider;
observer_ = observer;
provider_->AddObserver(this);
}
void ConfigurationPolicyObserverRegistrar::OnUpdatePolicy(
ConfigurationPolicyProvider* provider) {
DCHECK_EQ(provider_, provider);
observer_->OnUpdatePolicy(provider_);
}
void ConfigurationPolicyObserverRegistrar::OnProviderGoingAway(
ConfigurationPolicyProvider* provider) {
DCHECK_EQ(provider_, provider);
// The |observer_| might delete |this| during this callback: don't touch any
// of |this| field's after it returns.
// It might also invoke provider() during this callback, so |provider_| can't
// be set to NULL. So we set |observer_| to NULL instead to signal that
// we're not observing the provider anymore.
ConfigurationPolicyProvider::Observer* observer = observer_;
observer_ = NULL;
provider_->RemoveObserver(this);
observer->OnProviderGoingAway(provider);
}
} // namespace policy
|