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

Side by Side Diff: trunk/src/chrome/browser/chromeos/policy/device_local_account_policy_service.cc

Issue 32513006: Revert 229896 "Cache force-installed apps/extensions in device-l..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 2 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/chromeos/policy/device_local_account_policy_service.h" 5 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/file_util.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/files/file_path.h"
13 #include "base/logging.h" 10 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
15 #include "base/message_loop/message_loop_proxy.h" 12 #include "base/message_loop/message_loop_proxy.h"
16 #include "base/path_service.h"
17 #include "base/sequenced_task_runner.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "chrome/browser/chromeos/policy/device_local_account.h" 13 #include "chrome/browser/chromeos/policy/device_local_account.h"
20 #include "chrome/browser/chromeos/policy/device_local_account_policy_store.h" 14 #include "chrome/browser/chromeos/policy/device_local_account_policy_store.h"
15 #include "chrome/browser/chromeos/settings/cros_settings.h"
21 #include "chrome/browser/chromeos/settings/device_settings_service.h" 16 #include "chrome/browser/chromeos/settings/device_settings_service.h"
22 #include "chrome/browser/policy/cloud/cloud_policy_client.h" 17 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
23 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" 18 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
24 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" 19 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h"
25 #include "chrome/browser/policy/cloud/device_management_service.h" 20 #include "chrome/browser/policy/cloud/device_management_service.h"
26 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" 21 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
27 #include "chromeos/chromeos_paths.h"
28 #include "chromeos/dbus/session_manager_client.h" 22 #include "chromeos/dbus/session_manager_client.h"
29 #include "chromeos/settings/cros_settings_names.h" 23 #include "chromeos/settings/cros_settings_names.h"
30 #include "chromeos/settings/cros_settings_provider.h" 24 #include "chromeos/settings/cros_settings_provider.h"
31 #include "policy/policy_constants.h" 25 #include "policy/policy_constants.h"
32 26
33 namespace em = enterprise_management; 27 namespace em = enterprise_management;
34 28
35 namespace policy { 29 namespace policy {
36 30
37 namespace { 31 namespace {
(...skipping 14 matching lines...) Expand all
52 46
53 scoped_ptr<CloudPolicyClient> client( 47 scoped_ptr<CloudPolicyClient> client(
54 new CloudPolicyClient(std::string(), std::string(), 48 new CloudPolicyClient(std::string(), std::string(),
55 USER_AFFILIATION_MANAGED, 49 USER_AFFILIATION_MANAGED,
56 NULL, device_management_service)); 50 NULL, device_management_service));
57 client->SetupRegistration(policy_data->request_token(), 51 client->SetupRegistration(policy_data->request_token(),
58 policy_data->device_id()); 52 policy_data->device_id());
59 return client.Pass(); 53 return client.Pass();
60 } 54 }
61 55
62 // Get the subdirectory of the cache directory in which force-installed
63 // extensions are cached for |account_id|.
64 std::string GetCacheSubdirectoryForAccountID(const std::string& account_id) {
65 return base::HexEncode(account_id.c_str(), account_id.size());
66 }
67
68 // Cleans up the cache directory by removing subdirectories that are not found
69 // in |subdirectories_to_keep|. Only caches whose cache directory is found in
70 // |subdirectories_to_keep| may be running while the clean-up is in progress.
71 void DeleteOrphanedExtensionCaches(
72 const std::set<std::string>& subdirectories_to_keep) {
73 base::FilePath cache_root_dir;
74 CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_CACHE,
75 &cache_root_dir));
76 base::FileEnumerator enumerator(cache_root_dir,
77 false,
78 base::FileEnumerator::DIRECTORIES);
79 for (base::FilePath path = enumerator.Next(); !path.empty();
80 path = enumerator.Next()) {
81 const std::string subdirectory(path.BaseName().MaybeAsASCII());
82 if (subdirectories_to_keep.find(subdirectory) ==
83 subdirectories_to_keep.end()) {
84 base::DeleteFile(path, true);
85 }
86 }
87 }
88
89 // Removes the subdirectory belonging to |account_id_to_delete| from the cache
90 // directory. No cache belonging to |account_id_to_delete| may be running while
91 // the removal is in progress.
92 void DeleteObsoleteExtensionCache(const std::string& account_id_to_delete) {
93 base::FilePath cache_root_dir;
94 CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_CACHE,
95 &cache_root_dir));
96 const base::FilePath path = cache_root_dir
97 .Append(GetCacheSubdirectoryForAccountID(account_id_to_delete));
98 if (base::DirectoryExists(path))
99 base::DeleteFile(path, true);
100 }
101
102 } // namespace 56 } // namespace
103 57
104 DeviceLocalAccountPolicyBroker::DeviceLocalAccountPolicyBroker( 58 DeviceLocalAccountPolicyBroker::DeviceLocalAccountPolicyBroker(
105 const DeviceLocalAccount& account, 59 const std::string& user_id,
106 scoped_ptr<DeviceLocalAccountPolicyStore> store, 60 scoped_ptr<DeviceLocalAccountPolicyStore> store,
107 const scoped_refptr<base::SequencedTaskRunner>& task_runner) 61 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
108 : account_id_(account.account_id), 62 : user_id_(user_id),
109 user_id_(account.user_id),
110 store_(store.Pass()), 63 store_(store.Pass()),
111 core_(PolicyNamespaceKey(dm_protocol::kChromePublicAccountPolicyType, 64 core_(PolicyNamespaceKey(dm_protocol::kChromePublicAccountPolicyType,
112 store_->account_id()), 65 store_->account_id()),
113 store_.get(), 66 store_.get(),
114 task_runner) { 67 task_runner) {}
115 base::FilePath cache_root_dir;
116 CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_CACHE,
117 &cache_root_dir));
118 extension_loader_ = new chromeos::DeviceLocalAccountExternalPolicyLoader(
119 store_.get(),
120 cache_root_dir.Append(
121 GetCacheSubdirectoryForAccountID(account.account_id)));
122 }
123 68
124 DeviceLocalAccountPolicyBroker::~DeviceLocalAccountPolicyBroker() { 69 DeviceLocalAccountPolicyBroker::~DeviceLocalAccountPolicyBroker() {}
125 }
126 70
127 void DeviceLocalAccountPolicyBroker::Initialize() { 71 void DeviceLocalAccountPolicyBroker::Connect(
128 store_->Load(); 72 scoped_ptr<CloudPolicyClient> client) {
129 }
130
131 void DeviceLocalAccountPolicyBroker::ConnectIfPossible(
132 chromeos::DeviceSettingsService* device_settings_service,
133 DeviceManagementService* device_management_service) {
134 if (core_.client())
135 return;
136
137 scoped_ptr<CloudPolicyClient> client(CreateClient(device_settings_service,
138 device_management_service));
139 if (!client)
140 return;
141
142 core_.Connect(client.Pass()); 73 core_.Connect(client.Pass());
143 core_.StartRefreshScheduler(); 74 core_.StartRefreshScheduler();
144 UpdateRefreshDelay(); 75 UpdateRefreshDelay();
145 } 76 }
146 77
147 void DeviceLocalAccountPolicyBroker::Disconnect() { 78 void DeviceLocalAccountPolicyBroker::Disconnect() {
148 core_.Disconnect(); 79 core_.Disconnect();
149 } 80 }
150 81
151 void DeviceLocalAccountPolicyBroker::UpdateRefreshDelay() { 82 void DeviceLocalAccountPolicyBroker::UpdateRefreshDelay() {
152 if (core_.refresh_scheduler()) { 83 if (core_.refresh_scheduler()) {
153 const Value* policy_value = 84 const Value* policy_value =
154 store_->policy_map().GetValue(key::kPolicyRefreshRate); 85 store_->policy_map().GetValue(key::kPolicyRefreshRate);
155 int delay = 0; 86 int delay = 0;
156 if (policy_value && policy_value->GetAsInteger(&delay)) 87 if (policy_value && policy_value->GetAsInteger(&delay))
157 core_.refresh_scheduler()->SetRefreshDelay(delay); 88 core_.refresh_scheduler()->SetRefreshDelay(delay);
158 } 89 }
159 } 90 }
160 91
161 std::string DeviceLocalAccountPolicyBroker::GetDisplayName() const { 92 std::string DeviceLocalAccountPolicyBroker::GetDisplayName() const {
162 std::string display_name; 93 std::string display_name;
163 const base::Value* display_name_value = 94 const base::Value* display_name_value =
164 store_->policy_map().GetValue(policy::key::kUserDisplayName); 95 store_->policy_map().GetValue(policy::key::kUserDisplayName);
165 if (display_name_value) 96 if (display_name_value)
166 display_name_value->GetAsString(&display_name); 97 display_name_value->GetAsString(&display_name);
167 return display_name; 98 return display_name;
168 } 99 }
169 100
101 DeviceLocalAccountPolicyService::PolicyBrokerWrapper::PolicyBrokerWrapper()
102 : parent(NULL), broker(NULL) {}
103
104 DeviceLocalAccountPolicyService::PolicyBrokerWrapper::~PolicyBrokerWrapper() {}
105
106 DeviceLocalAccountPolicyBroker*
107 DeviceLocalAccountPolicyService::PolicyBrokerWrapper::GetBroker() {
108 if (!broker) {
109 scoped_ptr<DeviceLocalAccountPolicyStore> store(
110 new DeviceLocalAccountPolicyStore(account_id,
111 parent->session_manager_client_,
112 parent->device_settings_service_,
113 parent->background_task_runner_));
114 broker = new DeviceLocalAccountPolicyBroker(
115 user_id, store.Pass(), base::MessageLoopProxy::current());
116 broker->core()->store()->AddObserver(parent);
117 broker->core()->store()->Load();
118 }
119 return broker;
120 }
121
122 void DeviceLocalAccountPolicyService::PolicyBrokerWrapper::ConnectIfPossible() {
123 if (broker && broker->core()->client())
124 return;
125 scoped_ptr<CloudPolicyClient> client(CreateClient(
126 parent->device_settings_service_,
127 parent->device_management_service_));
128 if (client)
129 GetBroker()->Connect(client.Pass());
130 }
131
132 void DeviceLocalAccountPolicyService::PolicyBrokerWrapper::Disconnect() {
133 if (broker)
134 broker->Disconnect();
135 }
136
137 void DeviceLocalAccountPolicyService::PolicyBrokerWrapper::DeleteBroker() {
138 if (!broker)
139 return;
140 broker->core()->store()->RemoveObserver(parent);
141 delete broker;
142 broker = NULL;
143 }
144
170 DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService( 145 DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService(
171 chromeos::SessionManagerClient* session_manager_client, 146 chromeos::SessionManagerClient* session_manager_client,
172 chromeos::DeviceSettingsService* device_settings_service, 147 chromeos::DeviceSettingsService* device_settings_service,
173 chromeos::CrosSettings* cros_settings, 148 chromeos::CrosSettings* cros_settings,
174 scoped_refptr<base::SequencedTaskRunner> store_background_task_runner, 149 scoped_refptr<base::SequencedTaskRunner> background_task_runner)
175 scoped_refptr<base::SequencedTaskRunner> extension_cache_task_runner)
176 : session_manager_client_(session_manager_client), 150 : session_manager_client_(session_manager_client),
177 device_settings_service_(device_settings_service), 151 device_settings_service_(device_settings_service),
178 cros_settings_(cros_settings), 152 cros_settings_(cros_settings),
179 device_management_service_(NULL), 153 device_management_service_(NULL),
180 waiting_for_cros_settings_(false), 154 background_task_runner_(background_task_runner),
181 orphan_cache_deletion_state_(NOT_STARTED), 155 cros_settings_callback_factory_(this) {
182 store_background_task_runner_(store_background_task_runner), 156 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
183 extension_cache_task_runner_(extension_cache_task_runner), 157 chromeos::kAccountsPrefDeviceLocalAccounts,
184 local_accounts_subscription_(cros_settings_->AddSettingsObserver( 158 base::Bind(&DeviceLocalAccountPolicyService::
185 chromeos::kAccountsPrefDeviceLocalAccounts, 159 UpdateAccountListIfNonePending,
186 base::Bind(&DeviceLocalAccountPolicyService:: 160 base::Unretained(this)));
187 UpdateAccountListIfNonePending,
188 base::Unretained(this)))),
189 weak_factory_(this) {
190 UpdateAccountList(); 161 UpdateAccountList();
191 } 162 }
192 163
193 DeviceLocalAccountPolicyService::~DeviceLocalAccountPolicyService() { 164 DeviceLocalAccountPolicyService::~DeviceLocalAccountPolicyService() {
194 DeleteBrokers(&policy_brokers_); 165 DeleteBrokers(&policy_brokers_);
195 } 166 }
196 167
197 void DeviceLocalAccountPolicyService::Connect( 168 void DeviceLocalAccountPolicyService::Connect(
198 DeviceManagementService* device_management_service) { 169 DeviceManagementService* device_management_service) {
199 DCHECK(!device_management_service_); 170 DCHECK(!device_management_service_);
200 device_management_service_ = device_management_service; 171 device_management_service_ = device_management_service;
201 172
202 // Connect the brokers. 173 // Connect the brokers.
203 for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); 174 for (PolicyBrokerMap::iterator it(policy_brokers_.begin());
204 it != policy_brokers_.end(); ++it) { 175 it != policy_brokers_.end(); ++it) {
205 it->second->ConnectIfPossible(device_settings_service_, 176 it->second.ConnectIfPossible();
206 device_management_service_);
207 } 177 }
208 } 178 }
209 179
210 void DeviceLocalAccountPolicyService::Disconnect() { 180 void DeviceLocalAccountPolicyService::Disconnect() {
211 DCHECK(device_management_service_); 181 DCHECK(device_management_service_);
212 device_management_service_ = NULL; 182 device_management_service_ = NULL;
213 183
214 // Disconnect the brokers. 184 // Disconnect the brokers.
215 for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); 185 for (PolicyBrokerMap::iterator it(policy_brokers_.begin());
216 it != policy_brokers_.end(); ++it) { 186 it != policy_brokers_.end(); ++it) {
217 it->second->Disconnect(); 187 it->second.Disconnect();
218 } 188 }
219 } 189 }
220 190
221 DeviceLocalAccountPolicyBroker* 191 DeviceLocalAccountPolicyBroker*
222 DeviceLocalAccountPolicyService::GetBrokerForUser( 192 DeviceLocalAccountPolicyService::GetBrokerForUser(
223 const std::string& user_id) { 193 const std::string& user_id) {
224 PolicyBrokerMap::iterator entry = policy_brokers_.find(user_id); 194 PolicyBrokerMap::iterator entry = policy_brokers_.find(user_id);
225 if (entry == policy_brokers_.end()) 195 if (entry == policy_brokers_.end())
226 return NULL; 196 return NULL;
227 197
228 return entry->second; 198 return entry->second.GetBroker();
229 } 199 }
230 200
231 bool DeviceLocalAccountPolicyService::IsPolicyAvailableForUser( 201 bool DeviceLocalAccountPolicyService::IsPolicyAvailableForUser(
232 const std::string& user_id) { 202 const std::string& user_id) {
233 DeviceLocalAccountPolicyBroker* broker = GetBrokerForUser(user_id); 203 DeviceLocalAccountPolicyBroker* broker = GetBrokerForUser(user_id);
234 return broker && broker->core()->store()->is_managed(); 204 return broker && broker->core()->store()->is_managed();
235 } 205 }
236 206
237 void DeviceLocalAccountPolicyService::AddObserver(Observer* observer) { 207 void DeviceLocalAccountPolicyService::AddObserver(Observer* observer) {
238 observers_.AddObserver(observer); 208 observers_.AddObserver(observer);
(...skipping 13 matching lines...) Expand all
252 } 222 }
253 223
254 void DeviceLocalAccountPolicyService::OnStoreError(CloudPolicyStore* store) { 224 void DeviceLocalAccountPolicyService::OnStoreError(CloudPolicyStore* store) {
255 DeviceLocalAccountPolicyBroker* broker = GetBrokerForStore(store); 225 DeviceLocalAccountPolicyBroker* broker = GetBrokerForStore(store);
256 DCHECK(broker); 226 DCHECK(broker);
257 if (!broker) 227 if (!broker)
258 return; 228 return;
259 FOR_EACH_OBSERVER(Observer, observers_, OnPolicyUpdated(broker->user_id())); 229 FOR_EACH_OBSERVER(Observer, observers_, OnPolicyUpdated(broker->user_id()));
260 } 230 }
261 231
262 bool DeviceLocalAccountPolicyService::IsExtensionCacheDirectoryBusy(
263 const std::string& account_id) {
264 return busy_extension_cache_directories_.find(account_id) !=
265 busy_extension_cache_directories_.end();
266 }
267
268 void DeviceLocalAccountPolicyService::StartExtensionCachesIfPossible() {
269 for (PolicyBrokerMap::iterator it = policy_brokers_.begin();
270 it != policy_brokers_.end(); ++it) {
271 if (!it->second->extension_loader()->IsCacheRunning() &&
272 !IsExtensionCacheDirectoryBusy(it->second->account_id())) {
273 it->second->extension_loader()->StartCache(extension_cache_task_runner_);
274 }
275 }
276 }
277
278 bool DeviceLocalAccountPolicyService::StartExtensionCacheForAccountIfPresent(
279 const std::string& account_id) {
280 for (PolicyBrokerMap::iterator it = policy_brokers_.begin();
281 it != policy_brokers_.end(); ++it) {
282 if (it->second->account_id() == account_id) {
283 DCHECK(!it->second->extension_loader()->IsCacheRunning());
284 it->second->extension_loader()->StartCache(extension_cache_task_runner_);
285 return true;
286 }
287 }
288 return false;
289 }
290
291 void DeviceLocalAccountPolicyService::OnOrphanedExtensionCachesDeleted() {
292 DCHECK_EQ(IN_PROGRESS, orphan_cache_deletion_state_);
293
294 orphan_cache_deletion_state_ = DONE;
295 StartExtensionCachesIfPossible();
296 }
297
298 void DeviceLocalAccountPolicyService::OnObsoleteExtensionCacheShutdown(
299 const std::string& account_id) {
300 DCHECK_NE(NOT_STARTED, orphan_cache_deletion_state_);
301 DCHECK(IsExtensionCacheDirectoryBusy(account_id));
302
303 // The account with |account_id| was deleted and the broker for it has shut
304 // down completely.
305
306 if (StartExtensionCacheForAccountIfPresent(account_id)) {
307 // If another account with the same ID was created in the meantime, its
308 // extension cache is started, reusing the cache directory. The directory no
309 // longer needs to be marked as busy in this case.
310 busy_extension_cache_directories_.erase(account_id);
311 return;
312 }
313
314 // If no account with |account_id| exists anymore, the cache directory should
315 // be removed. The directory must stay marked as busy while the removal is in
316 // progress.
317 extension_cache_task_runner_->PostTaskAndReply(
318 FROM_HERE,
319 base::Bind(&DeleteObsoleteExtensionCache, account_id),
320 base::Bind(&DeviceLocalAccountPolicyService::
321 OnObsoleteExtensionCacheDeleted,
322 weak_factory_.GetWeakPtr(),
323 account_id));
324 }
325
326 void DeviceLocalAccountPolicyService::OnObsoleteExtensionCacheDeleted(
327 const std::string& account_id) {
328 DCHECK_EQ(DONE, orphan_cache_deletion_state_);
329 DCHECK(IsExtensionCacheDirectoryBusy(account_id));
330
331 // The cache directory for |account_id| has been deleted. The directory no
332 // longer needs to be marked as busy.
333 busy_extension_cache_directories_.erase(account_id);
334
335 // If another account with the same ID was created in the meantime, start its
336 // extension cache, creating a new cache directory.
337 StartExtensionCacheForAccountIfPresent(account_id);
338 }
339
340 void DeviceLocalAccountPolicyService::UpdateAccountListIfNonePending() { 232 void DeviceLocalAccountPolicyService::UpdateAccountListIfNonePending() {
341 // Avoid unnecessary calls to UpdateAccountList(): If an earlier call is still 233 // Avoid unnecessary calls to UpdateAccountList(): If an earlier call is still
342 // pending (because the |cros_settings_| are not trusted yet), the updated 234 // pending (because the |cros_settings_| are not trusted yet), the updated
343 // account list will be processed by that call when it eventually runs. 235 // account list will be processed by that call when it eventually runs.
344 if (!waiting_for_cros_settings_) 236 if (!cros_settings_callback_factory_.HasWeakPtrs())
345 UpdateAccountList(); 237 UpdateAccountList();
346 } 238 }
347 239
348 void DeviceLocalAccountPolicyService::UpdateAccountList() { 240 void DeviceLocalAccountPolicyService::UpdateAccountList() {
349 chromeos::CrosSettingsProvider::TrustedStatus status = 241 if (chromeos::CrosSettingsProvider::TRUSTED !=
350 cros_settings_->PrepareTrustedValues( 242 cros_settings_->PrepareTrustedValues(
351 base::Bind(&DeviceLocalAccountPolicyService::UpdateAccountList, 243 base::Bind(&DeviceLocalAccountPolicyService::UpdateAccountList,
352 weak_factory_.GetWeakPtr())); 244 cros_settings_callback_factory_.GetWeakPtr()))) {
353 switch (status) { 245 return;
354 case chromeos::CrosSettingsProvider::TRUSTED:
355 waiting_for_cros_settings_ = false;
356 break;
357 case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED:
358 waiting_for_cros_settings_ = true;
359 return;
360 case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED:
361 waiting_for_cros_settings_ = false;
362 return;
363 } 246 }
364 247
365 // Update |policy_brokers_|, keeping existing entries. 248 // Update |policy_brokers_|, keeping existing entries.
366 PolicyBrokerMap old_policy_brokers; 249 PolicyBrokerMap old_policy_brokers;
367 policy_brokers_.swap(old_policy_brokers); 250 policy_brokers_.swap(old_policy_brokers);
368 std::set<std::string> subdirectories_to_keep;
369 const std::vector<DeviceLocalAccount> device_local_accounts = 251 const std::vector<DeviceLocalAccount> device_local_accounts =
370 GetDeviceLocalAccounts(cros_settings_); 252 GetDeviceLocalAccounts(cros_settings_);
371 for (std::vector<DeviceLocalAccount>::const_iterator it = 253 for (std::vector<DeviceLocalAccount>::const_iterator it =
372 device_local_accounts.begin(); 254 device_local_accounts.begin();
373 it != device_local_accounts.end(); ++it) { 255 it != device_local_accounts.end(); ++it) {
374 PolicyBrokerMap::iterator broker_it = old_policy_brokers.find(it->user_id); 256 PolicyBrokerWrapper& wrapper = policy_brokers_[it->user_id];
257 wrapper.user_id = it->user_id;
258 wrapper.account_id = it->account_id;
259 wrapper.parent = this;
375 260
376 scoped_ptr<DeviceLocalAccountPolicyBroker> broker; 261 // Reuse the existing broker if present.
377 bool broker_initialized = false; 262 PolicyBrokerWrapper& existing_wrapper = old_policy_brokers[it->user_id];
378 if (broker_it != old_policy_brokers.end()) { 263 wrapper.broker = existing_wrapper.broker;
379 // Reuse the existing broker if present. 264 existing_wrapper.broker = NULL;
380 broker.reset(broker_it->second);
381 old_policy_brokers.erase(broker_it);
382 broker_initialized = true;
383 } else {
384 scoped_ptr<DeviceLocalAccountPolicyStore> store(
385 new DeviceLocalAccountPolicyStore(it->account_id,
386 session_manager_client_,
387 device_settings_service_,
388 store_background_task_runner_));
389 store->AddObserver(this);
390 broker.reset(new DeviceLocalAccountPolicyBroker(
391 *it,
392 store.Pass(),
393 base::MessageLoopProxy::current()));
394 }
395 265
396 // Fire up the cloud connection for fetching policy for the account from 266 // Fire up the cloud connection for fetching policy for the account from
397 // the cloud if this is an enterprise-managed device. 267 // the cloud if this is an enterprise-managed device.
398 broker->ConnectIfPossible(device_settings_service_, 268 wrapper.ConnectIfPossible();
399 device_management_service_);
400
401 policy_brokers_[it->user_id] = broker.release();
402 if (!broker_initialized) {
403 // The broker must be initialized after it has been added to
404 // |policy_brokers_|.
405 policy_brokers_[it->user_id]->Initialize();
406 }
407
408 if (orphan_cache_deletion_state_ == NOT_STARTED) {
409 subdirectories_to_keep.insert(
410 GetCacheSubdirectoryForAccountID(it->account_id));
411 }
412 } 269 }
413 270 DeleteBrokers(&old_policy_brokers);
414 std::set<std::string> obsolete_account_ids;
415 for (PolicyBrokerMap::const_iterator it = old_policy_brokers.begin();
416 it != old_policy_brokers.end(); ++it) {
417 obsolete_account_ids.insert(it->second->account_id());
418 }
419
420 if (orphan_cache_deletion_state_ == NOT_STARTED) {
421 DCHECK(old_policy_brokers.empty());
422 DCHECK(busy_extension_cache_directories_.empty());
423
424 // If this method is running for the first time, no extension caches have
425 // been started yet. Take this opportunity to do a clean-up by removing
426 // orphaned cache directories not found in |subdirectories_to_keep| from the
427 // cache directory.
428 orphan_cache_deletion_state_ = IN_PROGRESS;
429 extension_cache_task_runner_->PostTaskAndReply(
430 FROM_HERE,
431 base::Bind(&DeleteOrphanedExtensionCaches, subdirectories_to_keep),
432 base::Bind(&DeviceLocalAccountPolicyService::
433 OnOrphanedExtensionCachesDeleted,
434 weak_factory_.GetWeakPtr()));
435
436 // Start the extension caches for all brokers. These belong to accounts in
437 // |account_ids| and are not affected by the clean-up.
438 StartExtensionCachesIfPossible();
439 } else {
440 // If this method has run before, obsolete brokers may exist. Shut down
441 // their extension caches and delete the brokers.
442 DeleteBrokers(&old_policy_brokers);
443
444 if (orphan_cache_deletion_state_ == DONE) {
445 // If the initial clean-up of orphaned cache directories has been
446 // complete, start any extension caches that are not running yet but can
447 // be started now because their cache directories are not busy.
448 StartExtensionCachesIfPossible();
449 }
450 }
451 271
452 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceLocalAccountsChanged()); 272 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceLocalAccountsChanged());
453 } 273 }
454 274
455 void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) { 275 void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) {
456 for (PolicyBrokerMap::iterator it = map->begin(); it != map->end(); ++it) { 276 for (PolicyBrokerMap::iterator it = map->begin(); it != map->end(); ++it)
457 it->second->core()->store()->RemoveObserver(this); 277 it->second.DeleteBroker();
458 scoped_refptr<chromeos::DeviceLocalAccountExternalPolicyLoader>
459 extension_loader = it->second->extension_loader();
460 if (extension_loader->IsCacheRunning()) {
461 DCHECK(!IsExtensionCacheDirectoryBusy(it->second->account_id()));
462 busy_extension_cache_directories_.insert(it->second->account_id());
463 extension_loader->StopCache(base::Bind(
464 &DeviceLocalAccountPolicyService::OnObsoleteExtensionCacheShutdown,
465 weak_factory_.GetWeakPtr(),
466 it->second->account_id()));
467 }
468 delete it->second;
469 }
470 map->clear(); 278 map->clear();
471 } 279 }
472 280
473 DeviceLocalAccountPolicyBroker* 281 DeviceLocalAccountPolicyBroker*
474 DeviceLocalAccountPolicyService::GetBrokerForStore( 282 DeviceLocalAccountPolicyService::GetBrokerForStore(
475 CloudPolicyStore* store) { 283 CloudPolicyStore* store) {
476 for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); 284 for (PolicyBrokerMap::iterator it(policy_brokers_.begin());
477 it != policy_brokers_.end(); ++it) { 285 it != policy_brokers_.end(); ++it) {
478 if (it->second->core()->store() == store) 286 if (it->second.broker && it->second.broker->core()->store() == store)
479 return it->second; 287 return it->second.broker;
480 } 288 }
481 return NULL; 289 return NULL;
482 } 290 }
483 291
484 } // namespace policy 292 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698