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