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

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

Powered by Google App Engine
This is Rietveld 408576698