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

Side by Side Diff: chrome/browser/chromeos/policy/cloud_external_data_policy_observer_chromeos.cc

Issue 88423002: Add CloudExternalDataPolicyObserverChromeOS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Whitespace fix. Created 7 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/policy/cloud_external_data_policy_observer_chr omeos.h"
6
7 #include <set>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/logging.h"
13 #include "base/values.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/chromeos/login/user.h"
16 #include "chrome/browser/chromeos/login/user_manager.h"
17 #include "chrome/browser/chromeos/policy/device_local_account.h"
18 #include "chrome/browser/policy/cloud/cloud_policy_core.h"
19 #include "chrome/browser/policy/cloud/cloud_policy_store.h"
20 #include "chrome/browser/policy/policy_service.h"
21 #include "chrome/browser/policy/profile_policy_connector.h"
22 #include "chrome/browser/policy/profile_policy_connector_factory.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chromeos/settings/cros_settings_names.h"
25 #include "chromeos/settings/cros_settings_provider.h"
26 #include "components/policy/core/common/external_data_fetcher.h"
27 #include "components/policy/core/common/policy_namespace.h"
28 #include "content/public/browser/notification_details.h"
29 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/notification_source.h"
31
32 namespace policy {
33
34 // Helper class that observes a policy for a logged-in user, notifying the
35 // |parent_| whenever the external data reference for this user changes.
36 class CloudExternalDataPolicyObserverChromeOS::PolicyServiceObserver
37 : public PolicyService::Observer {
38 public:
39 PolicyServiceObserver(CloudExternalDataPolicyObserverChromeOS* parent,
40 const std::string& user_id,
41 PolicyService* policy_service);
42 virtual ~PolicyServiceObserver();
43
44 // PolicyService::Observer:
45 virtual void OnPolicyUpdated(const PolicyNamespace& ns,
46 const PolicyMap& previous,
47 const PolicyMap& current) OVERRIDE;
48
49 private:
50 CloudExternalDataPolicyObserverChromeOS* parent_;
51 const std::string user_id_;
52 PolicyService* policy_service_;
53
54 DISALLOW_COPY_AND_ASSIGN(PolicyServiceObserver);
55 };
56
57 CloudExternalDataPolicyObserverChromeOS::PolicyServiceObserver::
58 PolicyServiceObserver(CloudExternalDataPolicyObserverChromeOS* parent,
59 const std::string& user_id,
60 PolicyService* policy_service)
61 : parent_(parent),
62 user_id_(user_id),
63 policy_service_(policy_service) {
64 policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
65
66 if (!IsDeviceLocalAccountUser(user_id, NULL)) {
67 // Notify |parent_| if the external data reference for |user_id_| is set
68 // during login. This is omitted for device-local accounts because their
69 // policy is available before login and the external data reference will
70 // have been seen by the |parent_| already.
71 const PolicyMap::Entry* entry = policy_service_->GetPolicies(
72 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
73 .Get(parent_->policy_);
74 if (entry)
75 parent_->HandleExternalDataPolicyUpdate(user_id_, entry);
76 }
77 }
78
79 CloudExternalDataPolicyObserverChromeOS::PolicyServiceObserver::
80 ~PolicyServiceObserver() {
81 policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
82 }
83
84 void CloudExternalDataPolicyObserverChromeOS::PolicyServiceObserver::
85 OnPolicyUpdated(const PolicyNamespace& ns,
86 const PolicyMap& previous,
87 const PolicyMap& current) {
88 DCHECK(ns == PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
89
90 const PolicyMap::Entry* previous_entry = previous.Get(parent_->policy_);
91 const PolicyMap::Entry* current_entry = current.Get(parent_->policy_);
92 if ((!previous_entry && current_entry) ||
93 (previous_entry && !current_entry) ||
94 (previous_entry && current_entry &&
95 !previous_entry->Equals(*current_entry))) {
96 // Notify |parent_| if the external data reference for |user_id_| has
97 // changed.
98 parent_->HandleExternalDataPolicyUpdate(user_id_, current_entry);
99 }
100 }
101
102 CloudExternalDataPolicyObserverChromeOS::
103 CloudExternalDataPolicyObserverChromeOS(
104 chromeos::CrosSettings* cros_settings,
105 chromeos::UserManager* user_manager,
106 DeviceLocalAccountPolicyService* device_local_account_policy_service,
107 const std::string& policy)
108 : cros_settings_(cros_settings),
109 user_manager_(user_manager),
110 device_local_account_policy_service_(device_local_account_policy_service),
111 policy_(policy) {
112 notification_registrar_.Add(
113 this,
114 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
115 content::NotificationService::AllSources());
116
117 if (device_local_account_policy_service_)
118 device_local_account_policy_service_->AddObserver(this);
119
120 device_local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
121 chromeos::kAccountsPrefDeviceLocalAccounts,
122 base::Bind(
123 &CloudExternalDataPolicyObserverChromeOS::RetrieveDeviceLocalAccounts,
124 base::Unretained(this)));
125 }
126
127 CloudExternalDataPolicyObserverChromeOS::
128 ~CloudExternalDataPolicyObserverChromeOS() {
129 }
130
131 void CloudExternalDataPolicyObserverChromeOS::Init() {
132 RetrieveDeviceLocalAccounts();
133 }
134
135 void CloudExternalDataPolicyObserverChromeOS::Shutdown() {
136 device_local_accounts_subscription_.reset();
137 if (device_local_account_policy_service_)
138 device_local_account_policy_service_->RemoveObserver(this);
139 notification_registrar_.RemoveAll();
140
141 for (DeviceLocalAccountEntryMap::iterator it =
142 device_local_account_entries_.begin();
143 it != device_local_account_entries_.end(); ++it) {
144 delete it->second.value;
145 delete it->second.external_data_fetcher;
146 }
Joao da Silva 2013/11/27 14:33:59 device_local_account_entries_.clear()?
bartfab (slow) 2013/11/27 20:10:15 Done.
147 logged_in_user_observers_.clear();
148 }
149
150 void CloudExternalDataPolicyObserverChromeOS::Observe(
151 int type,
152 const content::NotificationSource& source,
153 const content::NotificationDetails& details) {
154 if (type != chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED) {
155 NOTREACHED();
156 return;
157 }
158 Profile* profile = content::Details<Profile>(details).ptr();
159
160 const chromeos::User* user = user_manager_->GetUserByProfile(profile);
161 if (!user) {
162 NOTREACHED();
163 return;
164 }
165
166 const std::string& user_id = user->email();
167 if (logged_in_user_observers_.find(user_id) !=
168 logged_in_user_observers_.end()) {
Joao da Silva 2013/11/27 14:33:59 ContainsKey() is clearer
bartfab (slow) 2013/11/27 20:10:15 Done.
169 NOTREACHED();
170 return;
171 }
172
173 ProfilePolicyConnector* policy_connector =
174 ProfilePolicyConnectorFactory::GetForProfile(profile);
175 logged_in_user_observers_[user_id] = make_linked_ptr(
176 new PolicyServiceObserver(this,
177 user_id,
178 policy_connector->policy_service()));
179 }
180
181 void CloudExternalDataPolicyObserverChromeOS::OnPolicyUpdated(
182 const std::string& user_id) {
183 if (logged_in_user_observers_.find(user_id) !=
184 logged_in_user_observers_.end()) {
Joao da Silva 2013/11/27 14:33:59 ContainsKey
bartfab (slow) 2013/11/27 20:10:15 Done.
185 // When a device-local account is logged in, a policy change triggers both
186 // OnPolicyUpdated() and PolicyServiceObserver::OnPolicyUpdated(). Ignore
187 // the former so that the policy change is handled only once.
188 return;
189 }
190
191 if (!device_local_account_policy_service_) {
192 NOTREACHED();
193 return;
194 }
195 DeviceLocalAccountPolicyBroker* broker =
196 device_local_account_policy_service_->GetBrokerForUser(user_id);
197 if (!broker) {
198 NOTREACHED();
199 return;
200 }
201
202 const PolicyMap::Entry* entry =
203 broker->core()->store()->policy_map().Get(policy_);
204 if (!entry) {
205 DeviceLocalAccountEntryMap::iterator it =
206 device_local_account_entries_.find(user_id);
207 if (it != device_local_account_entries_.end()) {
208 delete it->second.value;
209 delete it->second.external_data_fetcher;
210 device_local_account_entries_.erase(it);
211 HandleExternalDataPolicyUpdate(user_id, NULL);
212 }
213 return;
214 }
215
216 PolicyMap::Entry& map_entry = device_local_account_entries_[user_id];
217 if (map_entry.Equals(*entry))
218 return;
219
220 map_entry = *entry->DeepCopy();
Joao da Silva 2013/11/27 14:33:59 This leaks map_entry.value and map_entry.external_
bartfab (slow) 2013/11/27 20:10:15 Done.
221 HandleExternalDataPolicyUpdate(user_id, entry);
222 }
223
224 void CloudExternalDataPolicyObserverChromeOS::OnDeviceLocalAccountsChanged() {
225 // No action needed here, changes to the list of device-local accounts get
226 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
227 }
228
229 void CloudExternalDataPolicyObserverChromeOS::RetrieveDeviceLocalAccounts() {
230 // Schedule a callback if device policy has not yet been verified.
231 if (chromeos::CrosSettingsProvider::TRUSTED !=
232 cros_settings_->PrepareTrustedValues(base::Bind(
233 &CloudExternalDataPolicyObserverChromeOS::RetrieveDeviceLocalAccounts,
234 base::Unretained(this)))) {
Joao da Silva 2013/11/27 14:33:59 Is it safe to pass an unretained this? Can't the c
bartfab (slow) 2013/11/27 20:10:15 Nice catch. I copy & pasted this snippet from some
235 return;
236 }
237
238 std::vector<DeviceLocalAccount> device_local_account_list =
239 policy::GetDeviceLocalAccounts(cros_settings_);
240 std::set<std::string> device_local_accounts;
241 for (std::vector<DeviceLocalAccount>::const_iterator it =
242 device_local_account_list.begin();
243 it != device_local_account_list.end(); ++it) {
244 device_local_accounts.insert(it->user_id);
245 }
246
247 for (DeviceLocalAccountEntryMap::iterator it =
248 device_local_account_entries_.begin();
249 it != device_local_account_entries_.end(); ) {
250 if (device_local_accounts.find(it->first) == device_local_accounts.end()) {
Joao da Silva 2013/11/27 14:33:59 !ContainsKey
bartfab (slow) 2013/11/27 20:10:15 Done.
251 const std::string user_id = it->first;
252 delete it->second.value;
253 delete it->second.external_data_fetcher;
Joao da Silva 2013/11/27 14:33:59 This is repeated in 3 places, and maybe a 4th is a
bartfab (slow) 2013/11/27 20:10:15 Done.
254 device_local_account_entries_.erase(it++);
255 // When a device-local account whose external data reference was set is
256 // removed, emit a notification that the external data reference has been
257 // cleared.
258 HandleExternalDataPolicyUpdate(user_id, NULL);
259 } else {
260 ++it;
261 }
262 }
263
264 for (std::set<std::string>::const_iterator it = device_local_accounts.begin();
265 it != device_local_accounts.end(); ++it) {
266 OnPolicyUpdated(*it);
267 }
268 }
269
270 void CloudExternalDataPolicyObserverChromeOS::HandleExternalDataPolicyUpdate(
271 const std::string& user_id,
272 const PolicyMap::Entry* entry) {
273 if (!entry) {
274 OnExternalDataCleared(user_id);
275 fetch_weak_ptrs_.erase(user_id);
276 return;
277 }
278
279 OnExternalDataSet(user_id);
280
281 linked_ptr<WeakPtrFactory>& weak_ptr_factory = fetch_weak_ptrs_[user_id];
282 weak_ptr_factory.reset(new WeakPtrFactory(this));
283 if (entry->external_data_fetcher) {
284 entry->external_data_fetcher->Fetch(base::Bind(
285 &CloudExternalDataPolicyObserverChromeOS::OnExternalDataFetched,
286 weak_ptr_factory->GetWeakPtr(),
287 user_id));
288 } else {
289 NOTREACHED();
290 }
291 }
292
293 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698