OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |