OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/policy/core/common/schema_registry.h" | 5 #include "components/policy/core/common/schema_registry.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 | 8 |
9 namespace policy { | 9 namespace policy { |
10 | 10 |
11 SchemaRegistry::Observer::~Observer() {} | 11 SchemaRegistry::Observer::~Observer() {} |
12 | 12 |
| 13 SchemaRegistry::InternalObserver::~InternalObserver() {} |
| 14 |
13 SchemaRegistry::SchemaRegistry() : schema_map_(new SchemaMap) { | 15 SchemaRegistry::SchemaRegistry() : schema_map_(new SchemaMap) { |
14 for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i) | 16 for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i) |
15 domains_ready_[i] = false; | 17 domains_ready_[i] = false; |
16 #if !defined(ENABLE_EXTENSIONS) | 18 #if !defined(ENABLE_EXTENSIONS) |
17 domains_ready_[POLICY_DOMAIN_EXTENSIONS] = true; | 19 domains_ready_[POLICY_DOMAIN_EXTENSIONS] = true; |
18 #endif | 20 #endif |
19 } | 21 } |
20 | 22 |
21 SchemaRegistry::~SchemaRegistry() {} | 23 SchemaRegistry::~SchemaRegistry() { |
| 24 FOR_EACH_OBSERVER(InternalObserver, |
| 25 internal_observers_, |
| 26 OnSchemaRegistryShuttingDown(this)); |
| 27 } |
22 | 28 |
23 void SchemaRegistry::RegisterComponent(const PolicyNamespace& ns, | 29 void SchemaRegistry::RegisterComponent(const PolicyNamespace& ns, |
24 const Schema& schema) { | 30 const Schema& schema) { |
25 ComponentMap map; | 31 ComponentMap map; |
26 map[ns.component_id] = schema; | 32 map[ns.component_id] = schema; |
27 RegisterComponents(ns.domain, map); | 33 RegisterComponents(ns.domain, map); |
28 } | 34 } |
29 | 35 |
30 void SchemaRegistry::RegisterComponents(PolicyDomain domain, | 36 void SchemaRegistry::RegisterComponents(PolicyDomain domain, |
31 const ComponentMap& components) { | 37 const ComponentMap& components) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 } | 76 } |
71 | 77 |
72 void SchemaRegistry::AddObserver(Observer* observer) { | 78 void SchemaRegistry::AddObserver(Observer* observer) { |
73 observers_.AddObserver(observer); | 79 observers_.AddObserver(observer); |
74 } | 80 } |
75 | 81 |
76 void SchemaRegistry::RemoveObserver(Observer* observer) { | 82 void SchemaRegistry::RemoveObserver(Observer* observer) { |
77 observers_.RemoveObserver(observer); | 83 observers_.RemoveObserver(observer); |
78 } | 84 } |
79 | 85 |
| 86 void SchemaRegistry::AddInternalObserver(InternalObserver* observer) { |
| 87 internal_observers_.AddObserver(observer); |
| 88 } |
| 89 |
| 90 void SchemaRegistry::RemoveInternalObserver(InternalObserver* observer) { |
| 91 internal_observers_.RemoveObserver(observer); |
| 92 } |
| 93 |
80 void SchemaRegistry::Notify(bool has_new_schemas) { | 94 void SchemaRegistry::Notify(bool has_new_schemas) { |
81 FOR_EACH_OBSERVER( | 95 FOR_EACH_OBSERVER( |
82 Observer, observers_, OnSchemaRegistryUpdated(has_new_schemas)); | 96 Observer, observers_, OnSchemaRegistryUpdated(has_new_schemas)); |
83 } | 97 } |
84 | 98 |
85 bool SchemaRegistry::HasObservers() const { | |
86 return observers_.might_have_observers(); | |
87 } | |
88 | |
89 CombinedSchemaRegistry::CombinedSchemaRegistry() | 99 CombinedSchemaRegistry::CombinedSchemaRegistry() |
90 : own_schema_map_(new SchemaMap) { | 100 : own_schema_map_(new SchemaMap) { |
91 // The combined registry is always ready, since it can always start tracking | 101 // The combined registry is always ready, since it can always start tracking |
92 // another registry that is not ready yet and going from "ready" to "not | 102 // another registry that is not ready yet and going from "ready" to "not |
93 // ready" is not allowed. | 103 // ready" is not allowed. |
94 for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i) | 104 for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i) |
95 SetReady(static_cast<PolicyDomain>(i)); | 105 SetReady(static_cast<PolicyDomain>(i)); |
96 } | 106 } |
97 | 107 |
98 CombinedSchemaRegistry::~CombinedSchemaRegistry() {} | 108 CombinedSchemaRegistry::~CombinedSchemaRegistry() {} |
99 | 109 |
100 void CombinedSchemaRegistry::Track(SchemaRegistry* registry) { | 110 void CombinedSchemaRegistry::Track(SchemaRegistry* registry) { |
101 registries_.insert(registry); | 111 registries_.insert(registry); |
102 registry->AddObserver(this); | 112 registry->AddObserver(this); |
| 113 registry->AddInternalObserver(this); |
103 // Recombine the maps only if the |registry| has any components other than | 114 // Recombine the maps only if the |registry| has any components other than |
104 // POLICY_DOMAIN_CHROME. | 115 // POLICY_DOMAIN_CHROME. |
105 if (registry->schema_map()->HasComponents()) | 116 if (registry->schema_map()->HasComponents()) |
106 Combine(true); | 117 Combine(true); |
107 } | 118 } |
108 | 119 |
109 void CombinedSchemaRegistry::Untrack(SchemaRegistry* registry) { | |
110 registry->RemoveObserver(this); | |
111 if (registries_.erase(registry) != 0) { | |
112 if (registry->schema_map()->HasComponents()) | |
113 Combine(false); | |
114 } else { | |
115 NOTREACHED(); | |
116 } | |
117 } | |
118 | |
119 void CombinedSchemaRegistry::RegisterComponents( | 120 void CombinedSchemaRegistry::RegisterComponents( |
120 PolicyDomain domain, | 121 PolicyDomain domain, |
121 const ComponentMap& components) { | 122 const ComponentMap& components) { |
122 DomainMap map(own_schema_map_->GetDomains()); | 123 DomainMap map(own_schema_map_->GetDomains()); |
123 for (ComponentMap::const_iterator it = components.begin(); | 124 for (ComponentMap::const_iterator it = components.begin(); |
124 it != components.end(); ++it) { | 125 it != components.end(); ++it) { |
125 map[domain][it->first] = it->second; | 126 map[domain][it->first] = it->second; |
126 } | 127 } |
127 own_schema_map_ = new SchemaMap(map); | 128 own_schema_map_ = new SchemaMap(map); |
128 Combine(true); | 129 Combine(true); |
(...skipping 10 matching lines...) Expand all Loading... |
139 } | 140 } |
140 | 141 |
141 void CombinedSchemaRegistry::OnSchemaRegistryUpdated(bool has_new_schemas) { | 142 void CombinedSchemaRegistry::OnSchemaRegistryUpdated(bool has_new_schemas) { |
142 Combine(has_new_schemas); | 143 Combine(has_new_schemas); |
143 } | 144 } |
144 | 145 |
145 void CombinedSchemaRegistry::OnSchemaRegistryReady() { | 146 void CombinedSchemaRegistry::OnSchemaRegistryReady() { |
146 // Ignore. | 147 // Ignore. |
147 } | 148 } |
148 | 149 |
| 150 void CombinedSchemaRegistry::OnSchemaRegistryShuttingDown( |
| 151 SchemaRegistry* registry) { |
| 152 registry->RemoveObserver(this); |
| 153 registry->RemoveInternalObserver(this); |
| 154 if (registries_.erase(registry) != 0) { |
| 155 if (registry->schema_map()->HasComponents()) |
| 156 Combine(false); |
| 157 } else { |
| 158 NOTREACHED(); |
| 159 } |
| 160 } |
| 161 |
149 void CombinedSchemaRegistry::Combine(bool has_new_schemas) { | 162 void CombinedSchemaRegistry::Combine(bool has_new_schemas) { |
150 // If two registries publish a Schema for the same component then it's | 163 // If two registries publish a Schema for the same component then it's |
151 // undefined which version gets in the combined registry. | 164 // undefined which version gets in the combined registry. |
152 // | 165 // |
153 // The common case is that both registries want policy for the same component, | 166 // The common case is that both registries want policy for the same component, |
154 // and the Schemas should be the same; in that case this makes no difference. | 167 // and the Schemas should be the same; in that case this makes no difference. |
155 // | 168 // |
156 // But if the Schemas are different then one of the components is out of date. | 169 // But if the Schemas are different then one of the components is out of date. |
157 // In that case the policy loaded will be valid only for one of them, until | 170 // In that case the policy loaded will be valid only for one of them, until |
158 // the outdated components are updated. This is a known limitation of the | 171 // the outdated components are updated. This is a known limitation of the |
159 // way policies are loaded currently, but isn't a problem worth fixing for | 172 // way policies are loaded currently, but isn't a problem worth fixing for |
160 // the time being. | 173 // the time being. |
161 DomainMap map(own_schema_map_->GetDomains()); | 174 DomainMap map(own_schema_map_->GetDomains()); |
162 for (std::set<SchemaRegistry*>::const_iterator reg_it = registries_.begin(); | 175 for (std::set<SchemaRegistry*>::const_iterator reg_it = registries_.begin(); |
163 reg_it != registries_.end(); ++reg_it) { | 176 reg_it != registries_.end(); ++reg_it) { |
164 const DomainMap& reg_domain_map = (*reg_it)->schema_map()->GetDomains(); | 177 const DomainMap& reg_domain_map = (*reg_it)->schema_map()->GetDomains(); |
165 for (DomainMap::const_iterator domain_it = reg_domain_map.begin(); | 178 for (DomainMap::const_iterator domain_it = reg_domain_map.begin(); |
166 domain_it != reg_domain_map.end(); ++domain_it) { | 179 domain_it != reg_domain_map.end(); ++domain_it) { |
167 const ComponentMap& reg_component_map = domain_it->second; | 180 const ComponentMap& reg_component_map = domain_it->second; |
168 for (ComponentMap::const_iterator comp_it = reg_component_map.begin(); | 181 for (ComponentMap::const_iterator comp_it = reg_component_map.begin(); |
169 comp_it != reg_component_map.end(); ++comp_it) { | 182 comp_it != reg_component_map.end(); ++comp_it) { |
170 map[domain_it->first][comp_it->first] = comp_it->second; | 183 map[domain_it->first][comp_it->first] = comp_it->second; |
171 } | 184 } |
172 } | 185 } |
173 } | 186 } |
174 schema_map_ = new SchemaMap(map); | 187 schema_map_ = new SchemaMap(map); |
175 Notify(has_new_schemas); | 188 Notify(has_new_schemas); |
176 } | 189 } |
177 | 190 |
| 191 ForwardingSchemaRegistry::ForwardingSchemaRegistry(SchemaRegistry* wrapped) |
| 192 : wrapped_(wrapped) { |
| 193 schema_map_ = wrapped_->schema_map(); |
| 194 wrapped_->AddObserver(this); |
| 195 wrapped_->AddInternalObserver(this); |
| 196 // This registry is always ready. |
| 197 for (int i = 0; i < POLICY_DOMAIN_SIZE; ++i) |
| 198 SetReady(static_cast<PolicyDomain>(i)); |
| 199 } |
| 200 |
| 201 ForwardingSchemaRegistry::~ForwardingSchemaRegistry() { |
| 202 if (wrapped_) { |
| 203 wrapped_->RemoveObserver(this); |
| 204 wrapped_->RemoveInternalObserver(this); |
| 205 } |
| 206 } |
| 207 |
| 208 void ForwardingSchemaRegistry::RegisterComponents( |
| 209 PolicyDomain domain, |
| 210 const ComponentMap& components) { |
| 211 if (wrapped_) |
| 212 wrapped_->RegisterComponents(domain, components); |
| 213 // Ignore otherwise. |
| 214 } |
| 215 |
| 216 void ForwardingSchemaRegistry::UnregisterComponent(const PolicyNamespace& ns) { |
| 217 if (wrapped_) |
| 218 wrapped_->UnregisterComponent(ns); |
| 219 // Ignore otherwise. |
| 220 } |
| 221 |
| 222 void ForwardingSchemaRegistry::OnSchemaRegistryUpdated(bool has_new_schemas) { |
| 223 schema_map_ = wrapped_->schema_map(); |
| 224 Notify(has_new_schemas); |
| 225 } |
| 226 |
| 227 void ForwardingSchemaRegistry::OnSchemaRegistryReady() { |
| 228 // Ignore. |
| 229 } |
| 230 |
| 231 void ForwardingSchemaRegistry::OnSchemaRegistryShuttingDown( |
| 232 SchemaRegistry* registry) { |
| 233 DCHECK_EQ(wrapped_, registry); |
| 234 wrapped_->RemoveObserver(this); |
| 235 wrapped_->RemoveInternalObserver(this); |
| 236 wrapped_ = NULL; |
| 237 // Keep serving the same |schema_map_|. |
| 238 } |
| 239 |
178 } // namespace policy | 240 } // namespace policy |
OLD | NEW |