Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/policy/policy_service_impl.h" | 5 #include "chrome/browser/policy/policy_service_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | |
| 8 #include "base/bind_helpers.h" | |
| 7 #include "base/observer_list.h" | 9 #include "base/observer_list.h" |
| 8 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "content/public/browser/browser_thread.h" | |
| 12 | |
| 13 using content::BrowserThread; | |
| 9 | 14 |
| 10 namespace policy { | 15 namespace policy { |
| 11 | 16 |
| 12 struct PolicyServiceImpl::Entry { | 17 struct PolicyServiceImpl::Entry { |
| 13 PolicyMap policies; | 18 PolicyMap policies; |
| 14 ObserverList<PolicyService::Observer, true> observers; | 19 ObserverList<PolicyService::Observer, true> observers; |
| 15 }; | 20 }; |
| 16 | 21 |
| 17 struct PolicyServiceImpl::ProviderData { | 22 struct PolicyServiceImpl::ProviderData { |
| 18 ConfigurationPolicyProvider* provider; | 23 ConfigurationPolicyProvider* provider; |
| 19 ConfigurationPolicyObserverRegistrar registrar; | 24 ConfigurationPolicyObserverRegistrar registrar; |
| 20 PolicyMap policies; | 25 PolicyMap policies; |
| 26 bool refresh_pending; | |
| 21 }; | 27 }; |
| 22 | 28 |
| 23 PolicyServiceImpl::PolicyServiceImpl(const Providers& providers) { | 29 PolicyServiceImpl::PolicyServiceImpl(const Providers& providers) { |
| 24 initialization_complete_ = true; | 30 initialization_complete_ = true; |
| 25 for (size_t i = 0; i < providers.size(); ++i) { | 31 for (size_t i = 0; i < providers.size(); ++i) { |
| 26 ConfigurationPolicyProvider* provider = providers[i]; | 32 ConfigurationPolicyProvider* provider = providers[i]; |
| 27 ProviderData* data = new ProviderData; | 33 ProviderData* data = new ProviderData; |
| 28 data->provider = provider; | 34 data->provider = provider; |
| 29 data->registrar.Init(provider, this); | 35 data->registrar.Init(provider, this); |
| 36 data->refresh_pending = false; | |
| 30 if (provider->IsInitializationComplete()) | 37 if (provider->IsInitializationComplete()) |
| 31 provider->Provide(&data->policies); | 38 provider->Provide(&data->policies); |
| 32 else | 39 else |
| 33 initialization_complete_ = false; | 40 initialization_complete_ = false; |
| 34 providers_.push_back(data); | 41 providers_.push_back(data); |
| 35 } | 42 } |
| 36 // There are no observers yet, but calls to GetPolicies() should already get | 43 // There are no observers yet, but calls to GetPolicies() should already get |
| 37 // the processed policy values. | 44 // the processed policy values. |
| 38 MergeAndTriggerUpdates(); | 45 MergeAndTriggerUpdates(false); |
| 39 } | 46 } |
| 40 | 47 |
| 41 PolicyServiceImpl::~PolicyServiceImpl() { | 48 PolicyServiceImpl::~PolicyServiceImpl() { |
| 42 STLDeleteElements(&providers_); | 49 STLDeleteElements(&providers_); |
| 43 STLDeleteValues(&entries_); | 50 STLDeleteValues(&entries_); |
| 44 } | 51 } |
| 45 | 52 |
| 46 void PolicyServiceImpl::AddObserver(PolicyDomain domain, | 53 void PolicyServiceImpl::AddObserver(PolicyDomain domain, |
| 47 const std::string& component_id, | 54 const std::string& component_id, |
| 48 PolicyService::Observer* observer) { | 55 PolicyService::Observer* observer) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 68 const std::string& component_id) const { | 75 const std::string& component_id) const { |
| 69 PolicyNamespace ns = std::make_pair(domain, component_id); | 76 PolicyNamespace ns = std::make_pair(domain, component_id); |
| 70 EntryMap::const_iterator it = entries_.find(ns); | 77 EntryMap::const_iterator it = entries_.find(ns); |
| 71 return it == entries_.end() ? NULL : &it->second->policies; | 78 return it == entries_.end() ? NULL : &it->second->policies; |
| 72 } | 79 } |
| 73 | 80 |
| 74 bool PolicyServiceImpl::IsInitializationComplete() const { | 81 bool PolicyServiceImpl::IsInitializationComplete() const { |
| 75 return initialization_complete_; | 82 return initialization_complete_; |
| 76 } | 83 } |
| 77 | 84 |
| 85 void PolicyServiceImpl::RefreshPolicies(const base::Closure& callback) { | |
| 86 if (!callback.is_null()) | |
| 87 refresh_callbacks_.push_back(callback); | |
| 88 | |
| 89 // Some providers might invoke OnUpdatePolicy synchronously while handling | |
| 90 // RefreshPolicies. Flag all with refresh_pending before starting to refresh. | |
| 91 ProviderList::iterator it; | |
| 92 for (it = providers_.begin(); it != providers_.end(); ++it) | |
| 93 (*it)->refresh_pending = true; | |
| 94 for (it = providers_.begin(); it != providers_.end(); ++it) | |
| 95 (*it)->provider->RefreshPolicies(); | |
|
Mattias Nissler (ping if slow)
2012/04/27 09:03:27
What if providers_ is empty?
Joao da Silva
2012/04/27 11:24:12
Nice catch :-) Fixed.
| |
| 96 } | |
| 97 | |
| 78 void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) { | 98 void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) { |
| 79 ProviderList::iterator it = GetProviderData(provider); | 99 ProviderList::iterator it = GetProviderData(provider); |
| 80 if (it == providers_.end()) | 100 if (it == providers_.end()) |
| 81 return; | 101 return; |
| 82 provider->Provide(&(*it)->policies); | 102 provider->Provide(&(*it)->policies); |
| 83 MergeAndTriggerUpdates(); | 103 bool did_refresh = (*it)->refresh_pending; |
| 104 (*it)->refresh_pending = false; | |
| 105 MergeAndTriggerUpdates(did_refresh); | |
| 84 } | 106 } |
| 85 | 107 |
| 86 void PolicyServiceImpl::OnProviderGoingAway( | 108 void PolicyServiceImpl::OnProviderGoingAway( |
| 87 ConfigurationPolicyProvider* provider) { | 109 ConfigurationPolicyProvider* provider) { |
| 88 ProviderList::iterator it = GetProviderData(provider); | 110 ProviderList::iterator it = GetProviderData(provider); |
| 89 if (it == providers_.end()) | 111 if (it == providers_.end()) |
| 90 return; | 112 return; |
| 113 bool did_refresh = (*it)->refresh_pending; | |
| 91 delete *it; | 114 delete *it; |
| 92 providers_.erase(it); | 115 providers_.erase(it); |
| 93 MergeAndTriggerUpdates(); | 116 MergeAndTriggerUpdates(did_refresh); |
| 94 } | 117 } |
| 95 | 118 |
| 96 PolicyServiceImpl::Entry* PolicyServiceImpl::GetOrCreate( | 119 PolicyServiceImpl::Entry* PolicyServiceImpl::GetOrCreate( |
| 97 const PolicyNamespace& ns) { | 120 const PolicyNamespace& ns) { |
| 98 Entry*& entry = entries_[ns]; | 121 Entry*& entry = entries_[ns]; |
| 99 if (!entry) | 122 if (!entry) |
| 100 entry = new Entry; | 123 entry = new Entry; |
| 101 return entry; | 124 return entry; |
| 102 } | 125 } |
| 103 | 126 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 115 void PolicyServiceImpl::MaybeCleanup(const PolicyNamespace& ns) { | 138 void PolicyServiceImpl::MaybeCleanup(const PolicyNamespace& ns) { |
| 116 EntryMap::iterator it = entries_.find(ns); | 139 EntryMap::iterator it = entries_.find(ns); |
| 117 if (it != entries_.end() && | 140 if (it != entries_.end() && |
| 118 it->second->policies.empty() && | 141 it->second->policies.empty() && |
| 119 it->second->observers.size() == 0) { | 142 it->second->observers.size() == 0) { |
| 120 delete it->second; | 143 delete it->second; |
| 121 entries_.erase(it); | 144 entries_.erase(it); |
| 122 } | 145 } |
| 123 } | 146 } |
| 124 | 147 |
| 125 void PolicyServiceImpl::MergeAndTriggerUpdates() { | 148 void PolicyServiceImpl::MergeAndTriggerUpdates(bool is_refresh) { |
| 126 // TODO(joaodasilva): do this for each namespace once the providers also | 149 // TODO(joaodasilva): do this for each namespace once the providers also |
| 127 // provide policy for more namespaces. | 150 // provide policy for more namespaces. |
| 151 | |
| 128 PolicyMap policies; | 152 PolicyMap policies; |
| 153 bool refresh_pending = false; | |
| 129 for (ProviderList::iterator it = providers_.begin(); | 154 for (ProviderList::iterator it = providers_.begin(); |
| 130 it != providers_.end(); ++it) { | 155 it != providers_.end(); ++it) { |
| 131 policies.MergeFrom((*it)->policies); | 156 policies.MergeFrom((*it)->policies); |
| 157 refresh_pending |= (*it)->refresh_pending; | |
| 132 } | 158 } |
| 133 | 159 |
| 134 Entry* entry = GetOrCreate(std::make_pair(POLICY_DOMAIN_CHROME, "")); | 160 Entry* entry = GetOrCreate(std::make_pair(POLICY_DOMAIN_CHROME, "")); |
| 135 if (!policies.Equals(entry->policies)) { | 161 if (!policies.Equals(entry->policies)) { |
| 136 // Swap first, so that observers that call GetPolicies() see the current | 162 // Swap first, so that observers that call GetPolicies() see the current |
| 137 // values. | 163 // values. |
| 138 entry->policies.Swap(&policies); | 164 entry->policies.Swap(&policies); |
| 139 FOR_EACH_OBSERVER( | 165 FOR_EACH_OBSERVER( |
| 140 PolicyService::Observer, | 166 PolicyService::Observer, |
| 141 entry->observers, | 167 entry->observers, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 153 } | 179 } |
| 154 } | 180 } |
| 155 if (initialization_complete_) { | 181 if (initialization_complete_) { |
| 156 for (EntryMap::iterator i = entries_.begin(); i != entries_.end(); ++i) { | 182 for (EntryMap::iterator i = entries_.begin(); i != entries_.end(); ++i) { |
| 157 FOR_EACH_OBSERVER(PolicyService::Observer, | 183 FOR_EACH_OBSERVER(PolicyService::Observer, |
| 158 i->second->observers, | 184 i->second->observers, |
| 159 OnPolicyServiceInitialized()); | 185 OnPolicyServiceInitialized()); |
| 160 } | 186 } |
| 161 } | 187 } |
| 162 } | 188 } |
| 189 | |
| 190 // Invoke all the callbacks if a refresh has just fully completed. | |
| 191 if (is_refresh && !refresh_pending) { | |
| 192 std::vector<base::Closure> callbacks; | |
| 193 callbacks.swap(refresh_callbacks_); | |
| 194 for (size_t i = 0; i < callbacks.size(); ++i) | |
| 195 callbacks[i].Run(); | |
| 196 } | |
| 163 } | 197 } |
| 164 | 198 |
| 165 } // namespace policy | 199 } // namespace policy |
| OLD | NEW |