Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(743)

Unified Diff: chrome/browser/policy/policy_service_impl.cc

Issue 10386097: Refactored ConfigurationPolicyProvider to provide PolicyBundles instead of PolicyMaps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/policy/policy_service_impl.h ('k') | chrome/browser/policy/policy_service_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/policy/policy_service_impl.cc
diff --git a/chrome/browser/policy/policy_service_impl.cc b/chrome/browser/policy/policy_service_impl.cc
index 961a2a4038ba704a44f4300df99d204e02badacb..d927c657cf1c381bf10f0e9bfa12ecfac031cfe4 100644
--- a/chrome/browser/policy/policy_service_impl.cc
+++ b/chrome/browser/policy/policy_service_impl.cc
@@ -4,78 +4,61 @@
#include "chrome/browser/policy/policy_service_impl.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/observer_list.h"
#include "base/stl_util.h"
-#include "content/public/browser/browser_thread.h"
-
-using content::BrowserThread;
+#include "chrome/browser/policy/policy_map.h"
namespace policy {
-struct PolicyServiceImpl::Entry {
- PolicyMap policies;
- ObserverList<PolicyService::Observer, true> observers;
-};
-
-struct PolicyServiceImpl::ProviderData {
- ConfigurationPolicyProvider* provider;
- ConfigurationPolicyObserverRegistrar registrar;
- PolicyMap policies;
- bool refresh_pending;
-};
-
PolicyServiceImpl::PolicyServiceImpl(const Providers& providers) {
initialization_complete_ = true;
for (size_t i = 0; i < providers.size(); ++i) {
ConfigurationPolicyProvider* provider = providers[i];
- ProviderData* data = new ProviderData;
- data->provider = provider;
- data->registrar.Init(provider, this);
- data->refresh_pending = false;
- if (provider->IsInitializationComplete())
- provider->Provide(&data->policies);
- else
- initialization_complete_ = false;
- providers_.push_back(data);
+ ConfigurationPolicyObserverRegistrar* registrar =
+ new ConfigurationPolicyObserverRegistrar();
+ registrar->Init(provider, this);
+ initialization_complete_ &= provider->IsInitializationComplete();
+ registrars_.push_back(registrar);
}
// There are no observers yet, but calls to GetPolicies() should already get
// the processed policy values.
- MergeAndTriggerUpdates(false);
+ MergeAndTriggerUpdates();
}
PolicyServiceImpl::~PolicyServiceImpl() {
- STLDeleteElements(&providers_);
- STLDeleteValues(&entries_);
+ STLDeleteElements(&registrars_);
+ STLDeleteValues(&observers_);
}
void PolicyServiceImpl::AddObserver(PolicyDomain domain,
const std::string& component_id,
PolicyService::Observer* observer) {
- PolicyNamespace ns = std::make_pair(domain, component_id);
- GetOrCreate(ns)->observers.AddObserver(observer);
+ PolicyBundle::PolicyNamespace ns(domain, component_id);
+ Observers*& list = observers_[ns];
+ if (!list)
+ list = new Observers();
+ list->AddObserver(observer);
}
void PolicyServiceImpl::RemoveObserver(PolicyDomain domain,
const std::string& component_id,
PolicyService::Observer* observer) {
- PolicyNamespace ns = std::make_pair(domain, component_id);
- EntryMap::const_iterator it = entries_.find(ns);
- if (it == entries_.end()) {
+ PolicyBundle::PolicyNamespace ns(domain, component_id);
+ ObserverMap::iterator it = observers_.find(ns);
+ if (it == observers_.end()) {
NOTREACHED();
return;
}
- it->second->observers.RemoveObserver(observer);
- MaybeCleanup(ns);
+ it->second->RemoveObserver(observer);
+ if (it->second->size() == 0) {
+ delete it->second;
+ observers_.erase(it);
+ }
}
-const PolicyMap* PolicyServiceImpl::GetPolicies(
+const PolicyMap& PolicyServiceImpl::GetPolicies(
PolicyDomain domain,
const std::string& component_id) const {
- PolicyNamespace ns = std::make_pair(domain, component_id);
- EntryMap::const_iterator it = entries_.find(ns);
- return it == entries_.end() ? NULL : &it->second->policies;
+ return policy_bundle_.Get(domain, component_id);
}
bool PolicyServiceImpl::IsInitializationComplete() const {
@@ -86,114 +69,137 @@ void PolicyServiceImpl::RefreshPolicies(const base::Closure& callback) {
if (!callback.is_null())
refresh_callbacks_.push_back(callback);
- if (providers_.empty()) {
+ if (registrars_.empty()) {
// Refresh is immediately complete if there are no providers.
- MergeAndTriggerUpdates(true);
+ MergeAndTriggerUpdates();
} else {
// Some providers might invoke OnUpdatePolicy synchronously while handling
- // RefreshPolicies. Flag all with refresh_pending before refreshing.
- ProviderList::iterator it;
- for (it = providers_.begin(); it != providers_.end(); ++it)
- (*it)->refresh_pending = true;
- for (it = providers_.begin(); it != providers_.end(); ++it)
- (*it)->provider->RefreshPolicies();
+ // RefreshPolicies. Mark all as pending before refreshing.
+ RegistrarList::iterator it;
+ for (it = registrars_.begin(); it != registrars_.end(); ++it)
+ refresh_pending_.insert((*it)->provider());
+ for (it = registrars_.begin(); it != registrars_.end(); ++it)
+ (*it)->provider()->RefreshPolicies();
}
}
void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) {
- ProviderList::iterator it = GetProviderData(provider);
- if (it == providers_.end())
+ RegistrarList::iterator it = GetRegistrar(provider);
+ if (it == registrars_.end())
return;
- provider->Provide(&(*it)->policies);
- bool did_refresh = (*it)->refresh_pending;
- (*it)->refresh_pending = false;
- MergeAndTriggerUpdates(did_refresh);
+ refresh_pending_.erase(provider);
+ MergeAndTriggerUpdates();
}
void PolicyServiceImpl::OnProviderGoingAway(
ConfigurationPolicyProvider* provider) {
- ProviderList::iterator it = GetProviderData(provider);
- if (it == providers_.end())
+ RegistrarList::iterator it = GetRegistrar(provider);
+ if (it == registrars_.end())
return;
- bool did_refresh = (*it)->refresh_pending;
+ refresh_pending_.erase(provider);
delete *it;
- providers_.erase(it);
- MergeAndTriggerUpdates(did_refresh);
+ registrars_.erase(it);
+ MergeAndTriggerUpdates();
}
-PolicyServiceImpl::Entry* PolicyServiceImpl::GetOrCreate(
- const PolicyNamespace& ns) {
- Entry*& entry = entries_[ns];
- if (!entry)
- entry = new Entry;
- return entry;
-}
-
-PolicyServiceImpl::ProviderList::iterator PolicyServiceImpl::GetProviderData(
+PolicyServiceImpl::RegistrarList::iterator PolicyServiceImpl::GetRegistrar(
ConfigurationPolicyProvider* provider) {
- for (ProviderList::iterator it = providers_.begin();
- it != providers_.end(); ++it) {
- if ((*it)->provider == provider)
+ for (RegistrarList::iterator it = registrars_.begin();
+ it != registrars_.end(); ++it) {
+ if ((*it)->provider() == provider)
return it;
}
NOTREACHED();
- return providers_.end();
+ return registrars_.end();
}
-void PolicyServiceImpl::MaybeCleanup(const PolicyNamespace& ns) {
- EntryMap::iterator it = entries_.find(ns);
- if (it != entries_.end() &&
- it->second->policies.empty() &&
- it->second->observers.size() == 0) {
- delete it->second;
- entries_.erase(it);
+void PolicyServiceImpl::NotifyNamespaceUpdated(
+ const PolicyBundle::PolicyNamespace& ns,
+ const PolicyMap& previous,
+ const PolicyMap& current) {
+ ObserverMap::iterator iterator = observers_.find(ns);
+ if (iterator != observers_.end()) {
+ FOR_EACH_OBSERVER(
+ PolicyService::Observer,
+ *iterator->second,
+ OnPolicyUpdated(ns.first, ns.second, previous, current));
}
}
-void PolicyServiceImpl::MergeAndTriggerUpdates(bool is_refresh) {
- // TODO(joaodasilva): do this for each namespace once the providers also
- // provide policy for more namespaces.
-
- PolicyMap policies;
- bool refresh_pending = false;
- for (ProviderList::iterator it = providers_.begin();
- it != providers_.end(); ++it) {
- policies.MergeFrom((*it)->policies);
- refresh_pending |= (*it)->refresh_pending;
+void PolicyServiceImpl::MergeAndTriggerUpdates() {
+ // Merge from each provider in their order of priority.
+ PolicyBundle bundle;
+ for (RegistrarList::iterator it = registrars_.begin();
+ it != registrars_.end(); ++it) {
+ bundle.MergeFrom((*it)->provider()->policies());
}
- Entry* entry = GetOrCreate(std::make_pair(POLICY_DOMAIN_CHROME, ""));
- if (!policies.Equals(entry->policies)) {
- // Swap first, so that observers that call GetPolicies() see the current
- // values.
- entry->policies.Swap(&policies);
- FOR_EACH_OBSERVER(
- PolicyService::Observer,
- entry->observers,
- OnPolicyUpdated(POLICY_DOMAIN_CHROME, "", policies, entry->policies));
+ // Swap first, so that observers that call GetPolicies() see the current
+ // values.
+ policy_bundle_.Swap(&bundle);
+
+ // Only notify observers of namespaces that have been modified.
+ const PolicyMap kEmpty;
+ PolicyBundle::const_iterator it_new = policy_bundle_.begin();
+ PolicyBundle::const_iterator end_new = policy_bundle_.end();
+ PolicyBundle::const_iterator it_old = bundle.begin();
+ PolicyBundle::const_iterator end_old = bundle.end();
+ while (it_new != end_new && it_old != end_old) {
+ if (it_new->first < it_old->first) {
+ // A new namespace is available.
+ NotifyNamespaceUpdated(it_new->first, kEmpty, *it_new->second);
+ ++it_new;
+ } else if (it_new->first > it_old->first) {
+ // A previously available namespace is now gone.
+ NotifyNamespaceUpdated(it_old->first, *it_old->second, kEmpty);
+ ++it_old;
+ } else {
+ if (!it_new->second->Equals(*it_old->second)) {
+ // An existing namespace's policies have changed.
+ NotifyNamespaceUpdated(it_new->first, *it_old->second, *it_new->second);
+ }
+ ++it_new;
+ ++it_old;
+ }
}
+ // Send updates for the remaining new namespaces, if any.
+ for (; it_new != end_new; ++it_new)
+ NotifyNamespaceUpdated(it_new->first, kEmpty, *it_new->second);
+
+ // Sends updates for the remaining removed namespaces, if any.
+ for (; it_old != end_old; ++it_old)
+ NotifyNamespaceUpdated(it_old->first, *it_old->second, kEmpty);
+
+ CheckInitializationComplete();
+ CheckRefreshComplete();
+}
+
+void PolicyServiceImpl::CheckInitializationComplete() {
// Check if all providers became initialized just now, if they weren't before.
if (!initialization_complete_) {
initialization_complete_ = true;
- for (ProviderList::iterator iter = providers_.begin();
- iter != providers_.end(); ++iter) {
- if (!(*iter)->provider->IsInitializationComplete()) {
+ for (RegistrarList::iterator iter = registrars_.begin();
+ iter != registrars_.end(); ++iter) {
+ if (!(*iter)->provider()->IsInitializationComplete()) {
initialization_complete_ = false;
break;
}
}
if (initialization_complete_) {
- for (EntryMap::iterator i = entries_.begin(); i != entries_.end(); ++i) {
+ for (ObserverMap::iterator iter = observers_.begin();
+ iter != observers_.end(); ++iter) {
FOR_EACH_OBSERVER(PolicyService::Observer,
- i->second->observers,
+ *iter->second,
OnPolicyServiceInitialized());
}
}
}
+}
+void PolicyServiceImpl::CheckRefreshComplete() {
// Invoke all the callbacks if a refresh has just fully completed.
- if (is_refresh && !refresh_pending) {
+ if (refresh_pending_.empty() && !refresh_callbacks_.empty()) {
std::vector<base::Closure> callbacks;
callbacks.swap(refresh_callbacks_);
for (size_t i = 0; i < callbacks.size(); ++i)
« no previous file with comments | « chrome/browser/policy/policy_service_impl.h ('k') | chrome/browser/policy/policy_service_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698