12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <vector> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h" 106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/bind_helpers.h" 116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/command_line.h" 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/files/file_enumerator.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/path_service.h" 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/sequenced_task_runner.h" 196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/stl_util.h" 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/browser_process.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_external_data_service.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_policy_store.h" 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_service.h" 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/common/chrome_content_client.h" 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/chromeos_paths.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/session_manager_client.h" 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h" 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_provider.h" 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/policy/core/browser/browser_policy_connector.h" 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_client.h" 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h" 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h" 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/device_management_service.h" 366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/policy/core/common/cloud/resource_cache.h" 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/system_policy_request_context.h" 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/policy/core/common/policy_namespace.h" 396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/policy/core/common/policy_switches.h" 406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "policy/policy_constants.h" 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h" 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "url/gurl.h" 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace em = enterprise_management; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace policy { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Creates and initializes a cloud policy client. Returns NULL if the device 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// doesn't have credentials in device settings (i.e. is not 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// enterprise-enrolled). 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_ptr<CloudPolicyClient> CreateClient( 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chromeos::DeviceSettingsService* device_settings_service, 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceManagementService* device_management_service, 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> system_request_context) { 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const em::PolicyData* policy_data = device_settings_service->policy_data(); 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!policy_data || 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !policy_data->has_request_token() || 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !policy_data->has_device_id() || 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !device_management_service) { 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return scoped_ptr<CloudPolicyClient>(); 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context = 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new SystemPolicyRequestContext( 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) system_request_context, GetUserAgent()); 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<CloudPolicyClient> client( 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new CloudPolicyClient(std::string(), std::string(), 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kPolicyVerificationKeyHash, 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) USER_AFFILIATION_MANAGED, 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NULL, device_management_service, request_context)); 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) client->SetupRegistration(policy_data->request_token(), 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) policy_data->device_id()); 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return client.Pass(); 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Get the subdirectory of the force-installed extension cache and the component 826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// policy cache used for |account_id|. 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string GetCacheSubdirectoryForAccountID(const std::string& account_id) { 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return base::HexEncode(account_id.c_str(), account_id.size()); 858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Cleans up the cache directory by removing subdirectories that are not found 888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// in |subdirectories_to_keep|. Only caches whose cache directory is found in 898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// |subdirectories_to_keep| may be running while the clean-up is in progress. 906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void DeleteOrphanedCaches( 916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const base::FilePath& cache_root_dir, 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::set<std::string>& subdirectories_to_keep) { 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::FileEnumerator enumerator(cache_root_dir, 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) false, 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::FileEnumerator::DIRECTORIES); 968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (base::FilePath path = enumerator.Next(); !path.empty(); 978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) path = enumerator.Next()) { 988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string subdirectory(path.BaseName().MaybeAsASCII()); 996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (!ContainsKey(subdirectories_to_keep, subdirectory)) 1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::DeleteFile(path, true); 1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Removes the subdirectory belonging to |account_id_to_delete| from the cache 1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// directory. No cache belonging to |account_id_to_delete| may be running while 1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// the removal is in progress. 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DeleteObsoleteExtensionCache(const std::string& account_id_to_delete) { 1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::FilePath cache_root_dir; 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS, 1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &cache_root_dir)); 1116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const base::FilePath path = cache_root_dir.Append( 1126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GetCacheSubdirectoryForAccountID(account_id_to_delete)); 1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (base::DirectoryExists(path)) 1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::DeleteFile(path, true); 1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyBroker::DeviceLocalAccountPolicyBroker( 1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const DeviceLocalAccount& account, 1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const base::FilePath& component_policy_cache_path, 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<DeviceLocalAccountPolicyStore> store, 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<DeviceLocalAccountExternalDataManager> external_data_manager, 1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const base::Closure& policy_update_callback, 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const scoped_refptr<base::SequencedTaskRunner>& task_runner) 1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : account_id_(account.account_id), 1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) user_id_(account.user_id), 1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) component_policy_cache_path_(component_policy_cache_path), 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) store_(store.Pass()), 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_tracker_(account, store_.get(), &schema_registry_), 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_manager_(external_data_manager), 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) core_(PolicyNamespaceKey(dm_protocol::kChromePublicAccountPolicyType, 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_->account_id()), 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) store_.get(), 1356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) task_runner), 1366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) policy_update_callback_(policy_update_callback) { 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::FilePath cache_root_dir; 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS, 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &cache_root_dir)); 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_loader_ = new chromeos::DeviceLocalAccountExternalPolicyLoader( 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) store_.get(), 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cache_root_dir.Append( 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetCacheSubdirectoryForAccountID(account.account_id))); 1446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) store_->AddObserver(this); 1456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Unblock the |schema_registry_| so that the |component_policy_service_| 1476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // starts using it. 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch schema_registry_.RegisterComponent( 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PolicyNamespace(POLICY_DOMAIN_CHROME, ""), 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch g_browser_process->browser_policy_connector()->GetChromeSchema()); 1516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) schema_registry_.SetReady(POLICY_DOMAIN_CHROME); 1526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) schema_registry_.SetReady(POLICY_DOMAIN_EXTENSIONS); 1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DeviceLocalAccountPolicyBroker::~DeviceLocalAccountPolicyBroker() { 1566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) store_->RemoveObserver(this); 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_manager_->SetPolicyStore(NULL); 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_manager_->Disconnect(); 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DeviceLocalAccountPolicyBroker::Initialize() { 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) store_->Load(); 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DeviceLocalAccountPolicyBroker::ConnectIfPossible( 1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) chromeos::DeviceSettingsService* device_settings_service, 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DeviceManagementService* device_management_service, 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context) { 1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (core_.client()) 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<CloudPolicyClient> client(CreateClient(device_settings_service, 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_management_service, 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request_context)); 1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!client) 1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) core_.Connect(client.Pass()); 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_manager_->Connect(request_context); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) core_.StartRefreshScheduler(); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateRefreshDelay(); 1826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CreateComponentCloudPolicyService(request_context); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyBroker::UpdateRefreshDelay() { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (core_.refresh_scheduler()) { 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Value* policy_value = 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_->policy_map().GetValue(key::kPolicyRefreshRate); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int delay = 0; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (policy_value && policy_value->GetAsInteger(&delay)) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) core_.refresh_scheduler()->SetRefreshDelay(delay); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DeviceLocalAccountPolicyBroker::GetDisplayName() const { 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string display_name; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Value* display_name_value = 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) store_->policy_map().GetValue(policy::key::kUserDisplayName); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (display_name_value) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_name_value->GetAsString(&display_name); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return display_name; 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void DeviceLocalAccountPolicyBroker::OnStoreLoaded(CloudPolicyStore* store) { 2056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) UpdateRefreshDelay(); 2066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) policy_update_callback_.Run(); 2076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 2086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 2096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void DeviceLocalAccountPolicyBroker::OnStoreError(CloudPolicyStore* store) { 2106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) policy_update_callback_.Run(); 2116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 2126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 2136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void DeviceLocalAccountPolicyBroker::OnComponentCloudPolicyUpdated() { 2146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) policy_update_callback_.Run(); 2156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 2166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 2176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void DeviceLocalAccountPolicyBroker::CreateComponentCloudPolicyService( 2186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const scoped_refptr<net::URLRequestContextGetter>& request_context) { 2196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 2206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kDisableComponentCloudPolicy)) { 2216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Disabled via the command line. 2226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 2236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 2246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 2256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_ptr<ResourceCache> resource_cache( 2266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) new ResourceCache(component_policy_cache_path_, 2276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) content::BrowserThread::GetMessageLoopProxyForThread( 2286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) content::BrowserThread::FILE))); 2296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 2306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) component_policy_service_.reset(new ComponentCloudPolicyService( 2316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) this, 2326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) &schema_registry_, 2336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) core(), 2346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) resource_cache.Pass(), 2356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) request_context, 2366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) content::BrowserThread::GetMessageLoopProxyForThread( 2376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) content::BrowserThread::FILE), 2386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) content::BrowserThread::GetMessageLoopProxyForThread( 2396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) content::BrowserThread::IO))); 2406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 2416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService( 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chromeos::SessionManagerClient* session_manager_client, 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chromeos::DeviceSettingsService* device_settings_service, 2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) chromeos::CrosSettings* cros_settings, 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> store_background_task_runner, 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> extension_cache_task_runner, 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_service_backend_task_runner, 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> io_task_runner, 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : session_manager_client_(session_manager_client), 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_settings_service_(device_settings_service), 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) cros_settings_(cros_settings), 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) device_management_service_(NULL), 2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) waiting_for_cros_settings_(false), 2576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) orphan_extension_cache_deletion_state_(NOT_STARTED), 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) store_background_task_runner_(store_background_task_runner), 2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_cache_task_runner_(extension_cache_task_runner), 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_context_(request_context), 2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) local_accounts_subscription_(cros_settings_->AddSettingsObserver( 2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) chromeos::kAccountsPrefDeviceLocalAccounts, 2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&DeviceLocalAccountPolicyService:: 2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateAccountListIfNonePending, 2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Unretained(this)))), 2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) weak_factory_(this) { 2676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_COMPONENT_POLICY, 2686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) &component_policy_cache_root_)); 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_service_.reset(new DeviceLocalAccountExternalDataService( 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) this, 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_service_backend_task_runner, 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) io_task_runner)); 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateAccountList(); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyService::~DeviceLocalAccountPolicyService() { 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!request_context_.get()); 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(policy_brokers_.empty()); 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DeviceLocalAccountPolicyService::Shutdown() { 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_management_service_ = NULL; 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_context_ = NULL; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeleteBrokers(&policy_brokers_); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyService::Connect( 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceManagementService* device_management_service) { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!device_management_service_); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_management_service_ = device_management_service; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Connect the brokers. 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != policy_brokers_.end(); ++it) { 2958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) it->second->ConnectIfPossible(device_settings_service_, 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_management_service_, 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_context_); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyBroker* 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DeviceLocalAccountPolicyService::GetBrokerForUser( 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& user_id) { 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PolicyBrokerMap::iterator entry = policy_brokers_.find(user_id); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry == policy_brokers_.end()) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return entry->second; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool DeviceLocalAccountPolicyService::IsPolicyAvailableForUser( 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& user_id) { 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DeviceLocalAccountPolicyBroker* broker = GetBrokerForUser(user_id); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return broker && broker->core()->store()->is_managed(); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyService::AddObserver(Observer* observer) { 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.AddObserver(observer); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyService::RemoveObserver(Observer* observer) { 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.RemoveObserver(observer); 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool DeviceLocalAccountPolicyService::IsExtensionCacheDirectoryBusy( 3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string& account_id) { 3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return busy_extension_cache_directories_.find(account_id) != 3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) busy_extension_cache_directories_.end(); 3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DeviceLocalAccountPolicyService::StartExtensionCachesIfPossible() { 3328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (PolicyBrokerMap::iterator it = policy_brokers_.begin(); 3338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) it != policy_brokers_.end(); ++it) { 3348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!it->second->extension_loader()->IsCacheRunning() && 3358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) !IsExtensionCacheDirectoryBusy(it->second->account_id())) { 3368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) it->second->extension_loader()->StartCache(extension_cache_task_runner_); 3378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool DeviceLocalAccountPolicyService::StartExtensionCacheForAccountIfPresent( 3428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string& account_id) { 3438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (PolicyBrokerMap::iterator it = policy_brokers_.begin(); 3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) it != policy_brokers_.end(); ++it) { 3458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (it->second->account_id() == account_id) { 3468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!it->second->extension_loader()->IsCacheRunning()); 3478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) it->second->extension_loader()->StartCache(extension_cache_task_runner_); 3488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return true; 3498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DeviceLocalAccountPolicyService::OnOrphanedExtensionCachesDeleted() { 3556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK_EQ(IN_PROGRESS, orphan_extension_cache_deletion_state_); 3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) orphan_extension_cache_deletion_state_ = DONE; 3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartExtensionCachesIfPossible(); 3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DeviceLocalAccountPolicyService::OnObsoleteExtensionCacheShutdown( 3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string& account_id) { 3636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK_NE(NOT_STARTED, orphan_extension_cache_deletion_state_); 3648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(IsExtensionCacheDirectoryBusy(account_id)); 3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The account with |account_id| was deleted and the broker for it has shut 3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // down completely. 3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (StartExtensionCacheForAccountIfPresent(account_id)) { 3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If another account with the same ID was created in the meantime, its 3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // extension cache is started, reusing the cache directory. The directory no 3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // longer needs to be marked as busy in this case. 3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) busy_extension_cache_directories_.erase(account_id); 3748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If no account with |account_id| exists anymore, the cache directory should 3788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // be removed. The directory must stay marked as busy while the removal is in 3798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // progress. 3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_cache_task_runner_->PostTaskAndReply( 3818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FROM_HERE, 3828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&DeleteObsoleteExtensionCache, account_id), 3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&DeviceLocalAccountPolicyService:: 3848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnObsoleteExtensionCacheDeleted, 3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) weak_factory_.GetWeakPtr(), 3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) account_id)); 3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DeviceLocalAccountPolicyService::OnObsoleteExtensionCacheDeleted( 3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string& account_id) { 3916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK_EQ(DONE, orphan_extension_cache_deletion_state_); 3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(IsExtensionCacheDirectoryBusy(account_id)); 3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The cache directory for |account_id| has been deleted. The directory no 3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // longer needs to be marked as busy. 3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) busy_extension_cache_directories_.erase(account_id); 3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If another account with the same ID was created in the meantime, start its 3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // extension cache, creating a new cache directory. 4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartExtensionCacheForAccountIfPresent(account_id); 4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 40368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DeviceLocalAccountPolicyService::UpdateAccountListIfNonePending() { 40468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Avoid unnecessary calls to UpdateAccountList(): If an earlier call is still 40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // pending (because the |cros_settings_| are not trusted yet), the updated 40668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // account list will be processed by that call when it eventually runs. 4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!waiting_for_cros_settings_) 40868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateAccountList(); 40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 41068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DeviceLocalAccountPolicyService::UpdateAccountList() { 4128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) chromeos::CrosSettingsProvider::TrustedStatus status = 4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cros_settings_->PrepareTrustedValues( 4148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&DeviceLocalAccountPolicyService::UpdateAccountList, 4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) weak_factory_.GetWeakPtr())); 4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) switch (status) { 4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case chromeos::CrosSettingsProvider::TRUSTED: 4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) waiting_for_cros_settings_ = false; 4198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED: 4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) waiting_for_cros_settings_ = true; 4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 4238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED: 4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) waiting_for_cros_settings_ = false; 4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update |policy_brokers_|, keeping existing entries. 42968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PolicyBrokerMap old_policy_brokers; 43068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) policy_brokers_.swap(old_policy_brokers); 4318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::set<std::string> subdirectories_to_keep; 43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<DeviceLocalAccount> device_local_accounts = 43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetDeviceLocalAccounts(cros_settings_); 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::vector<DeviceLocalAccount>::const_iterator it = 43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) device_local_accounts.begin(); 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != device_local_accounts.end(); ++it) { 4378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PolicyBrokerMap::iterator broker_it = old_policy_brokers.find(it->user_id); 4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<DeviceLocalAccountPolicyBroker> broker; 4408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool broker_initialized = false; 4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (broker_it != old_policy_brokers.end()) { 4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Reuse the existing broker if present. 4438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) broker.reset(broker_it->second); 4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) old_policy_brokers.erase(broker_it); 4458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) broker_initialized = true; 4468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 4478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<DeviceLocalAccountPolicyStore> store( 4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new DeviceLocalAccountPolicyStore(it->account_id, 4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) session_manager_client_, 4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) device_settings_service_, 4518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) store_background_task_runner_)); 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<DeviceLocalAccountExternalDataManager> 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_manager = 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_service_->GetExternalDataManager(it->account_id, 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) store.get()); 4568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) broker.reset(new DeviceLocalAccountPolicyBroker( 4578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) *it, 4586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) component_policy_cache_root_.Append( 4596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GetCacheSubdirectoryForAccountID(it->account_id)), 4608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) store.Pass(), 461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) external_data_manager, 4626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Bind(&DeviceLocalAccountPolicyService::NotifyPolicyUpdated, 4636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Unretained(this), 4646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) it->user_id), 4658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::MessageLoopProxy::current())); 4668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Fire up the cloud connection for fetching policy for the account from 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the cloud if this is an enterprise-managed device. 4708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) broker->ConnectIfPossible(device_settings_service_, 471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_management_service_, 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_context_); 4738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) policy_brokers_[it->user_id] = broker.release(); 4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!broker_initialized) { 4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The broker must be initialized after it has been added to 4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // |policy_brokers_|. 4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) policy_brokers_[it->user_id]->Initialize(); 4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) subdirectories_to_keep.insert( 4826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GetCacheSubdirectoryForAccountID(it->account_id)); 4838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (orphan_extension_cache_deletion_state_ == NOT_STARTED) { 4868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(old_policy_brokers.empty()); 4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(busy_extension_cache_directories_.empty()); 4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If this method is running for the first time, no extension caches have 4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // been started yet. Take this opportunity to do a clean-up by removing 4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // orphaned cache directories not found in |subdirectories_to_keep| from the 4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // cache directory. 4936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) orphan_extension_cache_deletion_state_ = IN_PROGRESS; 4946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 4956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::FilePath cache_root_dir; 4966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS, 4976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) &cache_root_dir)); 4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_cache_task_runner_->PostTaskAndReply( 4998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FROM_HERE, 5006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Bind( 5016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) &DeleteOrphanedCaches, cache_root_dir, subdirectories_to_keep), 5026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Bind( 5036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) &DeviceLocalAccountPolicyService::OnOrphanedExtensionCachesDeleted, 5046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) weak_factory_.GetWeakPtr())); 5058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Start the extension caches for all brokers. These belong to accounts in 5078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // |account_ids| and are not affected by the clean-up. 5088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartExtensionCachesIfPossible(); 5098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 5108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If this method has run before, obsolete brokers may exist. Shut down 5118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // their extension caches and delete the brokers. 5128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DeleteBrokers(&old_policy_brokers); 5138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (orphan_extension_cache_deletion_state_ == DONE) { 5158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If the initial clean-up of orphaned cache directories has been 5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // complete, start any extension caches that are not running yet but can 5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // be started now because their cache directories are not busy. 5188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartExtensionCachesIfPossible(); 5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Purge the component policy caches of any accounts that have been removed. 5236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Do this only after any obsolete brokers have been destroyed. 5246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // TODO(joaodasilva): for now this must be posted to the FILE thread, 5256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // to avoid racing with the ComponentCloudPolicyStore. Use a task runner 5266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // once that class supports another background thread too. 5276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 5286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Bind(&DeleteOrphanedCaches, 5296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) component_policy_cache_root_, 5306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) subdirectories_to_keep)); 5316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, OnDeviceLocalAccountsChanged()); 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) { 5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (PolicyBrokerMap::iterator it = map->begin(); it != map->end(); ++it) { 5378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_refptr<chromeos::DeviceLocalAccountExternalPolicyLoader> 5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_loader = it->second->extension_loader(); 5398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (extension_loader->IsCacheRunning()) { 5408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!IsExtensionCacheDirectoryBusy(it->second->account_id())); 5418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) busy_extension_cache_directories_.insert(it->second->account_id()); 5428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_loader->StopCache(base::Bind( 5438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &DeviceLocalAccountPolicyService::OnObsoleteExtensionCacheShutdown, 5448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) weak_factory_.GetWeakPtr(), 5458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) it->second->account_id())); 5468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delete it->second; 5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) map->clear(); 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyBroker* 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceLocalAccountPolicyService::GetBrokerForStore( 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloudPolicyStore* store) { 55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (PolicyBrokerMap::iterator it(policy_brokers_.begin()); 55790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != policy_brokers_.end(); ++it) { 5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (it->second->core()->store() == store) 5598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return it->second; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void DeviceLocalAccountPolicyService::NotifyPolicyUpdated( 5656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const std::string& user_id) { 5666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, OnPolicyUpdated(user_id)); 5676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 5686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace policy 570