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

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: Rebased. Ready to reland after revert due to conflicting concurrent commit. 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 }
68 123
69 DeviceLocalAccountPolicyBroker::~DeviceLocalAccountPolicyBroker() {} 124 DeviceLocalAccountPolicyBroker::~DeviceLocalAccountPolicyBroker() {
125 }
70 126
71 void DeviceLocalAccountPolicyBroker::Connect( 127 void DeviceLocalAccountPolicyBroker::Initialize() {
72 scoped_ptr<CloudPolicyClient> client) { 128 store_->Load();
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
73 core_.Connect(client.Pass()); 142 core_.Connect(client.Pass());
74 core_.StartRefreshScheduler(); 143 core_.StartRefreshScheduler();
75 UpdateRefreshDelay(); 144 UpdateRefreshDelay();
76 } 145 }
77 146
78 void DeviceLocalAccountPolicyBroker::Disconnect() { 147 void DeviceLocalAccountPolicyBroker::Disconnect() {
79 core_.Disconnect(); 148 core_.Disconnect();
80 } 149 }
81 150
82 void DeviceLocalAccountPolicyBroker::UpdateRefreshDelay() { 151 void DeviceLocalAccountPolicyBroker::UpdateRefreshDelay() {
83 if (core_.refresh_scheduler()) { 152 if (core_.refresh_scheduler()) {
84 const Value* policy_value = 153 const Value* policy_value =
85 store_->policy_map().GetValue(key::kPolicyRefreshRate); 154 store_->policy_map().GetValue(key::kPolicyRefreshRate);
86 int delay = 0; 155 int delay = 0;
87 if (policy_value && policy_value->GetAsInteger(&delay)) 156 if (policy_value && policy_value->GetAsInteger(&delay))
88 core_.refresh_scheduler()->SetRefreshDelay(delay); 157 core_.refresh_scheduler()->SetRefreshDelay(delay);
89 } 158 }
90 } 159 }
91 160
92 std::string DeviceLocalAccountPolicyBroker::GetDisplayName() const { 161 std::string DeviceLocalAccountPolicyBroker::GetDisplayName() const {
93 std::string display_name; 162 std::string display_name;
94 const base::Value* display_name_value = 163 const base::Value* display_name_value =
95 store_->policy_map().GetValue(policy::key::kUserDisplayName); 164 store_->policy_map().GetValue(policy::key::kUserDisplayName);
96 if (display_name_value) 165 if (display_name_value)
97 display_name_value->GetAsString(&display_name); 166 display_name_value->GetAsString(&display_name);
98 return display_name; 167 return display_name;
99 } 168 }
100 169
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
145 DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService( 170 DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService(
146 chromeos::SessionManagerClient* session_manager_client, 171 chromeos::SessionManagerClient* session_manager_client,
147 chromeos::DeviceSettingsService* device_settings_service, 172 chromeos::DeviceSettingsService* device_settings_service,
148 chromeos::CrosSettings* cros_settings, 173 chromeos::CrosSettings* cros_settings,
149 scoped_refptr<base::SequencedTaskRunner> background_task_runner) 174 scoped_refptr<base::SequencedTaskRunner> store_background_task_runner,
175 scoped_refptr<base::SequencedTaskRunner> extension_cache_task_runner)
150 : session_manager_client_(session_manager_client), 176 : session_manager_client_(session_manager_client),
151 device_settings_service_(device_settings_service), 177 device_settings_service_(device_settings_service),
152 cros_settings_(cros_settings), 178 cros_settings_(cros_settings),
153 device_management_service_(NULL), 179 device_management_service_(NULL),
154 background_task_runner_(background_task_runner), 180 waiting_for_cros_settings_(false),
155 cros_settings_callback_factory_(this) { 181 orphan_cache_deletion_state_(NOT_STARTED),
156 local_accounts_subscription_ = cros_settings_->AddSettingsObserver( 182 store_background_task_runner_(store_background_task_runner),
157 chromeos::kAccountsPrefDeviceLocalAccounts, 183 extension_cache_task_runner_(extension_cache_task_runner),
158 base::Bind(&DeviceLocalAccountPolicyService:: 184 local_accounts_subscription_(cros_settings_->AddSettingsObserver(
159 UpdateAccountListIfNonePending, 185 chromeos::kAccountsPrefDeviceLocalAccounts,
160 base::Unretained(this))); 186 base::Bind(&DeviceLocalAccountPolicyService::
187 UpdateAccountListIfNonePending,
188 base::Unretained(this)))),
189 weak_factory_(this) {
161 UpdateAccountList(); 190 UpdateAccountList();
162 } 191 }
163 192
164 DeviceLocalAccountPolicyService::~DeviceLocalAccountPolicyService() { 193 DeviceLocalAccountPolicyService::~DeviceLocalAccountPolicyService() {
165 DeleteBrokers(&policy_brokers_); 194 DeleteBrokers(&policy_brokers_);
166 } 195 }
167 196
168 void DeviceLocalAccountPolicyService::Connect( 197 void DeviceLocalAccountPolicyService::Connect(
169 DeviceManagementService* device_management_service) { 198 DeviceManagementService* device_management_service) {
170 DCHECK(!device_management_service_); 199 DCHECK(!device_management_service_);
171 device_management_service_ = device_management_service; 200 device_management_service_ = device_management_service;
172 201
173 // Connect the brokers. 202 // Connect the brokers.
174 for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); 203 for (PolicyBrokerMap::iterator it(policy_brokers_.begin());
175 it != policy_brokers_.end(); ++it) { 204 it != policy_brokers_.end(); ++it) {
176 it->second.ConnectIfPossible(); 205 it->second->ConnectIfPossible(device_settings_service_,
206 device_management_service_);
177 } 207 }
178 } 208 }
179 209
180 void DeviceLocalAccountPolicyService::Disconnect() { 210 void DeviceLocalAccountPolicyService::Disconnect() {
181 DCHECK(device_management_service_); 211 DCHECK(device_management_service_);
182 device_management_service_ = NULL; 212 device_management_service_ = NULL;
183 213
184 // Disconnect the brokers. 214 // Disconnect the brokers.
185 for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); 215 for (PolicyBrokerMap::iterator it(policy_brokers_.begin());
186 it != policy_brokers_.end(); ++it) { 216 it != policy_brokers_.end(); ++it) {
187 it->second.Disconnect(); 217 it->second->Disconnect();
188 } 218 }
189 } 219 }
190 220
191 DeviceLocalAccountPolicyBroker* 221 DeviceLocalAccountPolicyBroker*
192 DeviceLocalAccountPolicyService::GetBrokerForUser( 222 DeviceLocalAccountPolicyService::GetBrokerForUser(
193 const std::string& user_id) { 223 const std::string& user_id) {
194 PolicyBrokerMap::iterator entry = policy_brokers_.find(user_id); 224 PolicyBrokerMap::iterator entry = policy_brokers_.find(user_id);
195 if (entry == policy_brokers_.end()) 225 if (entry == policy_brokers_.end())
196 return NULL; 226 return NULL;
197 227
198 return entry->second.GetBroker(); 228 return entry->second;
199 } 229 }
200 230
201 bool DeviceLocalAccountPolicyService::IsPolicyAvailableForUser( 231 bool DeviceLocalAccountPolicyService::IsPolicyAvailableForUser(
202 const std::string& user_id) { 232 const std::string& user_id) {
203 DeviceLocalAccountPolicyBroker* broker = GetBrokerForUser(user_id); 233 DeviceLocalAccountPolicyBroker* broker = GetBrokerForUser(user_id);
204 return broker && broker->core()->store()->is_managed(); 234 return broker && broker->core()->store()->is_managed();
205 } 235 }
206 236
207 void DeviceLocalAccountPolicyService::AddObserver(Observer* observer) { 237 void DeviceLocalAccountPolicyService::AddObserver(Observer* observer) {
208 observers_.AddObserver(observer); 238 observers_.AddObserver(observer);
(...skipping 13 matching lines...) Expand all
222 } 252 }
223 253
224 void DeviceLocalAccountPolicyService::OnStoreError(CloudPolicyStore* store) { 254 void DeviceLocalAccountPolicyService::OnStoreError(CloudPolicyStore* store) {
225 DeviceLocalAccountPolicyBroker* broker = GetBrokerForStore(store); 255 DeviceLocalAccountPolicyBroker* broker = GetBrokerForStore(store);
226 DCHECK(broker); 256 DCHECK(broker);
227 if (!broker) 257 if (!broker)
228 return; 258 return;
229 FOR_EACH_OBSERVER(Observer, observers_, OnPolicyUpdated(broker->user_id())); 259 FOR_EACH_OBSERVER(Observer, observers_, OnPolicyUpdated(broker->user_id()));
230 } 260 }
231 261
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
232 void DeviceLocalAccountPolicyService::UpdateAccountListIfNonePending() { 340 void DeviceLocalAccountPolicyService::UpdateAccountListIfNonePending() {
233 // Avoid unnecessary calls to UpdateAccountList(): If an earlier call is still 341 // Avoid unnecessary calls to UpdateAccountList(): If an earlier call is still
234 // pending (because the |cros_settings_| are not trusted yet), the updated 342 // pending (because the |cros_settings_| are not trusted yet), the updated
235 // account list will be processed by that call when it eventually runs. 343 // account list will be processed by that call when it eventually runs.
236 if (!cros_settings_callback_factory_.HasWeakPtrs()) 344 if (!waiting_for_cros_settings_)
237 UpdateAccountList(); 345 UpdateAccountList();
238 } 346 }
239 347
240 void DeviceLocalAccountPolicyService::UpdateAccountList() { 348 void DeviceLocalAccountPolicyService::UpdateAccountList() {
241 if (chromeos::CrosSettingsProvider::TRUSTED != 349 chromeos::CrosSettingsProvider::TrustedStatus status =
242 cros_settings_->PrepareTrustedValues( 350 cros_settings_->PrepareTrustedValues(
243 base::Bind(&DeviceLocalAccountPolicyService::UpdateAccountList, 351 base::Bind(&DeviceLocalAccountPolicyService::UpdateAccountList,
244 cros_settings_callback_factory_.GetWeakPtr()))) { 352 weak_factory_.GetWeakPtr()));
245 return; 353 switch (status) {
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;
246 } 363 }
247 364
248 // Update |policy_brokers_|, keeping existing entries. 365 // Update |policy_brokers_|, keeping existing entries.
249 PolicyBrokerMap old_policy_brokers; 366 PolicyBrokerMap old_policy_brokers;
250 policy_brokers_.swap(old_policy_brokers); 367 policy_brokers_.swap(old_policy_brokers);
368 std::set<std::string> subdirectories_to_keep;
251 const std::vector<DeviceLocalAccount> device_local_accounts = 369 const std::vector<DeviceLocalAccount> device_local_accounts =
252 GetDeviceLocalAccounts(cros_settings_); 370 GetDeviceLocalAccounts(cros_settings_);
253 for (std::vector<DeviceLocalAccount>::const_iterator it = 371 for (std::vector<DeviceLocalAccount>::const_iterator it =
254 device_local_accounts.begin(); 372 device_local_accounts.begin();
255 it != device_local_accounts.end(); ++it) { 373 it != device_local_accounts.end(); ++it) {
256 PolicyBrokerWrapper& wrapper = policy_brokers_[it->user_id]; 374 PolicyBrokerMap::iterator broker_it = old_policy_brokers.find(it->user_id);
257 wrapper.user_id = it->user_id; 375
258 wrapper.account_id = it->account_id; 376 scoped_ptr<DeviceLocalAccountPolicyBroker> broker;
259 wrapper.parent = this; 377 bool broker_initialized = false;
260 378 if (broker_it != old_policy_brokers.end()) {
261 // Reuse the existing broker if present. 379 // Reuse the existing broker if present.
262 PolicyBrokerWrapper& existing_wrapper = old_policy_brokers[it->user_id]; 380 broker.reset(broker_it->second);
263 wrapper.broker = existing_wrapper.broker; 381 old_policy_brokers.erase(broker_it);
264 existing_wrapper.broker = NULL; 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 }
265 395
266 // Fire up the cloud connection for fetching policy for the account from 396 // Fire up the cloud connection for fetching policy for the account from
267 // the cloud if this is an enterprise-managed device. 397 // the cloud if this is an enterprise-managed device.
268 wrapper.ConnectIfPossible(); 398 broker->ConnectIfPossible(device_settings_service_,
269 } 399 device_management_service_);
270 DeleteBrokers(&old_policy_brokers); 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 }
413
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 }
271 451
272 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceLocalAccountsChanged()); 452 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceLocalAccountsChanged());
273 } 453 }
274 454
275 void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) { 455 void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) {
276 for (PolicyBrokerMap::iterator it = map->begin(); it != map->end(); ++it) 456 for (PolicyBrokerMap::iterator it = map->begin(); it != map->end(); ++it) {
277 it->second.DeleteBroker(); 457 it->second->core()->store()->RemoveObserver(this);
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 }
278 map->clear(); 470 map->clear();
279 } 471 }
280 472
281 DeviceLocalAccountPolicyBroker* 473 DeviceLocalAccountPolicyBroker*
282 DeviceLocalAccountPolicyService::GetBrokerForStore( 474 DeviceLocalAccountPolicyService::GetBrokerForStore(
283 CloudPolicyStore* store) { 475 CloudPolicyStore* store) {
284 for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); 476 for (PolicyBrokerMap::iterator it(policy_brokers_.begin());
285 it != policy_brokers_.end(); ++it) { 477 it != policy_brokers_.end(); ++it) {
286 if (it->second.broker && it->second.broker->core()->store() == store) 478 if (it->second->core()->store() == store)
287 return it->second.broker; 479 return it->second;
288 } 480 }
289 return NULL; 481 return NULL;
290 } 482 }
291 483
292 } // namespace policy 484 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698