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