| 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 if (providers_.empty()) { |
| 90 // Refresh is immediately complete if there are no providers. |
| 91 MergeAndTriggerUpdates(true); |
| 92 } else { |
| 93 // Some providers might invoke OnUpdatePolicy synchronously while handling |
| 94 // RefreshPolicies. Flag all with refresh_pending before refreshing. |
| 95 ProviderList::iterator it; |
| 96 for (it = providers_.begin(); it != providers_.end(); ++it) |
| 97 (*it)->refresh_pending = true; |
| 98 for (it = providers_.begin(); it != providers_.end(); ++it) |
| 99 (*it)->provider->RefreshPolicies(); |
| 100 } |
| 101 } |
| 102 |
| 78 void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) { | 103 void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) { |
| 79 ProviderList::iterator it = GetProviderData(provider); | 104 ProviderList::iterator it = GetProviderData(provider); |
| 80 if (it == providers_.end()) | 105 if (it == providers_.end()) |
| 81 return; | 106 return; |
| 82 provider->Provide(&(*it)->policies); | 107 provider->Provide(&(*it)->policies); |
| 83 MergeAndTriggerUpdates(); | 108 bool did_refresh = (*it)->refresh_pending; |
| 109 (*it)->refresh_pending = false; |
| 110 MergeAndTriggerUpdates(did_refresh); |
| 84 } | 111 } |
| 85 | 112 |
| 86 void PolicyServiceImpl::OnProviderGoingAway( | 113 void PolicyServiceImpl::OnProviderGoingAway( |
| 87 ConfigurationPolicyProvider* provider) { | 114 ConfigurationPolicyProvider* provider) { |
| 88 ProviderList::iterator it = GetProviderData(provider); | 115 ProviderList::iterator it = GetProviderData(provider); |
| 89 if (it == providers_.end()) | 116 if (it == providers_.end()) |
| 90 return; | 117 return; |
| 118 bool did_refresh = (*it)->refresh_pending; |
| 91 delete *it; | 119 delete *it; |
| 92 providers_.erase(it); | 120 providers_.erase(it); |
| 93 MergeAndTriggerUpdates(); | 121 MergeAndTriggerUpdates(did_refresh); |
| 94 } | 122 } |
| 95 | 123 |
| 96 PolicyServiceImpl::Entry* PolicyServiceImpl::GetOrCreate( | 124 PolicyServiceImpl::Entry* PolicyServiceImpl::GetOrCreate( |
| 97 const PolicyNamespace& ns) { | 125 const PolicyNamespace& ns) { |
| 98 Entry*& entry = entries_[ns]; | 126 Entry*& entry = entries_[ns]; |
| 99 if (!entry) | 127 if (!entry) |
| 100 entry = new Entry; | 128 entry = new Entry; |
| 101 return entry; | 129 return entry; |
| 102 } | 130 } |
| 103 | 131 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 115 void PolicyServiceImpl::MaybeCleanup(const PolicyNamespace& ns) { | 143 void PolicyServiceImpl::MaybeCleanup(const PolicyNamespace& ns) { |
| 116 EntryMap::iterator it = entries_.find(ns); | 144 EntryMap::iterator it = entries_.find(ns); |
| 117 if (it != entries_.end() && | 145 if (it != entries_.end() && |
| 118 it->second->policies.empty() && | 146 it->second->policies.empty() && |
| 119 it->second->observers.size() == 0) { | 147 it->second->observers.size() == 0) { |
| 120 delete it->second; | 148 delete it->second; |
| 121 entries_.erase(it); | 149 entries_.erase(it); |
| 122 } | 150 } |
| 123 } | 151 } |
| 124 | 152 |
| 125 void PolicyServiceImpl::MergeAndTriggerUpdates() { | 153 void PolicyServiceImpl::MergeAndTriggerUpdates(bool is_refresh) { |
| 126 // TODO(joaodasilva): do this for each namespace once the providers also | 154 // TODO(joaodasilva): do this for each namespace once the providers also |
| 127 // provide policy for more namespaces. | 155 // provide policy for more namespaces. |
| 156 |
| 128 PolicyMap policies; | 157 PolicyMap policies; |
| 158 bool refresh_pending = false; |
| 129 for (ProviderList::iterator it = providers_.begin(); | 159 for (ProviderList::iterator it = providers_.begin(); |
| 130 it != providers_.end(); ++it) { | 160 it != providers_.end(); ++it) { |
| 131 policies.MergeFrom((*it)->policies); | 161 policies.MergeFrom((*it)->policies); |
| 162 refresh_pending |= (*it)->refresh_pending; |
| 132 } | 163 } |
| 133 | 164 |
| 134 Entry* entry = GetOrCreate(std::make_pair(POLICY_DOMAIN_CHROME, "")); | 165 Entry* entry = GetOrCreate(std::make_pair(POLICY_DOMAIN_CHROME, "")); |
| 135 if (!policies.Equals(entry->policies)) { | 166 if (!policies.Equals(entry->policies)) { |
| 136 // Swap first, so that observers that call GetPolicies() see the current | 167 // Swap first, so that observers that call GetPolicies() see the current |
| 137 // values. | 168 // values. |
| 138 entry->policies.Swap(&policies); | 169 entry->policies.Swap(&policies); |
| 139 FOR_EACH_OBSERVER( | 170 FOR_EACH_OBSERVER( |
| 140 PolicyService::Observer, | 171 PolicyService::Observer, |
| 141 entry->observers, | 172 entry->observers, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 153 } | 184 } |
| 154 } | 185 } |
| 155 if (initialization_complete_) { | 186 if (initialization_complete_) { |
| 156 for (EntryMap::iterator i = entries_.begin(); i != entries_.end(); ++i) { | 187 for (EntryMap::iterator i = entries_.begin(); i != entries_.end(); ++i) { |
| 157 FOR_EACH_OBSERVER(PolicyService::Observer, | 188 FOR_EACH_OBSERVER(PolicyService::Observer, |
| 158 i->second->observers, | 189 i->second->observers, |
| 159 OnPolicyServiceInitialized()); | 190 OnPolicyServiceInitialized()); |
| 160 } | 191 } |
| 161 } | 192 } |
| 162 } | 193 } |
| 194 |
| 195 // Invoke all the callbacks if a refresh has just fully completed. |
| 196 if (is_refresh && !refresh_pending) { |
| 197 std::vector<base::Closure> callbacks; |
| 198 callbacks.swap(refresh_callbacks_); |
| 199 for (size_t i = 0; i < callbacks.size(); ++i) |
| 200 callbacks[i].Run(); |
| 201 } |
| 163 } | 202 } |
| 164 | 203 |
| 165 } // namespace policy | 204 } // namespace policy |
| OLD | NEW |