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

Side by Side Diff: chrome/browser/policy/policy_service_impl.cc

Issue 11667006: Create a list of policy changes before notifying observers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Another ToT merge Created 7 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop.h"
9 #include "base/stl_util.h" 12 #include "base/stl_util.h"
10 #include "chrome/browser/policy/policy_map.h" 13 #include "chrome/browser/policy/policy_map.h"
11 14
12 namespace policy { 15 namespace policy {
13 16
17 PolicyServiceImpl::PolicyChangeInfo::PolicyChangeInfo(
18 const PolicyBundle::PolicyNamespace& policy_namespace,
19 const PolicyMap& previous, const PolicyMap& current)
20 : policy_namespace_(policy_namespace) {
21 previous_.CopyFrom(previous);
22 current_.CopyFrom(current);
23 }
24
25 PolicyServiceImpl::PolicyChangeInfo::~PolicyChangeInfo() {
26 }
27
14 typedef PolicyServiceImpl::Providers::const_iterator Iterator; 28 typedef PolicyServiceImpl::Providers::const_iterator Iterator;
15 29
16 PolicyServiceImpl::PolicyServiceImpl(const Providers& providers) { 30 PolicyServiceImpl::PolicyServiceImpl(const Providers& providers)
31 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
17 initialization_complete_ = true; 32 initialization_complete_ = true;
18 providers_ = providers; 33 providers_ = providers;
19 for (Iterator it = providers.begin(); it != providers.end(); ++it) { 34 for (Iterator it = providers.begin(); it != providers.end(); ++it) {
20 ConfigurationPolicyProvider* provider = *it; 35 ConfigurationPolicyProvider* provider = *it;
21 provider->AddObserver(this); 36 provider->AddObserver(this);
22 initialization_complete_ &= provider->IsInitializationComplete(); 37 initialization_complete_ &= provider->IsInitializationComplete();
23 } 38 }
24 // There are no observers yet, but calls to GetPolicies() should already get 39 // There are no observers yet, but calls to GetPolicies() should already get
25 // the processed policy values. 40 // the processed policy values.
26 MergeAndTriggerUpdates(); 41 MergeAndTriggerUpdates();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) { 99 void PolicyServiceImpl::OnUpdatePolicy(ConfigurationPolicyProvider* provider) {
85 DCHECK_EQ(1, std::count(providers_.begin(), providers_.end(), provider)); 100 DCHECK_EQ(1, std::count(providers_.begin(), providers_.end(), provider));
86 refresh_pending_.erase(provider); 101 refresh_pending_.erase(provider);
87 MergeAndTriggerUpdates(); 102 MergeAndTriggerUpdates();
88 } 103 }
89 104
90 void PolicyServiceImpl::NotifyNamespaceUpdated( 105 void PolicyServiceImpl::NotifyNamespaceUpdated(
91 const PolicyBundle::PolicyNamespace& ns, 106 const PolicyBundle::PolicyNamespace& ns,
92 const PolicyMap& previous, 107 const PolicyMap& previous,
93 const PolicyMap& current) { 108 const PolicyMap& current) {
94 ObserverMap::iterator iterator = observers_.find(ns.first); 109 // If running a unit test that hasn't setup a MessageLoop, don't send any
110 // notifications.
111 if (!MessageLoop::current())
112 return;
113
114 // Don't queue up a task if we have no observers - that way Observers added
115 // later don't get notified of changes that happened during construction time.
116 if (observers_.find(ns.first) == observers_.end())
117 return;
118
119 // Notify Observers via a queued task, so Observers can't trigger a re-entrant
120 // call to MergeAndTriggerUpdates() by modifying policy.
121 scoped_ptr<PolicyChangeInfo> changes(
122 new PolicyChangeInfo(ns, previous, current));
123 MessageLoop::current()->PostTask(
124 FROM_HERE,
125 base::Bind(&PolicyServiceImpl::NotifyNamespaceUpdatedTask,
126 weak_ptr_factory_.GetWeakPtr(),
127 base::Passed(&changes)));
128 }
129
130 void PolicyServiceImpl::NotifyNamespaceUpdatedTask(
131 scoped_ptr<PolicyChangeInfo> changes) {
132 ObserverMap::iterator iterator = observers_.find(
133 changes->policy_namespace_.first);
95 if (iterator != observers_.end()) { 134 if (iterator != observers_.end()) {
96 FOR_EACH_OBSERVER( 135 FOR_EACH_OBSERVER(
97 PolicyService::Observer, 136 PolicyService::Observer,
98 *iterator->second, 137 *iterator->second,
99 OnPolicyUpdated(ns.first, ns.second, previous, current)); 138 OnPolicyUpdated(changes->policy_namespace_.first,
139 changes->policy_namespace_.second,
140 changes->previous_,
141 changes->current_));
100 } 142 }
101 } 143 }
102 144
103 void PolicyServiceImpl::MergeAndTriggerUpdates() { 145 void PolicyServiceImpl::MergeAndTriggerUpdates() {
104 // Merge from each provider in their order of priority. 146 // Merge from each provider in their order of priority.
105 PolicyBundle bundle; 147 PolicyBundle bundle;
106 for (Iterator it = providers_.begin(); it != providers_.end(); ++it) 148 for (Iterator it = providers_.begin(); it != providers_.end(); ++it)
107 bundle.MergeFrom((*it)->policies()); 149 bundle.MergeFrom((*it)->policies());
108 150
109 // Swap first, so that observers that call GetPolicies() see the current 151 // Swap first, so that observers that call GetPolicies() see the current
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 if (refresh_pending_.empty() && !refresh_callbacks_.empty()) { 215 if (refresh_pending_.empty() && !refresh_callbacks_.empty()) {
174 std::vector<base::Closure> callbacks; 216 std::vector<base::Closure> callbacks;
175 callbacks.swap(refresh_callbacks_); 217 callbacks.swap(refresh_callbacks_);
176 std::vector<base::Closure>::iterator it; 218 std::vector<base::Closure>::iterator it;
177 for (it = callbacks.begin(); it != callbacks.end(); ++it) 219 for (it = callbacks.begin(); it != callbacks.end(); ++it)
178 it->Run(); 220 it->Run();
179 } 221 }
180 } 222 }
181 223
182 } // namespace policy 224 } // namespace policy
OLDNEW
« 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