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

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

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

Powered by Google App Engine
This is Rietveld 408576698