| 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 |