Chromium Code Reviews| 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 |