summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_process_impl.cc3
-rw-r--r--chrome/browser/chromeos/login/login_utils.cc25
-rw-r--r--chrome/browser/chromeos/login/login_utils_browsertest.cc1
-rw-r--r--chrome/browser/chromeos/login/policy_oauth_fetcher.cc14
-rw-r--r--chrome/browser/policy/auto_enrollment_client.cc5
-rw-r--r--chrome/browser/policy/browser_policy_connector.cc209
-rw-r--r--chrome/browser/policy/browser_policy_connector.h16
-rw-r--r--chrome/browser/policy/cloud_policy_client.cc9
-rw-r--r--chrome/browser/policy/cloud_policy_provider.cc10
-rw-r--r--chrome/browser/policy/cloud_policy_store.h8
-rw-r--r--chrome/browser/policy/cloud_policy_subsystem.cc9
-rw-r--r--chrome/browser/policy/cloud_policy_subsystem.h3
-rw-r--r--chrome/browser/policy/config_dir_policy_loader.cc9
-rw-r--r--chrome/browser/policy/user_cloud_policy_manager.cc33
-rw-r--r--chrome/browser/policy/user_cloud_policy_manager.h30
-rw-r--r--chrome/browser/policy/user_cloud_policy_store.cc79
-rw-r--r--chrome/browser/policy/user_cloud_policy_store.h52
-rw-r--r--chrome/browser/policy/user_cloud_policy_store_base.cc44
-rw-r--r--chrome/browser/policy/user_cloud_policy_store_base.h42
-rw-r--r--chrome/browser/policy/user_cloud_policy_store_chromeos.cc65
-rw-r--r--chrome/browser/policy/user_cloud_policy_store_chromeos.h9
-rw-r--r--chrome/browser/policy/user_cloud_policy_store_unittest.cc133
-rw-r--r--chrome/browser/policy/user_policy_signin_service.cc177
-rw-r--r--chrome/browser/policy/user_policy_signin_service.h73
-rw-r--r--chrome/browser/policy/user_policy_signin_service_factory.cc56
-rw-r--r--chrome/browser/policy/user_policy_signin_service_factory.h48
-rw-r--r--chrome/browser/policy/user_policy_signin_service_unittest.cc161
-rw-r--r--chrome/browser/prefs/command_line_pref_store.cc2
-rw-r--r--chrome/browser/prefs/pref_member.cc5
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.cc5
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.h1
-rw-r--r--chrome/browser/profiles/profile.h7
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.cc5
-rw-r--r--chrome/browser/profiles/profile_impl.cc18
-rw-r--r--chrome/browser/profiles/profile_impl.h10
-rw-r--r--chrome/browser/profiles/profile_io_data.cc1
-rw-r--r--chrome/browser/signin/signin_manager.h7
-rw-r--r--chrome/browser/signin/signin_manager_fake.cc13
-rw-r--r--chrome/browser/signin/signin_manager_fake.h2
-rw-r--r--chrome/browser/sync/profile_sync_service_mock.cc11
-rw-r--r--chrome/browser/sync/sync_ui_util_unittest.cc6
-rw-r--r--chrome/browser/ui/sync/one_click_signin_helper_unittest.cc5
-rw-r--r--chrome/browser/ui/webui/sync_setup_handler_unittest.cc5
-rw-r--r--chrome/chrome_browser.gypi14
-rw-r--r--chrome/chrome_tests.gypi5
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/pref_names.cc3
-rw-r--r--chrome/common/pref_names.h1
-rw-r--r--chrome/test/base/testing_browser_process.cc24
-rw-r--r--chrome/test/base/testing_profile.cc136
-rw-r--r--chrome/test/base/testing_profile.h64
52 files changed, 1444 insertions, 234 deletions
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index f09c755..769f07b 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -441,8 +441,7 @@ policy::BrowserPolicyConnector* BrowserProcessImpl::browser_policy_connector() {
policy::PolicyService* BrowserProcessImpl::policy_service() {
if (!policy_service_.get()) {
#if defined(ENABLE_CONFIGURATION_POLICY)
- policy_service_.reset(
- browser_policy_connector()->CreatePolicyService(NULL));
+ policy_service_ = browser_policy_connector()->CreatePolicyService(NULL);
#else
policy_service_.reset(new policy::PolicyServiceStub());
#endif
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
index abd594d..67a4242 100644
--- a/chrome/browser/chromeos/login/login_utils.cc
+++ b/chrome/browser/chromeos/login/login_utils.cc
@@ -49,6 +49,9 @@
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/net/preconnect.h"
#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/cloud_policy_client.h"
+#include "chrome/browser/policy/cloud_policy_service.h"
+#include "chrome/browser/policy/user_cloud_policy_manager.h"
#include "chrome/browser/prefs/pref_member.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
@@ -487,6 +490,23 @@ void LoginUtilsImpl::PrepareProfile(
// initialization code sees the cached policy settings.
connector->InitializeUserPolicy(username, wait_for_policy_fetch);
+ // The default profile will have been changed because the ProfileManager
+ // will process the notification that the UserManager sends out.
+ ProfileManager::CreateDefaultProfileAsync(
+ base::Bind(&LoginUtilsImpl::OnProfileCreated, AsWeakPtr()));
+
+ // The default profile is only partially initialized at this point.
+ // Setup the UserCloudPolicyManager so profile initialization can complete.
+ Profile* user_profile = ProfileManager::GetDefaultProfile();
+
+ // Initialize the new cloud policy framework, if enabled.
+ if (user_profile->GetUserCloudPolicyManager()) {
+ user_profile->GetUserCloudPolicyManager()->Initialize(
+ g_browser_process->local_state(),
+ connector->device_management_service(),
+ connector->GetUserAffiliation(username));
+ }
+
if (wait_for_policy_fetch) {
// Profile creation will block until user policy is fetched, which
// requires the DeviceManagement token. Try to fetch it now.
@@ -495,11 +515,6 @@ void LoginUtilsImpl::PrepareProfile(
new PolicyOAuthFetcher(authenticator_->authentication_profile()));
policy_oauth_fetcher_->Start();
}
-
- // The default profile will have been changed because the ProfileManager
- // will process the notification that the UserManager sends out.
- ProfileManager::CreateDefaultProfileAsync(
- base::Bind(&LoginUtilsImpl::OnProfileCreated, AsWeakPtr()));
}
void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) {
diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc
index 4546141..89eda71 100644
--- a/chrome/browser/chromeos/login/login_utils_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc
@@ -203,7 +203,6 @@ class LoginUtilsTest : public testing::Test,
browser_process_->SetProfileManager(
new ProfileManagerWithoutInit(scoped_temp_dir_.path()));
connector_ = browser_process_->browser_policy_connector();
- connector_->Init();
RunAllPending();
}
diff --git a/chrome/browser/chromeos/login/policy_oauth_fetcher.cc b/chrome/browser/chromeos/login/policy_oauth_fetcher.cc
index deb93db..add6120b 100644
--- a/chrome/browser/chromeos/login/policy_oauth_fetcher.cc
+++ b/chrome/browser/chromeos/login/policy_oauth_fetcher.cc
@@ -7,7 +7,9 @@
#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/user_cloud_policy_manager.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/net/gaia/gaia_constants.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
@@ -94,6 +96,18 @@ void PolicyOAuthFetcher::OnOAuthWrapBridgeFailure(
void PolicyOAuthFetcher::SetPolicyToken(const std::string& token) {
policy_token_ = token;
g_browser_process->browser_policy_connector()->RegisterForUserPolicy(token);
+
+ // The Profile object passed in to the constructor is destroyed after the
+ // login process is complete. Get the UserCloudPolicyManager from the user's
+ // default profile instead.
+ policy::UserCloudPolicyManager* cloud_policy_manager =
+ ProfileManager::GetDefaultProfile()->GetUserCloudPolicyManager();
+ if (cloud_policy_manager) {
+ if (token.empty())
+ cloud_policy_manager->CancelWaitForPolicyFetch();
+ else
+ cloud_policy_manager->RegisterClient(token);
+ }
}
} // namespace chromeos
diff --git a/chrome/browser/policy/auto_enrollment_client.cc b/chrome/browser/policy/auto_enrollment_client.cc
index eabe10e..c6ca989 100644
--- a/chrome/browser/policy/auto_enrollment_client.cc
+++ b/chrome/browser/policy/auto_enrollment_client.cc
@@ -111,15 +111,12 @@ bool AutoEnrollmentClient::IsDisabled() {
// static
AutoEnrollmentClient* AutoEnrollmentClient::Create(
const base::Closure& completion_callback) {
- CommandLine* command_line = CommandLine::ForCurrentProcess();
-
// The client won't do anything if |service| is NULL.
DeviceManagementService* service = NULL;
if (IsDisabled()) {
VLOG(1) << "Auto-enrollment is disabled";
} else {
- std::string url =
- command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl);
+ std::string url = BrowserPolicyConnector::GetDeviceManagementUrl();
if (!url.empty()) {
service = new DeviceManagementService(url);
service->ScheduleInitialization(0);
diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc
index 2874a91..552de44 100644
--- a/chrome/browser/policy/browser_policy_connector.cc
+++ b/chrome/browser/policy/browser_policy_connector.cc
@@ -23,10 +23,12 @@
#include "chrome/browser/policy/user_cloud_policy_manager.h"
#include "chrome/browser/policy/user_policy_cache.h"
#include "chrome/browser/policy/user_policy_token_cache.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/token_service.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/net/gaia/gaia_auth_util.h"
#include "chrome/common/net/gaia/gaia_constants.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/notification_details.h"
@@ -45,6 +47,8 @@
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/login/authenticator.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/system/statistics_provider.h"
#include "chrome/browser/policy/app_pack_updater.h"
#include "chrome/browser/policy/cros_user_policy_cache.h"
@@ -70,6 +74,10 @@ const FilePath::CharType kPolicyCacheFile[] = FILE_PATH_LITERAL("Policy");
// Delay in milliseconds from startup.
const int64 kServiceInitializationStartupDelay = 5000;
+// The URL for the device management server.
+const char kDefaultDeviceManagementServerUrl[] =
+ "https://m.google.com/devicemanagement/data/api";
+
#if defined(OS_CHROMEOS)
// MachineInfo key names.
const char kMachineInfoSystemHwqual[] = "hardware_class";
@@ -114,40 +122,37 @@ BrowserPolicyConnector::~BrowserPolicyConnector() {
user_policy_token_cache_.reset();
user_data_store_.reset();
- if (user_cloud_policy_manager_.get())
- user_cloud_policy_manager_->Shutdown();
- user_cloud_policy_manager_.reset();
-
device_management_service_.reset();
}
void BrowserPolicyConnector::Init() {
- platform_provider_.reset(CreatePlatformProvider());
+ DCHECK(!device_management_service_.get()) <<
+ "BrowserPolicyConnector::Init() called twice.";
+ // Don't create platform providers if running in a unit test, since
+ // AsyncPlatformLoader requires deletion on the FILE thread.
+ if (MessageLoop::current())
+ platform_provider_.reset(CreatePlatformProvider());
+
+ device_management_service_.reset(
+ new DeviceManagementService(GetDeviceManagementUrl()));
#if defined(OS_CHROMEOS)
- // The CloudPolicyProvider blocks asynchronous Profile creation until a login
- // is performed. This is used to ensure that the Profile's PrefService sees
- // managed preferences on managed Chrome OS devices. However, this also
- // prevents creation of new Profiles in Desktop Chrome. The implementation of
- // cloud policy on the Desktop requires a refactoring of the cloud provider,
- // but for now it just isn't created.
CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDeviceManagementUrl)) {
- device_management_service_.reset(
- new DeviceManagementService(
- command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl)));
- if (!command_line->HasSwitch(switches::kEnableCloudPolicyService)) {
- managed_cloud_provider_.reset(new CloudPolicyProvider(
- this,
- POLICY_LEVEL_MANDATORY));
- recommended_cloud_provider_.reset(new CloudPolicyProvider(
- this,
- POLICY_LEVEL_RECOMMENDED));
- }
+ if (!command_line->HasSwitch(switches::kEnableCloudPolicyService)) {
+ managed_cloud_provider_.reset(new CloudPolicyProvider(
+ this,
+ POLICY_LEVEL_MANDATORY));
+ recommended_cloud_provider_.reset(new CloudPolicyProvider(
+ this,
+ POLICY_LEVEL_RECOMMENDED));
}
InitializeDevicePolicy();
+ // Don't bother updating the cache if this is a unit test.
+ if (!MessageLoop::current())
+ return;
+
// Create the AppPackUpdater to start updating the cache. It requires the
// system request context, which isn't available yet; therefore it is
// created only once the loops are running.
@@ -158,7 +163,36 @@ void BrowserPolicyConnector::Init() {
#endif
}
-PolicyService* BrowserPolicyConnector::CreatePolicyService(
+scoped_ptr<UserCloudPolicyManager>
+ BrowserPolicyConnector::CreateCloudPolicyManager(Profile* profile) {
+ scoped_ptr<UserCloudPolicyManager> manager;
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableCloudPolicyService)) {
+ bool wait_for_policy_fetch = false;
+#if defined(OS_CHROMEOS)
+ // TODO(mnissler): Revisit once Chrome OS gains multi-profiles support.
+ // Don't wait for a policy fetch if there's no logged in user.
+ if (chromeos::UserManager::Get()->IsUserLoggedIn()) {
+ wait_for_policy_fetch =
+ g_browser_process->browser_policy_connector()->GetUserAffiliation(
+ chromeos::UserManager::Get()->GetLoggedInUser().email()) ==
+ policy::USER_AFFILIATION_MANAGED;
+ }
+#else
+ // On desktop, there's no way to figure out if a user is logged in yet
+ // because prefs are not yet initialized. So we do not block waiting for
+ // the policy fetch to happen (because that would inhibit startup for
+ // non-signed-in users) and instead rely on the fact that a signed-in
+ // profile will already have policy downloaded. If no policy is available
+ // (due to a previous fetch failing), the normal policy refresh mechanism
+ // will cause it to get downloaded eventually.
+#endif
+ manager = UserCloudPolicyManager::Create(profile, wait_for_policy_fetch);
+ }
+ return manager.Pass();
+}
+
+scoped_ptr<PolicyService> BrowserPolicyConnector::CreatePolicyService(
Profile* profile) {
// |providers| in decreasing order of priority.
PolicyServiceImpl::Providers providers;
@@ -176,8 +210,9 @@ PolicyService* BrowserPolicyConnector::CreatePolicyService(
// directly as their provider, which may also block initialization on a policy
// fetch at login time.
if (profile) {
- if (user_cloud_policy_manager_.get())
- providers.push_back(user_cloud_policy_manager_.get());
+ UserCloudPolicyManager* manager = profile->GetUserCloudPolicyManager();
+ if (manager)
+ providers.push_back(manager);
providers.push_back(
ManagedModePolicyProviderFactory::GetForProfile(profile));
@@ -185,7 +220,7 @@ PolicyService* BrowserPolicyConnector::CreatePolicyService(
providers.push_back(&user_cloud_policy_provider_);
}
- return new PolicyServiceImpl(providers);
+ return scoped_ptr<PolicyService>(new PolicyServiceImpl(providers)).Pass();
}
void BrowserPolicyConnector::RegisterForDevicePolicy(
@@ -302,12 +337,11 @@ void BrowserPolicyConnector::ScheduleServiceInitialization(
}
#endif
}
+
void BrowserPolicyConnector::InitializeUserPolicy(
const std::string& user_name,
bool wait_for_policy_fetch) {
// Throw away the old backend.
- user_cloud_policy_manager_.reset();
-
user_cloud_policy_subsystem_.reset();
user_policy_token_cache_.reset();
user_data_store_.reset();
@@ -316,66 +350,54 @@ void BrowserPolicyConnector::InitializeUserPolicy(
CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDeviceManagementUrl)) {
- int64 startup_delay =
- wait_for_policy_fetch ? 0 : kServiceInitializationStartupDelay;
+ int64 startup_delay =
+ wait_for_policy_fetch ? 0 : kServiceInitializationStartupDelay;
- if (command_line->HasSwitch(switches::kEnableCloudPolicyService)) {
-#if defined(OS_CHROMEOS)
- user_cloud_policy_manager_ =
- UserCloudPolicyManager::Create(wait_for_policy_fetch);
- user_cloud_policy_manager_->Initialize(g_browser_process->local_state(),
- device_management_service_.get(),
- GetUserAffiliation(user_name));
- user_cloud_policy_provider_.SetDelegate(user_cloud_policy_manager_.get());
-
- device_management_service_->ScheduleInitialization(startup_delay);
-#endif
- } else {
- FilePath profile_dir;
- PathService::Get(chrome::DIR_USER_DATA, &profile_dir);
+ if (!command_line->HasSwitch(switches::kEnableCloudPolicyService)) {
+ FilePath profile_dir;
+ PathService::Get(chrome::DIR_USER_DATA, &profile_dir);
#if defined(OS_CHROMEOS)
- profile_dir = profile_dir.Append(
- command_line->GetSwitchValuePath(switches::kLoginProfile));
+ profile_dir = profile_dir.Append(
+ command_line->GetSwitchValuePath(switches::kLoginProfile));
#endif
- const FilePath policy_dir = profile_dir.Append(kPolicyDir);
- const FilePath policy_cache_file = policy_dir.Append(kPolicyCacheFile);
- const FilePath token_cache_file = policy_dir.Append(kTokenCacheFile);
- CloudPolicyCacheBase* user_policy_cache = NULL;
+ const FilePath policy_dir = profile_dir.Append(kPolicyDir);
+ const FilePath policy_cache_file = policy_dir.Append(kPolicyCacheFile);
+ const FilePath token_cache_file = policy_dir.Append(kTokenCacheFile);
+ CloudPolicyCacheBase* user_policy_cache = NULL;
- user_data_store_.reset(CloudPolicyDataStore::CreateForUserPolicies());
+ user_data_store_.reset(CloudPolicyDataStore::CreateForUserPolicies());
#if defined(OS_CHROMEOS)
- user_policy_cache =
- new CrosUserPolicyCache(
- chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
- user_data_store_.get(),
- wait_for_policy_fetch,
- token_cache_file,
- policy_cache_file);
+ user_policy_cache =
+ new CrosUserPolicyCache(
+ chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
+ user_data_store_.get(),
+ wait_for_policy_fetch,
+ token_cache_file,
+ policy_cache_file);
#else
- user_policy_cache = new UserPolicyCache(policy_cache_file,
- wait_for_policy_fetch);
- user_policy_token_cache_.reset(
- new UserPolicyTokenCache(user_data_store_.get(), token_cache_file));
+ user_policy_cache = new UserPolicyCache(policy_cache_file,
+ wait_for_policy_fetch);
+ user_policy_token_cache_.reset(
+ new UserPolicyTokenCache(user_data_store_.get(), token_cache_file));
- // Initiate the DM-Token load.
- user_policy_token_cache_->Load();
+ // Initiate the DM-Token load.
+ user_policy_token_cache_->Load();
#endif
- user_cloud_policy_subsystem_.reset(new CloudPolicySubsystem(
- user_data_store_.get(),
- user_policy_cache));
+ user_cloud_policy_subsystem_.reset(new CloudPolicySubsystem(
+ user_data_store_.get(),
+ user_policy_cache,
+ GetDeviceManagementUrl()));
- user_data_store_->set_user_name(user_name);
- user_data_store_->set_user_affiliation(GetUserAffiliation(user_name));
+ user_data_store_->set_user_name(user_name);
+ user_data_store_->set_user_affiliation(GetUserAffiliation(user_name));
- user_cloud_policy_subsystem_->CompleteInitialization(
- prefs::kUserPolicyRefreshRate,
- startup_delay);
+ user_cloud_policy_subsystem_->CompleteInitialization(
+ prefs::kUserPolicyRefreshRate,
+ startup_delay);
- managed_cloud_provider_->SetUserPolicyCache(user_policy_cache);
- recommended_cloud_provider_->SetUserPolicyCache(user_policy_cache);
- }
+ managed_cloud_provider_->SetUserPolicyCache(user_policy_cache);
+ recommended_cloud_provider_->SetUserPolicyCache(user_policy_cache);
}
}
@@ -407,17 +429,6 @@ void BrowserPolicyConnector::RegisterForUserPolicy(
if (user_data_store_.get())
user_data_store_->SetOAuthToken(oauth_token);
}
- if (user_cloud_policy_manager_.get()) {
- CloudPolicyService* service =
- user_cloud_policy_manager_->cloud_policy_service();
- if (service->client() &&
- !service->client()->is_registered() &&
- !oauth_token.empty()) {
- service->client()->Register(oauth_token);
- } else {
- user_cloud_policy_manager_->CancelWaitForPolicyFetch();
- }
- }
}
CloudPolicyDataStore* BrowserPolicyConnector::GetDeviceCloudPolicyDataStore() {
@@ -441,9 +452,11 @@ UserAffiliation BrowserPolicyConnector::GetUserAffiliation(
const std::string& user_name) {
#if defined(OS_CHROMEOS)
if (install_attributes_.get()) {
- size_t pos = user_name.find('@');
+ std::string canonicalized_user_name(gaia::CanonicalizeEmail(user_name));
+ size_t pos = canonicalized_user_name.find('@');
if (pos != std::string::npos &&
- user_name.substr(pos + 1) == install_attributes_->GetDomain()) {
+ canonicalized_user_name.substr(pos + 1) ==
+ install_attributes_->GetDomain()) {
return USER_AFFILIATION_MANAGED;
}
}
@@ -474,6 +487,15 @@ void BrowserPolicyConnector::SetPolicyProviderForTesting(
g_testing_provider = provider;
}
+// static
+std::string BrowserPolicyConnector::GetDeviceManagementUrl() {
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kDeviceManagementUrl))
+ return command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl);
+ else
+ return kDefaultDeviceManagementServerUrl;
+}
+
void BrowserPolicyConnector::Observe(
int type,
const content::NotificationSource& source,
@@ -521,7 +543,12 @@ void BrowserPolicyConnector::InitializeDevicePolicy() {
device_cloud_policy_subsystem_.reset(new CloudPolicySubsystem(
device_data_store_.get(),
- device_policy_cache));
+ device_policy_cache,
+ GetDeviceManagementUrl()));
+
+ // Skip the final initialization if this is a unit test.
+ if (!MessageLoop::current())
+ return;
// Initialize the subsystem once the message loops are spinning.
MessageLoop::current()->PostTask(
diff --git a/chrome/browser/policy/browser_policy_connector.h b/chrome/browser/policy/browser_policy_connector.h
index 818c2bf..8218f36 100644
--- a/chrome/browser/policy/browser_policy_connector.h
+++ b/chrome/browser/policy/browser_policy_connector.h
@@ -48,9 +48,14 @@ class BrowserPolicyConnector : public content::NotificationObserver {
// policy system running.
void Init();
+ // Creates a UserCloudPolicyManager for the given profile, or returns NULL if
+ // it is not supported on this platform. Ownership is transferred to the
+ // caller.
+ scoped_ptr<UserCloudPolicyManager> CreateCloudPolicyManager(Profile* profile);
+
// Creates a new policy service for the given profile, or a global one if
// it is NULL. Ownership is transferred to the caller.
- PolicyService* CreatePolicyService(Profile* profile);
+ scoped_ptr<PolicyService> CreatePolicyService(Profile* profile);
// Returns a weak pointer to the CloudPolicySubsystem corresponding to the
// device policy managed by this policy connector, or NULL if no such
@@ -140,6 +145,10 @@ class BrowserPolicyConnector : public content::NotificationObserver {
AppPackUpdater* GetAppPackUpdater();
+ DeviceManagementService* device_management_service() {
+ return device_management_service_.get();
+ }
+
// Sets a |provider| that will be included in PolicyServices returned by
// CreatePolicyService. This is a static method because local state is
// created immediately after the connector, and tests don't have a chance to
@@ -148,6 +157,10 @@ class BrowserPolicyConnector : public content::NotificationObserver {
static void SetPolicyProviderForTesting(
ConfigurationPolicyProvider* provider);
+ // Gets the URL of the DM server (either the default or a URL provided via the
+ // command line).
+ static std::string GetDeviceManagementUrl();
+
private:
// content::NotificationObserver method overrides:
virtual void Observe(int type,
@@ -190,7 +203,6 @@ class BrowserPolicyConnector : public content::NotificationObserver {
scoped_ptr<DeviceManagementService> device_management_service_;
ProxyPolicyProvider user_cloud_policy_provider_;
- scoped_ptr<UserCloudPolicyManager> user_cloud_policy_manager_;
// Used to initialize the device policy subsystem once the message loops
// are spinning.
diff --git a/chrome/browser/policy/cloud_policy_client.cc b/chrome/browser/policy/cloud_policy_client.cc
index c34adac..6a27d06 100644
--- a/chrome/browser/policy/cloud_policy_client.cc
+++ b/chrome/browser/policy/cloud_policy_client.cc
@@ -31,9 +31,10 @@ CloudPolicyClient::CloudPolicyClient(const std::string& machine_id,
submit_machine_id_(false),
public_key_version_(-1),
public_key_version_valid_(false),
- service_(service),
- status_provider_(status_provider),
- status_(DM_STATUS_SUCCESS) {}
+ service_(service), // Can be NULL for unit tests.
+ status_provider_(status_provider), // Can be NULL for unit tests.
+ status_(DM_STATUS_SUCCESS) {
+}
CloudPolicyClient::~CloudPolicyClient() {}
@@ -52,6 +53,7 @@ void CloudPolicyClient::SetupRegistration(const std::string& dm_token,
}
void CloudPolicyClient::Register(const std::string& auth_token) {
+ DCHECK(service_);
DCHECK(!auth_token.empty());
DCHECK(!is_registered());
@@ -120,6 +122,7 @@ void CloudPolicyClient::FetchPolicy() {
}
void CloudPolicyClient::Unregister() {
+ DCHECK(service_);
request_job_.reset(
service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION));
request_job_->SetDMToken(dm_token_);
diff --git a/chrome/browser/policy/cloud_policy_provider.cc b/chrome/browser/policy/cloud_policy_provider.cc
index f921b8a..e4af5ce 100644
--- a/chrome/browser/policy/cloud_policy_provider.cc
+++ b/chrome/browser/policy/cloud_policy_provider.cc
@@ -4,10 +4,12 @@
#include "chrome/browser/policy/cloud_policy_provider.h"
+#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/policy_bundle.h"
#include "chrome/browser/policy/policy_map.h"
+#include "chrome/common/chrome_switches.h"
namespace policy {
@@ -83,6 +85,14 @@ void CloudPolicyProvider::Merge() {
if (!initialization_complete_) {
initialization_complete_ = true;
for (size_t i = 0; i < CACHE_SIZE; ++i) {
+#if defined(OS_CHROMEOS)
+ // Ignore the device policy cache if device policy is not enabled.
+ if (i == CACHE_DEVICE &&
+ !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableDevicePolicy)) {
+ continue;
+ }
+#endif
if (caches_[i] == NULL || !caches_[i]->IsReady()) {
initialization_complete_ = false;
break;
diff --git a/chrome/browser/policy/cloud_policy_store.h b/chrome/browser/policy/cloud_policy_store.h
index 224fcea..080e50e 100644
--- a/chrome/browser/policy/cloud_policy_store.h
+++ b/chrome/browser/policy/cloud_policy_store.h
@@ -12,6 +12,8 @@
#include "chrome/browser/policy/policy_map.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
+class Profile;
+
namespace policy {
// Defines the low-level interface used by the cloud policy code to:
@@ -91,6 +93,12 @@ class CloudPolicyStore {
// Removes the specified observer.
void RemoveObserver(Observer* observer);
+ // Factory method to create a CloudPolicyStore appropriate for the current
+ // platform, for storing user policy for the user associated with the passed
+ // |profile|. Implementation is defined in the individual platform store
+ // files.
+ static scoped_ptr<CloudPolicyStore> CreateUserPolicyStore(Profile* profile);
+
protected:
// Invokes the corresponding callback on all registered observers.
void NotifyStoreLoaded();
diff --git a/chrome/browser/policy/cloud_policy_subsystem.cc b/chrome/browser/policy/cloud_policy_subsystem.cc
index c48f61e..bc51d67 100644
--- a/chrome/browser/policy/cloud_policy_subsystem.cc
+++ b/chrome/browser/policy/cloud_policy_subsystem.cc
@@ -50,13 +50,8 @@ CloudPolicySubsystem::ObserverRegistrar::~ObserverRegistrar() {
CloudPolicySubsystem::CloudPolicySubsystem(
CloudPolicyDataStore* data_store,
- CloudPolicyCacheBase* policy_cache) {
- std::string device_management_url;
- CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDeviceManagementUrl)) {
- device_management_url =
- command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl);
- }
+ CloudPolicyCacheBase* policy_cache,
+ const std::string& device_management_url) {
Initialize(data_store, policy_cache, device_management_url);
}
diff --git a/chrome/browser/policy/cloud_policy_subsystem.h b/chrome/browser/policy/cloud_policy_subsystem.h
index bb95c15..12effca 100644
--- a/chrome/browser/policy/cloud_policy_subsystem.h
+++ b/chrome/browser/policy/cloud_policy_subsystem.h
@@ -71,7 +71,8 @@ class CloudPolicySubsystem
};
CloudPolicySubsystem(CloudPolicyDataStore* data_store,
- CloudPolicyCacheBase* policy_cache);
+ CloudPolicyCacheBase* policy_cache,
+ const std::string& device_management_url);
virtual ~CloudPolicySubsystem();
// Initializes the subsystem. The first network request will only be made
diff --git a/chrome/browser/policy/config_dir_policy_loader.cc b/chrome/browser/policy/config_dir_policy_loader.cc
index 4e83229..82495a4b 100644
--- a/chrome/browser/policy/config_dir_policy_loader.cc
+++ b/chrome/browser/policy/config_dir_policy_loader.cc
@@ -13,9 +13,11 @@
#include "base/file_util.h"
#include "base/json/json_file_value_serializer.h"
#include "base/logging.h"
+#include "base/message_loop.h"
#include "base/platform_file.h"
#include "base/stl_util.h"
#include "chrome/browser/policy/policy_bundle.h"
+#include "content/public/browser/browser_thread.h"
namespace policy {
@@ -36,6 +38,13 @@ ConfigDirPolicyLoader::ConfigDirPolicyLoader(const FilePath& config_dir,
ConfigDirPolicyLoader::~ConfigDirPolicyLoader() {}
void ConfigDirPolicyLoader::InitOnFile() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+ // Some unit tests create a File thread that shares a MessageLoop with the
+ // UI thread, and this causes DCHECKs because IO operations aren't allowed on
+ // that thread. So if this is running in the context of one of those tests,
+ // just exit.
+ if (!MessageLoop::current()->IsType(MessageLoop::TYPE_IO))
+ return;
base::files::FilePathWatcher::Callback callback =
base::Bind(&ConfigDirPolicyLoader::OnFileUpdated, base::Unretained(this));
mandatory_watcher_.Watch(config_dir_.Append(kMandatoryConfigDir), callback);
diff --git a/chrome/browser/policy/user_cloud_policy_manager.cc b/chrome/browser/policy/user_cloud_policy_manager.cc
index ccbc55d..84f4c67 100644
--- a/chrome/browser/policy/user_cloud_policy_manager.cc
+++ b/chrome/browser/policy/user_cloud_policy_manager.cc
@@ -56,32 +56,21 @@ UserCloudPolicyManager::~UserCloudPolicyManager() {
store_->RemoveObserver(this);
}
-#if defined(OS_CHROMEOS)
// static
scoped_ptr<UserCloudPolicyManager> UserCloudPolicyManager::Create(
+ Profile* profile,
bool wait_for_policy_fetch) {
- FilePath profile_dir;
- CHECK(PathService::Get(chrome::DIR_USER_DATA, &profile_dir));
- CommandLine* command_line = CommandLine::ForCurrentProcess();
- const FilePath policy_dir =
- profile_dir
- .Append(command_line->GetSwitchValuePath(switches::kLoginProfile))
- .Append(kPolicyDir);
- const FilePath policy_cache_file = policy_dir.Append(kPolicyCacheFile);
- const FilePath token_cache_file = policy_dir.Append(kTokenCacheFile);
-
- scoped_ptr<CloudPolicyStore> store(
- new UserCloudPolicyStoreChromeOS(
- chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
- token_cache_file, policy_cache_file));
+ scoped_ptr<CloudPolicyStore> store =
+ CloudPolicyStore::CreateUserPolicyStore(profile);
return scoped_ptr<UserCloudPolicyManager>(
new UserCloudPolicyManager(store.Pass(), wait_for_policy_fetch));
}
-#endif
void UserCloudPolicyManager::Initialize(PrefService* prefs,
DeviceManagementService* service,
UserAffiliation user_affiliation) {
+ DCHECK(service);
+ DCHECK(prefs);
DCHECK(!service_.get());
prefs_ = prefs;
scoped_ptr<CloudPolicyClient> client(
@@ -129,6 +118,18 @@ void UserCloudPolicyManager::CancelWaitForPolicyFetch() {
}
}
+bool UserCloudPolicyManager::IsClientRegistered() const {
+ if (!service_.get())
+ return false;
+ return service_->client()->is_registered();
+}
+
+void UserCloudPolicyManager::RegisterClient(const std::string& access_token) {
+ DCHECK(cloud_policy_service()) << "Callers must invoke Initialize() first";
+ if (!cloud_policy_service()->client()->is_registered())
+ cloud_policy_service()->client()->Register(access_token);
+}
+
bool UserCloudPolicyManager::IsInitializationComplete() const {
return store_->is_initialized() && !wait_for_policy_fetch_;
}
diff --git a/chrome/browser/policy/user_cloud_policy_manager.h b/chrome/browser/policy/user_cloud_policy_manager.h
index 8db19d0..98c59e2 100644
--- a/chrome/browser/policy/user_cloud_policy_manager.h
+++ b/chrome/browser/policy/user_cloud_policy_manager.h
@@ -13,6 +13,7 @@
#include "chrome/browser/policy/configuration_policy_provider.h"
class PrefService;
+class Profile;
namespace policy {
@@ -33,23 +34,32 @@ class UserCloudPolicyManager : public ConfigurationPolicyProvider,
bool wait_for_policy_fetch);
virtual ~UserCloudPolicyManager();
-#if defined(OS_CHROMEOS)
- // Creates a UserCloudPolicyService instance for the Chrome OS platform.
- static scoped_ptr<UserCloudPolicyManager> Create(bool wait_for_policy_fetch);
-#endif
+ // Creates a UserCloudPolicyService instance associated with the passed
+ // |profile|.
+ static scoped_ptr<UserCloudPolicyManager> Create(Profile* profile,
+ bool wait_for_policy_fetch);
- // Initializes the cloud connection. |prefs| and |service| must stay valid
- // until Shutdown() gets called.
- void Initialize(PrefService* prefs,
- DeviceManagementService* service,
- UserAffiliation user_affiliation);
- void Shutdown();
+ // Initializes the cloud connection. |local_prefs| and |service| must stay
+ // valid until Shutdown() gets called. Virtual for mocking.
+ virtual void Initialize(PrefService* local_prefs,
+ DeviceManagementService* service,
+ UserAffiliation user_affiliation);
+
+ // Virtual for mocks.
+ virtual void Shutdown();
// Cancels waiting for the policy fetch and flags the
// ConfigurationPolicyProvider ready (assuming all other initialization tasks
// have completed).
void CancelWaitForPolicyFetch();
+ // Returns true if the underlying CloudPolicyClient is already registered.
+ // Virtual for mocking.
+ virtual bool IsClientRegistered() const;
+
+ // Register the CloudPolicyClient using the passed OAuth token.
+ void RegisterClient(const std::string& access_token);
+
CloudPolicyService* cloud_policy_service() { return service_.get(); }
// ConfigurationPolicyProvider:
diff --git a/chrome/browser/policy/user_cloud_policy_store.cc b/chrome/browser/policy/user_cloud_policy_store.cc
new file mode 100644
index 0000000..9817828
--- /dev/null
+++ b/chrome/browser/policy/user_cloud_policy_store.cc
@@ -0,0 +1,79 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/user_cloud_policy_store.h"
+
+#include "base/bind.h"
+#include "chrome/browser/policy/proto/cloud_policy.pb.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+
+using enterprise_management::PolicyData;
+
+namespace policy {
+
+UserCloudPolicyStore::UserCloudPolicyStore(Profile* profile)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ profile_(profile) {
+}
+
+UserCloudPolicyStore::~UserCloudPolicyStore() {
+}
+
+void UserCloudPolicyStore::Load() {
+ // TODO(atwilson): Read policy from file.
+ policy_.reset();
+ policy_map_.Clear();
+ NotifyStoreLoaded();
+}
+
+void UserCloudPolicyStore::Store(
+ const enterprise_management::PolicyFetchResponse& policy) {
+ // Stop any pending requests to store policy, then validate the new policy
+ // before storing it.
+ weak_factory_.InvalidateWeakPtrs();
+ scoped_ptr<enterprise_management::PolicyFetchResponse> policy_copy(
+ new enterprise_management::PolicyFetchResponse(policy));
+ Validate(policy_copy.Pass(),
+ base::Bind(&UserCloudPolicyStore::StorePolicyAfterValidation,
+ weak_factory_.GetWeakPtr()));
+}
+
+void UserCloudPolicyStore::Validate(
+ scoped_ptr<enterprise_management::PolicyFetchResponse> policy,
+ const UserCloudPolicyValidator::CompletionCallback& callback) {
+ // Configure the validator.
+ scoped_ptr<UserCloudPolicyValidator> validator =
+ CreateValidator(policy.Pass(), callback);
+ SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
+ std::string username = signin->GetAuthenticatedUsername();
+ DCHECK(!username.empty());
+ validator->ValidateUsername(username);
+
+ // Start validation. The Validator will free itself once validation is
+ // complete.
+ validator.release()->StartValidation();
+}
+
+void UserCloudPolicyStore::StorePolicyAfterValidation(
+ UserCloudPolicyValidator* validator) {
+ validation_status_ = validator->status();
+ if (!validator->success()) {
+ status_ = STATUS_VALIDATION_ERROR;
+ NotifyStoreError();
+ return;
+ }
+ // TODO(atwilson): Write policy to file.
+ InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass());
+ status_ = STATUS_OK;
+ NotifyStoreLoaded();
+}
+
+// static
+scoped_ptr<CloudPolicyStore> CloudPolicyStore::CreateUserPolicyStore(
+ Profile* profile) {
+ return scoped_ptr<CloudPolicyStore>(new UserCloudPolicyStore(profile));
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/user_cloud_policy_store.h b/chrome/browser/policy/user_cloud_policy_store.h
new file mode 100644
index 0000000..85141dd
--- /dev/null
+++ b/chrome/browser/policy/user_cloud_policy_store.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_USER_CLOUD_POLICY_STORE_H_
+#define CHROME_BROWSER_POLICY_USER_CLOUD_POLICY_STORE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/policy/user_cloud_policy_store_base.h"
+
+namespace policy {
+
+// Implements a cloud policy store that is stored in a simple file in the user's
+// profile directory. This is used on (non-chromeos) platforms that do not have
+// a secure storage implementation.
+class UserCloudPolicyStore : public UserCloudPolicyStoreBase {
+ public:
+ // Creates a policy store associated with the user signed in to this
+ // |profile|.
+ explicit UserCloudPolicyStore(Profile* profile);
+ virtual ~UserCloudPolicyStore();
+
+ // CloudPolicyStore implementation.
+ virtual void Load() OVERRIDE;
+ virtual void Store(
+ const enterprise_management::PolicyFetchResponse& policy) OVERRIDE;
+
+ private:
+ // Starts policy blob validation. |callback| is invoked once validation is
+ // complete.
+ void Validate(
+ scoped_ptr<enterprise_management::PolicyFetchResponse> policy,
+ const UserCloudPolicyValidator::CompletionCallback& callback);
+
+ // Callback invoked to store the policy after validation has finished.
+ void StorePolicyAfterValidation(UserCloudPolicyValidator* validator);
+
+ base::WeakPtrFactory<UserCloudPolicyStore> weak_factory_;
+
+ // Weak pointer to the profile associated with this store.
+ Profile* profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStore);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_USER_CLOUD_POLICY_STORE_H_
diff --git a/chrome/browser/policy/user_cloud_policy_store_base.cc b/chrome/browser/policy/user_cloud_policy_store_base.cc
new file mode 100644
index 0000000..4658ab9
--- /dev/null
+++ b/chrome/browser/policy/user_cloud_policy_store_base.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/user_cloud_policy_store_base.h"
+
+#include "chrome/browser/policy/cloud_policy_constants.h"
+#include "chrome/browser/policy/proto/cloud_policy.pb.h"
+
+namespace policy {
+
+// Decodes a CloudPolicySettings object into a policy map. The implementation is
+// generated code in policy/cloud_policy_generated.cc.
+void DecodePolicy(const enterprise_management::CloudPolicySettings& policy,
+ PolicyMap* policies);
+
+UserCloudPolicyStoreBase::UserCloudPolicyStoreBase() {
+}
+
+UserCloudPolicyStoreBase::~UserCloudPolicyStoreBase() {
+}
+
+scoped_ptr<UserCloudPolicyValidator> UserCloudPolicyStoreBase::CreateValidator(
+ scoped_ptr<enterprise_management::PolicyFetchResponse> policy,
+ const UserCloudPolicyValidator::CompletionCallback& callback) {
+ // Configure the validator.
+ UserCloudPolicyValidator* validator =
+ UserCloudPolicyValidator::Create(policy.Pass(), callback);
+ validator->ValidatePolicyType(dm_protocol::kChromeUserPolicyType);
+ validator->ValidateAgainstCurrentPolicy(policy_.get());
+ validator->ValidatePayload();
+ return scoped_ptr<UserCloudPolicyValidator>(validator);
+}
+
+void UserCloudPolicyStoreBase::InstallPolicy(
+ scoped_ptr<enterprise_management::PolicyData> policy_data,
+ scoped_ptr<enterprise_management::CloudPolicySettings> payload) {
+ // Decode the payload.
+ policy_map_.Clear();
+ DecodePolicy(*payload, &policy_map_);
+ policy_ = policy_data.Pass();
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/user_cloud_policy_store_base.h b/chrome/browser/policy/user_cloud_policy_store_base.h
new file mode 100644
index 0000000..5fda2f8
--- /dev/null
+++ b/chrome/browser/policy/user_cloud_policy_store_base.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_USER_CLOUD_POLICY_STORE_BASE_H_
+#define CHROME_BROWSER_POLICY_USER_CLOUD_POLICY_STORE_BASE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/policy/cloud_policy_store.h"
+
+namespace policy {
+
+// Base class that implements common cross-platform UserCloudPolicyStore
+// functionality.
+class UserCloudPolicyStoreBase : public CloudPolicyStore {
+ public:
+ UserCloudPolicyStoreBase();
+ virtual ~UserCloudPolicyStoreBase();
+
+ protected:
+ // Creates a validator configured to validate a user policy. The caller owns
+ // the resulting object until StartValidation() is invoked.
+ scoped_ptr<UserCloudPolicyValidator> CreateValidator(
+ scoped_ptr<enterprise_management::PolicyFetchResponse> policy,
+ const UserCloudPolicyValidator::CompletionCallback& callback);
+
+ // Sets |policy_data| and |payload| as the active policy.
+ void InstallPolicy(
+ scoped_ptr<enterprise_management::PolicyData> policy_data,
+ scoped_ptr<enterprise_management::CloudPolicySettings> payload);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreBase);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_USER_CLOUD_POLICY_STORE_BASE_H_
diff --git a/chrome/browser/policy/user_cloud_policy_store_chromeos.cc b/chrome/browser/policy/user_cloud_policy_store_chromeos.cc
index 4a0a38f..f44b10c 100644
--- a/chrome/browser/policy/user_cloud_policy_store_chromeos.cc
+++ b/chrome/browser/policy/user_cloud_policy_store_chromeos.cc
@@ -9,14 +9,19 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
+#include "base/path_service.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/policy/proto/cloud_policy.pb.h"
#include "chrome/browser/policy/proto/device_management_local.pb.h"
#include "chrome/browser/policy/user_policy_disk_cache.h"
#include "chrome/browser/policy/user_policy_token_cache.h"
#include "chrome/common/net/gaia/gaia_auth_util.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
#include "content/public/browser/browser_thread.h"
@@ -24,10 +29,15 @@ namespace em = enterprise_management;
namespace policy {
-// Decodes a CloudPolicySettings object into a policy map. The implementation is
-// generated code in policy/cloud_policy_generated.cc.
-void DecodePolicy(const em::CloudPolicySettings& policy,
- PolicyMap* policies);
+namespace {
+// Subdirectory in the user's profile for storing user policies.
+const FilePath::CharType kPolicyDir[] = FILE_PATH_LITERAL("Device Management");
+// File in the above directory for stroing user policy dmtokens.
+const FilePath::CharType kTokenCacheFile[] = FILE_PATH_LITERAL("Token");
+// File in the above directory for storing user policy data.
+const FilePath::CharType kPolicyCacheFile[] = FILE_PATH_LITERAL("Policy");
+} // namespace
+
// Helper class for loading legacy policy caches.
class LegacyPolicyCacheLoader : public UserPolicyTokenCache::Delegate,
@@ -158,10 +168,10 @@ void UserCloudPolicyStoreChromeOS::Store(
const em::PolicyFetchResponse& policy) {
// Cancel all pending requests.
weak_factory_.InvalidateWeakPtrs();
- Validate(scoped_ptr<em::PolicyFetchResponse>(
- new em::PolicyFetchResponse(policy)),
- base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
- weak_factory_.GetWeakPtr()));
+ Validate(
+ scoped_ptr<em::PolicyFetchResponse>(new em::PolicyFetchResponse(policy)),
+ base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated,
+ weak_factory_.GetWeakPtr()));
}
void UserCloudPolicyStoreChromeOS::Load() {
@@ -262,33 +272,22 @@ void UserCloudPolicyStoreChromeOS::OnPolicyStored(bool success) {
}
}
-void UserCloudPolicyStoreChromeOS::InstallPolicy(
- scoped_ptr<em::PolicyData> policy_data,
- scoped_ptr<em::CloudPolicySettings> payload) {
- // Decode the payload.
- policy_map_.Clear();
- DecodePolicy(*payload, &policy_map_);
- policy_ = policy_data.Pass();
-}
-
void UserCloudPolicyStoreChromeOS::Validate(
scoped_ptr<em::PolicyFetchResponse> policy,
const UserCloudPolicyValidator::CompletionCallback& callback) {
// Configure the validator.
- UserCloudPolicyValidator* validator =
- UserCloudPolicyValidator::Create(policy.Pass(), callback);
+ scoped_ptr<UserCloudPolicyValidator> validator =
+ CreateValidator(policy.Pass(), callback);
validator->ValidateUsername(
chromeos::UserManager::Get()->GetLoggedInUser().email());
- validator->ValidatePolicyType(dm_protocol::kChromeUserPolicyType);
- validator->ValidateAgainstCurrentPolicy(policy_.get());
- validator->ValidatePayload();
// TODO(mnissler): Do a signature check here as well. The key is stored by
// session_manager in the root-owned cryptohome area, which is currently
// inaccessible to Chrome though.
- // Start validation.
- validator->StartValidation();
+ // Start validation. The Validator will free itself once validation is
+ // complete.
+ validator.release()->StartValidation();
}
void UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished(
@@ -352,4 +351,22 @@ void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir(const FilePath& dir) {
LOG(ERROR) << "Failed to remove cache dir " << dir.value();
}
+// static
+scoped_ptr<CloudPolicyStore> CloudPolicyStore::CreateUserPolicyStore(
+ Profile* profile) {
+ FilePath profile_dir;
+ CHECK(PathService::Get(chrome::DIR_USER_DATA, &profile_dir));
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ const FilePath policy_dir =
+ profile_dir
+ .Append(command_line->GetSwitchValuePath(switches::kLoginProfile))
+ .Append(kPolicyDir);
+ const FilePath policy_cache_file = policy_dir.Append(kPolicyCacheFile);
+ const FilePath token_cache_file = policy_dir.Append(kTokenCacheFile);
+
+ return scoped_ptr<CloudPolicyStore>(new UserCloudPolicyStoreChromeOS(
+ chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
+ token_cache_file, policy_cache_file));
+}
+
} // namespace policy
diff --git a/chrome/browser/policy/user_cloud_policy_store_chromeos.h b/chrome/browser/policy/user_cloud_policy_store_chromeos.h
index 41ea0d1..3fba4b0 100644
--- a/chrome/browser/policy/user_cloud_policy_store_chromeos.h
+++ b/chrome/browser/policy/user_cloud_policy_store_chromeos.h
@@ -12,8 +12,8 @@
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "chrome/browser/policy/cloud_policy_store.h"
#include "chrome/browser/policy/cloud_policy_validator.h"
+#include "chrome/browser/policy/user_cloud_policy_store_base.h"
namespace chromeos {
class SessionManagerClient;
@@ -34,7 +34,7 @@ class LegacyPolicyCacheLoader;
// Additionally, this class drives legacy UserPolicyTokenCache and
// UserPolicyDiskCache instances, migrating policy from these to session_manager
// storage on the fly.
-class UserCloudPolicyStoreChromeOS : public CloudPolicyStore {
+class UserCloudPolicyStoreChromeOS : public UserCloudPolicyStoreBase {
public:
UserCloudPolicyStoreChromeOS(
chromeos::SessionManagerClient* session_manager_client,
@@ -62,11 +62,6 @@ class UserCloudPolicyStoreChromeOS : public CloudPolicyStore {
// Called back from SessionManagerClient for policy store operations.
void OnPolicyStored(bool);
- // Installs |policy_data| and |payload|.
- void InstallPolicy(
- scoped_ptr<enterprise_management::PolicyData> policy_data,
- scoped_ptr<enterprise_management::CloudPolicySettings> payload);
-
// Starts policy blob validation.
void Validate(
scoped_ptr<enterprise_management::PolicyFetchResponse> policy,
diff --git a/chrome/browser/policy/user_cloud_policy_store_unittest.cc b/chrome/browser/policy/user_cloud_policy_store_unittest.cc
new file mode 100644
index 0000000..5f0ff80
--- /dev/null
+++ b/chrome/browser/policy/user_cloud_policy_store_unittest.cc
@@ -0,0 +1,133 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/user_cloud_policy_store.h"
+
+#include "base/message_loop.h"
+#include "base/run_loop.h"
+#include "chrome/browser/policy/policy_builder.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/signin_manager_fake.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread.h"
+#include "policy/policy_constants.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::AllOf;
+using testing::Eq;
+using testing::Property;
+
+namespace policy {
+
+namespace {
+
+class MockCloudPolicyStoreObserver : public CloudPolicyStore::Observer {
+ public:
+ MockCloudPolicyStoreObserver() {}
+ virtual ~MockCloudPolicyStoreObserver() {}
+
+ MOCK_METHOD1(OnStoreLoaded, void(CloudPolicyStore* store));
+ MOCK_METHOD1(OnStoreError, void(CloudPolicyStore* store));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyStoreObserver);
+};
+
+class UserCloudPolicyStoreTest : public testing::Test {
+ public:
+ UserCloudPolicyStoreTest()
+ : loop_(MessageLoop::TYPE_UI),
+ ui_thread_(content::BrowserThread::UI, &loop_),
+ file_thread_(content::BrowserThread::FILE, &loop_),
+ profile_(new TestingProfile()) {}
+
+ virtual void SetUp() OVERRIDE {
+ SigninManager* signin = static_cast<SigninManager*>(
+ SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
+ profile_.get(), FakeSigninManager::Build));
+ signin->SetAuthenticatedUsername(PolicyBuilder::kFakeUsername);
+ store_.reset(new UserCloudPolicyStore(profile_.get()));
+ store_->AddObserver(&observer_);
+
+ policy_.payload().mutable_showhomebutton()->set_showhomebutton(true);
+ policy_.Build();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ store_->RemoveObserver(&observer_);
+ store_.reset();
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ }
+
+ // Verifies that store_->policy_map() has the ShowHomeButton entry.
+ void VerifyPolicyMap() {
+ EXPECT_EQ(1U, store_->policy_map().size());
+ const PolicyMap::Entry* entry =
+ store_->policy_map().Get(key::kShowHomeButton);
+ ASSERT_TRUE(entry);
+ EXPECT_TRUE(base::FundamentalValue(true).Equals(entry->value));
+ }
+
+ // Install an expectation on |observer_| for an error code.
+ void ExpectError(CloudPolicyStore::Status error) {
+ EXPECT_CALL(observer_,
+ OnStoreError(AllOf(Eq(store_.get()),
+ Property(&CloudPolicyStore::status,
+ Eq(error)))));
+ }
+
+ UserPolicyBuilder policy_;
+ MockCloudPolicyStoreObserver observer_;
+ scoped_ptr<UserCloudPolicyStore> store_;
+
+ // CloudPolicyValidator() requires a FILE thread so declare one here. Both
+ // |ui_thread_| and |file_thread_| share the same MessageLoop |loop_| so
+ // callers can use RunLoop to manage both virtual threads.
+ MessageLoop loop_;
+ content::TestBrowserThread ui_thread_;
+ content::TestBrowserThread file_thread_;
+
+ scoped_ptr<TestingProfile> profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreTest);
+};
+
+TEST_F(UserCloudPolicyStoreTest, Store) {
+ EXPECT_FALSE(store_->policy());
+ EXPECT_TRUE(store_->policy_map().empty());
+
+ // Store a simple policy and make sure it ends up as the currently active
+ // policy.
+ store_->Store(policy_.policy());
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ // Policy should be decoded and stored.
+ ASSERT_TRUE(store_->policy());
+ EXPECT_EQ(policy_.policy_data().SerializeAsString(),
+ store_->policy()->SerializeAsString());
+ VerifyPolicyMap();
+ EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
+}
+
+TEST_F(UserCloudPolicyStoreTest, StoreValidationError) {
+ // Create an invalid policy (no policy type).
+ policy_.policy_data().clear_policy_type();
+ policy_.Build();
+
+ // Store policy.
+ ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
+ store_->Store(policy_.policy());
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ ASSERT_FALSE(store_->policy());
+}
+
+} // namespace
+
+} // namespace policy
+
diff --git a/chrome/browser/policy/user_policy_signin_service.cc b/chrome/browser/policy/user_policy_signin_service.cc
new file mode 100644
index 0000000..32137be
--- /dev/null
+++ b/chrome/browser/policy/user_policy_signin_service.cc
@@ -0,0 +1,177 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/user_policy_signin_service.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/policy/cloud_policy_service.h"
+#include "chrome/browser/policy/user_cloud_policy_manager.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/token_service.h"
+#include "chrome/browser/signin/token_service_factory.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/net/gaia/gaia_constants.h"
+#include "chrome/common/net/gaia/gaia_urls.h"
+#include "chrome/common/net/gaia/oauth2_access_token_fetcher.h"
+#include "chrome/common/pref_names.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
+
+namespace {
+// TODO(atwilson): Move this once we add OAuth token support to TokenService.
+const char kServiceScopeChromeOSDeviceManagement[] =
+ "https://www.googleapis.com/auth/chromeosdevicemanagement";
+
+// How long to delay before starting device policy network requests. Set to a
+// few seconds to alleviate contention during initial startup.
+const int64 kPolicyServiceInitializationDelayMilliseconds = 2000;
+} // namespace
+
+namespace policy {
+
+UserPolicySigninService::UserPolicySigninService(
+ Profile* profile,
+ UserCloudPolicyManager* manager)
+ : profile_(profile),
+ manager_(manager) {
+
+ // Initialize/shutdown the UserCloudPolicyManager when the user signs in or
+ // out.
+ registrar_.Add(this,
+ chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
+ content::Source<Profile>(profile));
+ registrar_.Add(this,
+ chrome::NOTIFICATION_TOKEN_AVAILABLE,
+ content::Source<TokenService>(
+ TokenServiceFactory::GetForProfile(profile)));
+
+ // The Profile is not yet fully initialized when this object is created,
+ // so wait until the initialization has finished to initialize the
+ // UserCloudPolicyManager as otherwise various crashes ensue from services
+ // trying to access the partially-initialized Profile.
+ // TODO(atwilson): Remove this once ProfileImpl::DoFinalInit() goes away and
+ // the profile is fully initialized before ProfileKeyedServices are created.
+ registrar_.Add(this,
+ chrome::NOTIFICATION_PROFILE_ADDED,
+ content::Source<Profile>(profile));
+}
+
+UserPolicySigninService::~UserPolicySigninService() {
+}
+
+void UserPolicySigninService::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ case chrome::NOTIFICATION_PROFILE_ADDED:
+ // Profile is initialized so it's safe to initialize the
+ // UserCloudPolicyManager now.
+ ConfigureUserCloudPolicyManager();
+ break;
+ case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
+ ConfigureUserCloudPolicyManager();
+ break;
+ case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
+ const TokenService::TokenAvailableDetails& token_details =
+ *(content::Details<const TokenService::TokenAvailableDetails>(
+ details).ptr());
+ if (token_details.service() ==
+ GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
+ // TokenService now has a refresh token, so reconfigure the
+ // UserCloudPolicyManager to initiate a DMToken fetch if needed.
+ ConfigureUserCloudPolicyManager();
+ }
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+}
+
+
+void UserPolicySigninService::ConfigureUserCloudPolicyManager() {
+ // Don't do anything unless cloud policy is enabled.
+ if (!profile_->GetPrefs()->GetBoolean(prefs::kLoadCloudPolicyOnSignin))
+ return;
+
+ // Either startup or shutdown the UserCloudPolicyManager depending on whether
+ // the user is signed in or not.
+ if (!manager_)
+ return; // Can be null in unit tests.
+
+ SigninManager* signin_manager = SigninManagerFactory::GetForProfile(profile_);
+ if (signin_manager->GetAuthenticatedUsername().empty()) {
+ manager_->Shutdown();
+ } else {
+ if (!manager_->cloud_policy_service()) {
+ // Make sure we've initialized the DeviceManagementService. It's OK to
+ // call this multiple times so we do it every time we initialize the
+ // UserCloudPolicyManager.
+ g_browser_process->browser_policy_connector()->
+ ScheduleServiceInitialization(
+ kPolicyServiceInitializationDelayMilliseconds);
+ // Initialize the UserCloudPolicyManager if it isn't already initialized.
+ policy::DeviceManagementService* service = g_browser_process->
+ browser_policy_connector()->device_management_service();
+ manager_->Initialize(g_browser_process->local_state(),
+ service,
+ policy::USER_AFFILIATION_NONE);
+ DCHECK(manager_->cloud_policy_service());
+ }
+
+ // Register the CloudPolicyService if needed.
+ if (!manager_->IsClientRegistered())
+ RegisterCloudPolicyService();
+ }
+}
+
+void UserPolicySigninService::RegisterCloudPolicyService() {
+ // TODO(atwilson): Move the code to mint the devicemanagement token into
+ // TokenService.
+ std::string token = TokenServiceFactory::GetForProfile(profile_)->
+ GetOAuth2LoginRefreshToken();
+ if (token.empty()) {
+ DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download";
+ return;
+ }
+
+ // Do nothing if already fetching an access token.
+ if (oauth2_access_token_fetcher_.get())
+ return;
+
+ // Start fetching an OAuth2 access token for the device management service and
+ // hand it off to the CloudPolicyClient when done.
+ oauth2_access_token_fetcher_.reset(
+ new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext()));
+ std::vector<std::string> scopes(1, kServiceScopeChromeOSDeviceManagement);
+ GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
+ oauth2_access_token_fetcher_->Start(
+ gaia_urls->oauth2_chrome_client_id(),
+ gaia_urls->oauth2_chrome_client_secret(),
+ token,
+ scopes);
+}
+
+void UserPolicySigninService::OnGetTokenFailure(
+ const GoogleServiceAuthError& error) {
+ DLOG(WARNING) << "Could not fetch access token for "
+ << kServiceScopeChromeOSDeviceManagement;
+ oauth2_access_token_fetcher_.reset();
+ manager_->CancelWaitForPolicyFetch();
+}
+
+void UserPolicySigninService::OnGetTokenSuccess(
+ const std::string& access_token,
+ const base::Time& expiration_time) {
+ // Pass along the new access token to the CloudPolicyClient.
+ manager_->RegisterClient(access_token);
+ oauth2_access_token_fetcher_.reset();
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/user_policy_signin_service.h b/chrome/browser/policy/user_policy_signin_service.h
new file mode 100644
index 0000000..99a6381
--- /dev/null
+++ b/chrome/browser/policy/user_policy_signin_service.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_USER_POLICY_SIGNIN_SERVICE_H_
+#define CHROME_BROWSER_POLICY_USER_POLICY_SIGNIN_SERVICE_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/profiles/profile_keyed_service.h"
+#include "chrome/common/net/gaia/oauth2_access_token_consumer.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+
+class OAuth2AccessTokenFetcher;
+class Profile;
+
+namespace base {
+class Time;
+}
+
+namespace policy {
+
+class UserCloudPolicyManager;
+
+// The UserPolicySigninService tracks when user signin/signout actions occur and
+// initializes/shuts down the UserCloudPolicyManager as required. This class is
+// not used on ChromeOS because UserCloudPolicyManager initialization is handled
+// via LoginUtils, since it must happen before profile creation.
+class UserPolicySigninService
+ : public ProfileKeyedService,
+ public OAuth2AccessTokenConsumer,
+ public content::NotificationObserver {
+ public:
+ // Creates a UserPolicySigninService associated with the passed |profile|.
+ UserPolicySigninService(Profile* profile, UserCloudPolicyManager* manager);
+ virtual ~UserPolicySigninService();
+
+ // content::NotificationObserver implementation.
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
+ // OAuth2AccessTokenConsumer implementation.
+ virtual void OnGetTokenSuccess(const std::string& access_token,
+ const base::Time& expiration_time) OVERRIDE;
+ virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
+
+ private:
+ // Initializes the UserCloudPolicyManager to reflect the currently-signed-in
+ // user.
+ void ConfigureUserCloudPolicyManager();
+
+ // Fetches an OAuth token to allow the cloud policy service to register with
+ // the cloud policy server.
+ void RegisterCloudPolicyService();
+
+ // Weak pointer to the profile this service is associated with.
+ Profile* profile_;
+
+ content::NotificationRegistrar registrar_;
+ scoped_ptr<OAuth2AccessTokenFetcher> oauth2_access_token_fetcher_;
+
+ // Weak pointer to the UserCloudPolicyManager (allows dependency injection
+ // for tests).
+ UserCloudPolicyManager* manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserPolicySigninService);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_USER_POLICY_SIGNIN_SERVICE_H_
diff --git a/chrome/browser/policy/user_policy_signin_service_factory.cc b/chrome/browser/policy/user_policy_signin_service_factory.cc
new file mode 100644
index 0000000..34cb028
--- /dev/null
+++ b/chrome/browser/policy/user_policy_signin_service_factory.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/user_policy_signin_service_factory.h"
+
+#include "chrome/browser/policy/user_policy_signin_service.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_dependency_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/token_service_factory.h"
+#include "chrome/common/pref_names.h"
+
+namespace policy {
+
+UserPolicySigninServiceFactory::UserPolicySigninServiceFactory()
+ : ProfileKeyedServiceFactory("UserPolicySigninService",
+ ProfileDependencyManager::GetInstance()) {
+ DependsOn(TokenServiceFactory::GetInstance());
+ DependsOn(SigninManagerFactory::GetInstance());
+}
+
+UserPolicySigninServiceFactory::~UserPolicySigninServiceFactory() {}
+
+// static
+UserPolicySigninService* UserPolicySigninServiceFactory::GetForProfile(
+ Profile* profile) {
+ return static_cast<UserPolicySigninService*>(
+ GetInstance()->GetServiceForProfile(profile, true));
+}
+
+// static
+UserPolicySigninServiceFactory* UserPolicySigninServiceFactory::GetInstance() {
+ return Singleton<UserPolicySigninServiceFactory>::get();
+}
+
+ProfileKeyedService* UserPolicySigninServiceFactory::BuildServiceInstanceFor(
+ Profile* profile) const {
+ return new UserPolicySigninService(profile,
+ profile->GetUserCloudPolicyManager());
+}
+
+bool UserPolicySigninServiceFactory::ServiceIsCreatedWithProfile() {
+ // Create this object when the profile is created so it can track any
+ // user signin activity.
+ return true;
+}
+
+void UserPolicySigninServiceFactory::RegisterUserPrefs(
+ PrefService* user_prefs) {
+ user_prefs->RegisterBooleanPref(prefs::kLoadCloudPolicyOnSignin,
+ false, PrefService::UNSYNCABLE_PREF);
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/user_policy_signin_service_factory.h b/chrome/browser/policy/user_policy_signin_service_factory.h
new file mode 100644
index 0000000..5b60b32
--- /dev/null
+++ b/chrome/browser/policy/user_policy_signin_service_factory.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_USER_POLICY_SIGNIN_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_POLICY_USER_POLICY_SIGNIN_SERVICE_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "chrome/browser/profiles/profile_keyed_service_factory.h"
+
+namespace policy {
+
+class UserPolicySigninService;
+
+// Singleton that owns all UserPolicySigninServices and creates/deletes them as
+// new Profiles are created/shutdown.
+class UserPolicySigninServiceFactory : public ProfileKeyedServiceFactory {
+ public:
+ // Returns an instance of the UserPolicySigninServiceFactory singleton.
+ static UserPolicySigninServiceFactory* GetInstance();
+
+ // Returns the instance of UserPolicySigninService for the passed |profile|.
+ // Used primarily for testing.
+ static UserPolicySigninService* GetForProfile(Profile* profile);
+
+ protected:
+ // ProfileKeyedServiceFactory implementation.
+ virtual ProfileKeyedService* BuildServiceInstanceFor(
+ Profile* profile) const OVERRIDE;
+
+ // Overridden to cause this object to be created when the profile is created.
+ virtual bool ServiceIsCreatedWithProfile() OVERRIDE;
+
+ // Register the preferences related to cloud-based user policy.
+ virtual void RegisterUserPrefs(PrefService* user_prefs) OVERRIDE;
+
+ private:
+ friend struct DefaultSingletonTraits<UserPolicySigninServiceFactory>;
+
+ UserPolicySigninServiceFactory();
+ virtual ~UserPolicySigninServiceFactory();
+
+ DISALLOW_COPY_AND_ASSIGN(UserPolicySigninServiceFactory);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_USER_POLICY_SIGNIN_SERVICE_FACTORY_H_
diff --git a/chrome/browser/policy/user_policy_signin_service_unittest.cc b/chrome/browser/policy/user_policy_signin_service_unittest.cc
new file mode 100644
index 0000000..fc3d3fa
--- /dev/null
+++ b/chrome/browser/policy/user_policy_signin_service_unittest.cc
@@ -0,0 +1,161 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/message_loop.h"
+#include "chrome/browser/policy/mock_cloud_policy_store.h"
+#include "chrome/browser/policy/user_cloud_policy_manager.h"
+#include "chrome/browser/policy/user_policy_signin_service.h"
+#include "chrome/browser/policy/user_policy_signin_service_factory.h"
+#include "chrome/browser/prefs/browser_prefs.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/signin_manager_fake.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_pref_service.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/test/test_browser_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Return;
+
+namespace policy {
+
+namespace {
+
+class UserPolicySigninServiceTest : public testing::Test {
+ public:
+ UserPolicySigninServiceTest()
+ : loop_(MessageLoop::TYPE_UI),
+ ui_thread_(content::BrowserThread::UI, &loop_) {
+ }
+
+ virtual void SetUp() OVERRIDE {
+ local_state_.reset(new TestingPrefService);
+ chrome::RegisterLocalState(local_state_.get());
+ static_cast<TestingBrowserProcess*>(g_browser_process)->SetLocalState(
+ local_state_.get());
+
+ // Create a UserCloudPolicyManager with a MockCloudPolicyStore, and build a
+ // TestingProfile that uses it.
+ mock_store_ = new MockCloudPolicyStore();
+ mock_store_->NotifyStoreLoaded();
+ EXPECT_CALL(*mock_store_, Load());
+ scoped_ptr<UserCloudPolicyManager> manager(new UserCloudPolicyManager(
+ scoped_ptr<CloudPolicyStore>(mock_store_), false));
+ TestingProfile::Builder builder;
+ builder.SetUserCloudPolicyManager(manager.Pass());
+ profile_ = builder.Build().Pass();
+ profile_->GetPrefs()->SetBoolean(prefs::kLoadCloudPolicyOnSignin, true);
+ SigninManagerFactory::GetInstance()->SetTestingFactory(
+ profile_.get(), FakeSigninManager::Build);
+
+ // Make sure the UserPolicySigninService is created.
+ UserPolicySigninServiceFactory::GetForProfile(profile_.get());
+ }
+
+ virtual void TearDown() OVERRIDE {
+ // Free the profile before we clear out the browser prefs.
+ profile_.reset();
+ static_cast<TestingBrowserProcess*>(g_browser_process)->SetLocalState(NULL);
+ local_state_.reset();
+ }
+
+
+ scoped_ptr<TestingProfile> profile_;
+ // Weak pointer to a MockCloudPolicyStore - lifetime is managed by the
+ // UserCloudPolicyManager.
+ MockCloudPolicyStore* mock_store_;
+
+ // BrowserPolicyConnector wants to initialize various components
+ // asynchronously via tasks, so create a fake thread here.
+ MessageLoop loop_;
+ content::TestBrowserThread ui_thread_;
+
+ scoped_ptr<TestingPrefService> local_state_;
+};
+
+TEST_F(UserPolicySigninServiceTest, InitWhileSignedOut) {
+ // Make sure user is not signed in.
+ ASSERT_TRUE(SigninManagerFactory::GetForProfile(profile_.get())->
+ GetAuthenticatedUsername().empty());
+
+ // Let the SigninService know that the profile has been created.
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_PROFILE_ADDED,
+ content::Source<Profile>(profile_.get()),
+ content::NotificationService::NoDetails());
+
+ // UserCloudPolicyManager should not be initialized.
+ ASSERT_FALSE(profile_->GetUserCloudPolicyManager()->cloud_policy_service());
+}
+
+TEST_F(UserPolicySigninServiceTest, InitWhileSignedIn) {
+ // Set the user as signed in.
+ SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
+ "testuser@test.com");
+
+ // Let the SigninService know that the profile has been created.
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_PROFILE_ADDED,
+ content::Source<Profile>(profile_.get()),
+ content::NotificationService::NoDetails());
+
+ // UserCloudPolicyManager should be initialized.
+ ASSERT_TRUE(profile_->GetUserCloudPolicyManager()->cloud_policy_service());
+}
+
+// TODO(atwilson): Enable test for signing in once it is possible to use a
+// mock TokenService (http://crbug.com/138618).
+TEST_F(UserPolicySigninServiceTest, DISABLED_SignInAfterInit) {
+ // Let the SigninService know that the profile has been created.
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_PROFILE_ADDED,
+ content::Source<Profile>(profile_.get()),
+ content::NotificationService::NoDetails());
+
+ // UserCloudPolicyManager should not be initialized.
+ ASSERT_FALSE(profile_->GetUserCloudPolicyManager()->cloud_policy_service());
+
+ // Now sign in the user.
+ SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
+ "testuser@test.com");
+
+ // Make oauth token available (needs MockTokenService - see TODO above).
+
+ // UserCloudPolicyManager should be initialized.
+ ASSERT_TRUE(profile_->GetUserCloudPolicyManager()->cloud_policy_service());
+}
+
+TEST_F(UserPolicySigninServiceTest, SignOutAfterInit) {
+ // Set the user as signed in.
+ SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
+ "testuser@test.com");
+
+ // Let the SigninService know that the profile has been created.
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_PROFILE_ADDED,
+ content::Source<Profile>(profile_.get()),
+ content::NotificationService::NoDetails());
+
+ // UserCloudPolicyManager should be initialized.
+ ASSERT_TRUE(profile_->GetUserCloudPolicyManager()->cloud_policy_service());
+
+ // Now sign out.
+ SigninManagerFactory::GetForProfile(profile_.get())->SignOut();
+
+ // UserCloudPolicyManager should be shut down.
+ ASSERT_FALSE(profile_->GetUserCloudPolicyManager()->cloud_policy_service());
+}
+
+} // namespace
+
+} // namespace policy
diff --git a/chrome/browser/prefs/command_line_pref_store.cc b/chrome/browser/prefs/command_line_pref_store.cc
index 70d8056..a3ce691 100644
--- a/chrome/browser/prefs/command_line_pref_store.cc
+++ b/chrome/browser/prefs/command_line_pref_store.cc
@@ -64,6 +64,8 @@ const CommandLinePrefStore::BooleanSwitchToPreferenceMapEntry
{ switches::kEnableTouchpadThreeFingerClick,
prefs::kEnableTouchpadThreeFingerClick, true },
#endif
+ { switches::kLoadCloudPolicyOnSignin, prefs::kLoadCloudPolicyOnSignin,
+ true },
};
const CommandLinePrefStore::IntegerSwitchToPreferenceMapEntry
diff --git a/chrome/browser/prefs/pref_member.cc b/chrome/browser/prefs/pref_member.cc
index 025138e..902224e 100644
--- a/chrome/browser/prefs/pref_member.cc
+++ b/chrome/browser/prefs/pref_member.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -35,7 +35,8 @@ void PrefMemberBase::Init(const char* pref_name,
prefs_ = prefs;
pref_name_ = pref_name;
// Check that the preference is registered.
- DCHECK(prefs_->FindPreference(pref_name_.c_str()));
+ DCHECK(prefs_->FindPreference(pref_name_.c_str()))
+ << pref_name << " not registered.";
// Add ourselves as a pref observer so we can keep our local value in sync.
prefs_->AddPrefObserver(pref_name, this);
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 94f3bab..ef78264 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -241,6 +241,11 @@ FaviconService* OffTheRecordProfileImpl::GetFaviconService(
return NULL;
}
+policy::UserCloudPolicyManager*
+ OffTheRecordProfileImpl::GetUserCloudPolicyManager() {
+ return profile_->GetUserCloudPolicyManager();
+}
+
policy::PolicyService* OffTheRecordProfileImpl::GetPolicyService() {
return profile_->GetPolicyService();
}
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h
index 6b09bd4..2ebc061 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.h
+++ b/chrome/browser/profiles/off_the_record_profile_impl.h
@@ -49,6 +49,7 @@ class OffTheRecordProfileImpl : public Profile,
virtual HistoryService* GetHistoryService(ServiceAccessType sat) OVERRIDE;
virtual HistoryService* GetHistoryServiceWithoutCreating() OVERRIDE;
virtual FaviconService* GetFaviconService(ServiceAccessType sat) OVERRIDE;
+ virtual policy::UserCloudPolicyManager* GetUserCloudPolicyManager() OVERRIDE;
virtual policy::PolicyService* GetPolicyService() OVERRIDE;
virtual PrefService* GetPrefs() OVERRIDE;
virtual PrefService* GetOffTheRecordPrefs() OVERRIDE;
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index 37dd180..3912eda 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -65,8 +65,8 @@ class FileSystemContext;
}
namespace history {
-class TopSites;
class ShortcutsBackend;
+class TopSites;
}
namespace net {
@@ -75,6 +75,7 @@ class SSLConfigService;
namespace policy {
class PolicyService;
+class UserCloudPolicyManager;
}
class Profile : public content::BrowserContext {
@@ -249,6 +250,10 @@ class Profile : public content::BrowserContext {
// doesn't already exist.
virtual HistoryService* GetHistoryServiceWithoutCreating() = 0;
+ // Returns the UserCloudPolicyManager (if any) that handles this profile's
+ // connection to the cloud-based management service.
+ virtual policy::UserCloudPolicyManager* GetUserCloudPolicyManager() = 0;
+
// Returns the PolicyService that provides policies for this profile.
virtual policy::PolicyService* GetPolicyService() = 0;
diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc
index c070b97..0a30db0 100644
--- a/chrome/browser/profiles/profile_dependency_manager.cc
+++ b/chrome/browser/profiles/profile_dependency_manager.cc
@@ -60,6 +60,7 @@
#if defined(ENABLE_CONFIGURATION_POLICY)
#include "chrome/browser/policy/managed_mode_policy_provider_factory.h"
+#include "chrome/browser/policy/user_policy_signin_service_factory.h"
#endif
#if defined(USE_AURA)
@@ -233,6 +234,10 @@ void ProfileDependencyManager::AssertFactoriesBuilt() {
PinnedTabServiceFactory::GetInstance();
#endif
PluginPrefsFactory::GetInstance();
+#if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS)
+ // Not used on chromeos because signin happens before the profile is loaded.
+ policy::UserPolicySigninServiceFactory::GetInstance();
+#endif
predictors::AutocompleteActionPredictorFactory::GetInstance();
predictors::PredictorDatabaseFactory::GetInstance();
predictors::ResourcePrefetchPredictorFactory::GetInstance();
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 34b30d9..bb1f44e 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -56,6 +56,7 @@
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/plugin_prefs.h"
#include "chrome/browser/policy/policy_service.h"
+#include "chrome/browser/policy/user_cloud_policy_manager.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
@@ -286,10 +287,17 @@ ProfileImpl::ProfileImpl(const FilePath& path,
session_restore_enabled_ =
!command_line->HasSwitch(switches::kDisableRestoreSessionState);
#if defined(ENABLE_CONFIGURATION_POLICY)
- policy_service_.reset(
- g_browser_process->browser_policy_connector()->CreatePolicyService(this));
+ // TODO(atwilson): Change these to ProfileKeyedServices once PrefService is
+ // a ProfileKeyedService (policy must be initialized before PrefService
+ // because PrefService depends on policy loading to get overridden pref
+ // values).
+ cloud_policy_manager_ =
+ g_browser_process->browser_policy_connector()->CreateCloudPolicyManager(
+ this);
+ policy_service_ =
+ g_browser_process->browser_policy_connector()->CreatePolicyService(this);
#else
- policy_service_.reset(new policy::PolicyServiceStub());
+ policy_service_.reset(new policy::PolicyServiceStub());
#endif
if (create_mode == CREATE_MODE_ASYNCHRONOUS) {
prefs_.reset(PrefService::CreatePrefService(
@@ -649,6 +657,10 @@ bool ProfileImpl::WasCreatedByVersionOrLater(const std::string& version) {
return (profile_version.CompareTo(arg_version) >= 0);
}
+policy::UserCloudPolicyManager* ProfileImpl::GetUserCloudPolicyManager() {
+ return cloud_policy_manager_.get();
+}
+
policy::PolicyService* ProfileImpl::GetPolicyService() {
DCHECK(policy_service_.get()); // Should explicitly be initialized.
return policy_service_.get();
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index be96345..cebc882 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -87,6 +87,7 @@ class ProfileImpl : public Profile,
virtual GAIAInfoUpdateService* GetGAIAInfoUpdateService() OVERRIDE;
virtual HistoryService* GetHistoryService(ServiceAccessType sat) OVERRIDE;
virtual HistoryService* GetHistoryServiceWithoutCreating() OVERRIDE;
+ virtual policy::UserCloudPolicyManager* GetUserCloudPolicyManager() OVERRIDE;
virtual policy::PolicyService* GetPolicyService() OVERRIDE;
virtual PrefService* GetPrefs() OVERRIDE;
virtual PrefService* GetOffTheRecordPrefs() OVERRIDE;
@@ -186,9 +187,12 @@ class ProfileImpl : public Profile,
// that the declaration occurs AFTER things it depends on as destruction
// happens in reverse order of declaration.
- // |prefs_| depends on |policy_service_|.
- // TODO(bauerb): Once |prefs_| is a ProfileKeyedService, |policy_service_|
- // should become one as well.
+ // |prefs_| depends on |policy_service_|, which depends on
+ // |user_cloud_policy_manager_|.
+ // TODO(bauerb, mnissler): Once |prefs_| is a ProfileKeyedService,
+ // |policy_service_| and |user_cloud_policy_manager_| should become
+ // ProfiledKeyedServices as well.
+ scoped_ptr<policy::UserCloudPolicyManager> cloud_policy_manager_;
scoped_ptr<policy::PolicyService> policy_service_;
// Keep |prefs_| on top for destruction order because |extension_prefs_|,
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 2c8c08d..d9904ab 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -360,6 +360,7 @@ ProfileIOData::GetIsolatedAppRequestContext(
}
ExtensionInfoMap* ProfileIOData::GetExtensionInfoMap() const {
+ DCHECK(extension_info_map_) << "ExtensionSystem not initialized";
return extension_info_map_;
}
diff --git a/chrome/browser/signin/signin_manager.h b/chrome/browser/signin/signin_manager.h
index 1baecf7..49879c7 100644
--- a/chrome/browser/signin/signin_manager.h
+++ b/chrome/browser/signin/signin_manager.h
@@ -140,6 +140,11 @@ class SigninManager : public GaiaAuthConsumer,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ protected:
+ // Weak pointer to parent profile (protected so FakeSigninManager can access
+ // it).
+ Profile* profile_;
+
private:
enum SigninType {
SIGNIN_TYPE_NONE,
@@ -173,8 +178,6 @@ class SigninManager : public GaiaAuthConsumer,
void HandleAuthError(const GoogleServiceAuthError& error,
bool clear_transient_data);
- Profile* profile_;
-
// ClientLogin identity.
std::string possibly_invalid_username_;
std::string password_; // This is kept empty whenever possible.
diff --git a/chrome/browser/signin/signin_manager_fake.cc b/chrome/browser/signin/signin_manager_fake.cc
index 4cd8ecc..b3068ea 100644
--- a/chrome/browser/signin/signin_manager_fake.cc
+++ b/chrome/browser/signin/signin_manager_fake.cc
@@ -4,7 +4,12 @@
#include "chrome/browser/signin/signin_manager_fake.h"
-FakeSigninManager::FakeSigninManager() {}
+#include "chrome/common/chrome_notification_types.h"
+#include "content/public/browser/notification_service.h"
+
+FakeSigninManager::FakeSigninManager(Profile* profile) {
+ profile_ = profile;
+}
FakeSigninManager::~FakeSigninManager() {}
@@ -29,9 +34,13 @@ void FakeSigninManager::StartSignInWithOAuth(const std::string& username,
void FakeSigninManager::SignOut() {
authenticated_username_.clear();
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
+ content::Source<Profile>(profile_),
+ content::NotificationService::NoDetails());
}
// static
ProfileKeyedService* FakeSigninManager::Build(Profile* profile) {
- return new FakeSigninManager();
+ return new FakeSigninManager(profile);
}
diff --git a/chrome/browser/signin/signin_manager_fake.h b/chrome/browser/signin/signin_manager_fake.h
index a108b0a..2cd46d7 100644
--- a/chrome/browser/signin/signin_manager_fake.h
+++ b/chrome/browser/signin/signin_manager_fake.h
@@ -17,7 +17,7 @@ class ProfileKeyedService;
// and accepts the credentials provided to StartSignIn.
class FakeSigninManager : public SigninManager {
public:
- FakeSigninManager();
+ explicit FakeSigninManager(Profile* profile);
virtual ~FakeSigninManager();
virtual void StartSignIn(const std::string& username,
diff --git a/chrome/browser/sync/profile_sync_service_mock.cc b/chrome/browser/sync/profile_sync_service_mock.cc
index 694753a..e62e8f1 100644
--- a/chrome/browser/sync/profile_sync_service_mock.cc
+++ b/chrome/browser/sync/profile_sync_service_mock.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/prefs/pref_service_mock_builder.h"
+#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/testing_pref_store.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/profile_sync_service_mock.h"
@@ -31,14 +31,7 @@ ProfileSyncServiceMock::~ProfileSyncServiceMock() {
// static
TestingProfile* ProfileSyncServiceMock::MakeSignedInTestingProfile() {
TestingProfile* profile = new TestingProfile();
- TestingPrefStore* user_prefs = new TestingPrefStore();
- PrefService* prefs = PrefServiceMockBuilder()
- .WithUserPrefs(user_prefs)
- .Create();
- profile->SetPrefService(prefs);
- // We just blew away our prefs, so reregister them.
- SigninManagerFactory::GetInstance()->RegisterUserPrefs(prefs);
- user_prefs->SetString(prefs::kGoogleServicesUsername, "foo");
+ profile->GetPrefs()->SetString(prefs::kGoogleServicesUsername, "foo");
return profile;
}
diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc
index 0448118..d15be1d 100644
--- a/chrome/browser/sync/sync_ui_util_unittest.cc
+++ b/chrome/browser/sync/sync_ui_util_unittest.cc
@@ -78,7 +78,7 @@ TEST(SyncUIUtilTest, PassphraseGlobalError) {
scoped_ptr<Profile> profile(
ProfileSyncServiceMock::MakeSignedInTestingProfile());
NiceMock<ProfileSyncServiceMock> service(profile.get());
- FakeSigninManager signin;
+ FakeSigninManager signin(profile.get());
browser_sync::SyncBackendHost::Status status;
EXPECT_CALL(service, QueryDetailedSyncStatus(_))
.WillRepeatedly(Return(false));
@@ -99,7 +99,7 @@ TEST(SyncUIUtilTest, AuthAndPassphraseGlobalError) {
scoped_ptr<Profile> profile(
ProfileSyncServiceMock::MakeSignedInTestingProfile());
NiceMock<ProfileSyncServiceMock> service(profile.get());
- FakeSigninManager signin;
+ FakeSigninManager signin(profile.get());
browser_sync::SyncBackendHost::Status status;
EXPECT_CALL(service, QueryDetailedSyncStatus(_))
.WillRepeatedly(Return(false));
@@ -153,7 +153,7 @@ TEST(SyncUIUtilTest, AuthStateGlobalError) {
{ GoogleServiceAuthError::HOSTED_NOT_ALLOWED, true },
};
- FakeSigninManager signin;
+ FakeSigninManager signin(profile.get());
for (size_t i = 0; i < sizeof(table)/sizeof(*table); ++i) {
VerifySyncGlobalErrorResult(
&service, signin, table[i].error_state, true, table[i].is_error);
diff --git a/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc b/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
index 826f188..1330c8c 100644
--- a/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
+++ b/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
@@ -35,7 +35,8 @@ namespace {
class SigninManagerMock : public FakeSigninManager {
public:
- SigninManagerMock() {}
+ explicit SigninManagerMock(Profile* profile)
+ : FakeSigninManager(profile) {}
MOCK_CONST_METHOD1(IsAllowedUsername, bool(const std::string& username));
};
@@ -78,7 +79,7 @@ void OneClickSigninHelperTest::SetUp() {
}
static ProfileKeyedService* BuildSigninManagerMock(Profile* profile) {
- return new SigninManagerMock();
+ return new SigninManagerMock(profile);
}
content::WebContents* OneClickSigninHelperTest::CreateMockWebContents(
diff --git a/chrome/browser/ui/webui/sync_setup_handler_unittest.cc b/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
index ae1b4be..662614c 100644
--- a/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
+++ b/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
@@ -341,12 +341,12 @@ class TestingSyncSetupHandler : public SyncSetupHandler {
class SigninManagerMock : public FakeSigninManager {
public:
- SigninManagerMock() {}
+ explicit SigninManagerMock(Profile* profile) : FakeSigninManager(profile) {}
MOCK_CONST_METHOD1(IsAllowedUsername, bool(const std::string& username));
};
static ProfileKeyedService* BuildSigninManagerMock(Profile* profile) {
- return new SigninManagerMock();
+ return new SigninManagerMock(profile);
}
// The boolean parameter indicates whether the test is run with ClientOAuth
@@ -367,7 +367,6 @@ class SyncSetupHandlerTest : public testing::TestWithParam<bool> {
error_ = GoogleServiceAuthError::None();
profile_.reset(ProfileSyncServiceMock::MakeSignedInTestingProfile());
- SyncPromoUI::RegisterUserPrefs(profile_->GetPrefs());
mock_pss_ = static_cast<ProfileSyncServiceMock*>(
ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
profile_.get(),
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index d74c016..12cca45 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1764,12 +1764,20 @@
'browser/policy/url_blacklist_manager.h',
'browser/policy/user_cloud_policy_manager.cc',
'browser/policy/user_cloud_policy_manager.h',
+ 'browser/policy/user_cloud_policy_store.cc',
+ 'browser/policy/user_cloud_policy_store.h',
+ 'browser/policy/user_cloud_policy_store_base.cc',
+ 'browser/policy/user_cloud_policy_store_base.h',
'browser/policy/user_cloud_policy_store_chromeos.cc',
'browser/policy/user_cloud_policy_store_chromeos.h',
'browser/policy/user_policy_cache.cc',
'browser/policy/user_policy_cache.h',
'browser/policy/user_policy_disk_cache.cc',
'browser/policy/user_policy_disk_cache.h',
+ 'browser/policy/user_policy_signin_service.cc',
+ 'browser/policy/user_policy_signin_service.h',
+ 'browser/policy/user_policy_signin_service_factory.cc',
+ 'browser/policy/user_policy_signin_service_factory.h',
'browser/policy/user_policy_token_cache.cc',
'browser/policy/user_policy_token_cache.h',
'browser/predictors/autocomplete_action_predictor.cc',
@@ -4615,6 +4623,12 @@
['exclude', 'browser/password_manager/native_backend_gnome_x.h'],
['exclude', 'browser/password_manager/native_backend_kwallet_x.cc'],
['exclude', 'browser/password_manager/native_backend_kwallet_x.h'],
+ ['exclude', 'browser/policy/user_cloud_policy_store.cc'],
+ ['exclude', 'browser/policy/user_cloud_policy_store.h'],
+ ['exclude', 'browser/policy/user_policy_signin_service.cc'],
+ ['exclude', 'browser/policy/user_policy_signin_service.h'],
+ ['exclude', 'browser/policy/user_policy_signin_service_factory.cc'],
+ ['exclude', 'browser/policy/user_policy_signin_service_factory.h'],
['exclude', 'browser/platform_util_linux.cc'],
['exclude', 'browser/speech/extension_api/tts_extension_api_linux.cc'],
['exclude', 'browser/ui/webui/help/version_updater_basic.cc'],
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index d7e6e915..a97ad5c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1452,8 +1452,10 @@
'browser/policy/testing_policy_url_fetcher_factory.h',
'browser/policy/url_blacklist_manager_unittest.cc',
'browser/policy/user_cloud_policy_manager_unittest.cc',
+ 'browser/policy/user_cloud_policy_store_unittest.cc',
'browser/policy/user_cloud_policy_store_chromeos_unittest.cc',
'browser/policy/user_policy_cache_unittest.cc',
+ 'browser/policy/user_policy_signin_service_unittest.cc',
'browser/predictors/autocomplete_action_predictor_table_unittest.cc',
'browser/predictors/autocomplete_action_predictor_unittest.cc',
'browser/predictors/resource_prefetch_predictor_unittest.cc',
@@ -2186,6 +2188,9 @@
['exclude', '^browser/media_gallery/media_device_notifications_linux_unittest.cc'],
['exclude', '^browser/password_manager/native_backend_gnome_x_unittest.cc'],
['exclude', '^browser/password_manager/native_backend_kwallet_x_unittest.cc'],
+ ['exclude', '^browser/policy/user_cloud_policy_store_unittest.cc'],
+ ['exclude', '^browser/policy/user_policy_signin_service_unittest.cc'],
+
['exclude', '^browser/safe_browsing/download_protection_service_unittest.cc' ],
],
'sources': [
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index a406daf..4e24a2d 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -821,6 +821,10 @@ const char kKioskModePrinting[] = "kiosk-printing";
// Comma-separated list of directories with component extensions to load.
const char kLoadComponentExtension[] = "load-component-extension";
+// If present, cloud policy will be loaded and applied once the user is signed
+// in to the browser.
+const char kLoadCloudPolicyOnSignin[] = "load-cloud-policy-on-signin";
+
// Loads an extension from the specified directory.
const char kLoadExtension[] = "load-extension";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 0774788..ffac570 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -221,6 +221,7 @@ extern const char kKeepAliveForTest[];
extern const char kKioskMode[];
extern const char kKioskModePrinting[];
extern const char kLoadComponentExtension[];
+extern const char kLoadCloudPolicyOnSignin[];
extern const char kLoadExtension[];
extern const char kLoadOpencryptoki[];
extern const char kUninstallExtension[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 023067f..ec389ed 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1845,6 +1845,9 @@ const char kChromeOsReleaseChannel[] = "cros.system.releaseChannel";
// Value of the enums in TabStrip::LayoutType as an int.
const char kTabStripLayoutType[] = "tab_strip_layout_type";
+// If true, cloud policy for the user is loaded once the user signs in.
+const char kLoadCloudPolicyOnSignin[] = "policy.load_cloud_policy_on_signin";
+
// *************** SERVICE PREFS ***************
// These are attached to the service process.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 2e823de3..54cbc6c 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -708,6 +708,7 @@ extern const char kBackgroundModeEnabled[];
extern const char kDevicePolicyRefreshRate[];
extern const char kUserPolicyRefreshRate[];
+extern const char kLoadCloudPolicyOnSignin[];
extern const char kRecoveryComponentVersion[];
extern const char kComponentUpdaterState[];
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index 5251c93..da4fa89 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -16,8 +16,8 @@
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "content/public/browser/notification_service.h"
#include "net/url_request/url_request_context_getter.h"
-#include "ui/base/clipboard/clipboard.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/clipboard/clipboard.h"
#if !defined(ENABLE_CONFIGURATION_POLICY)
#include "chrome/browser/policy/policy_service_stub.h"
@@ -73,8 +73,10 @@ chrome_variations::VariationsService*
policy::BrowserPolicyConnector*
TestingBrowserProcess::browser_policy_connector() {
#if defined(ENABLE_CONFIGURATION_POLICY)
- if (!browser_policy_connector_.get())
+ if (!browser_policy_connector_.get()) {
browser_policy_connector_.reset(new policy::BrowserPolicyConnector());
+ browser_policy_connector_->Init();
+ }
#endif
return browser_policy_connector_.get();
}
@@ -82,8 +84,7 @@ policy::BrowserPolicyConnector*
policy::PolicyService* TestingBrowserProcess::policy_service() {
if (!policy_service_.get()) {
#if defined(ENABLE_CONFIGURATION_POLICY)
- policy_service_.reset(
- browser_policy_connector()->CreatePolicyService(NULL));
+ policy_service_ = browser_policy_connector()->CreatePolicyService(NULL);
#else
policy_service_.reset(new policy::PolicyServiceStub());
#endif
@@ -249,8 +250,19 @@ CRLSetFetcher* TestingBrowserProcess::crl_set_fetcher() {
}
void TestingBrowserProcess::SetLocalState(PrefService* local_state) {
- if (!local_state && notification_ui_manager_.get())
- notification_ui_manager_.reset(); // Used local_state_.
+ if (!local_state) {
+ // The local_state_ PrefService is owned outside of TestingBrowserProcess,
+ // but some of the members of TestingBrowserProcess hold references to it
+ // (for example, via PrefNotifier members). But given our test
+ // infrastructure which tears down individual tests before freeing the
+ // TestingBrowserProcess, there's not a good way to make local_state outlive
+ // these dependencies. As a workaround, whenever local_state_ is cleared
+ // (assumedly as part of exiting the test and freeing TestingBrowserProcess)
+ // any components owned by TestingBrowserProcess that depend on local_state
+ // are also freed.
+ notification_ui_manager_.reset();
+ browser_policy_connector_.reset();
+ }
local_state_ = local_state;
}
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 388b452..c173ef3 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -34,6 +34,7 @@
#include "chrome/browser/net/proxy_service_factory.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/notifications/desktop_notification_service_factory.h"
+#include "chrome/browser/policy/user_cloud_policy_manager.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/testing_pref_store.h"
#include "chrome/browser/prerender/prerender_manager.h"
@@ -159,30 +160,7 @@ TestingProfile::TestingProfile()
last_session_exited_cleanly_(true),
profile_dependency_manager_(ProfileDependencyManager::GetInstance()),
delegate_(NULL) {
- if (!temp_dir_.CreateUniqueTempDir()) {
- LOG(ERROR) << "Failed to create unique temporary directory.";
-
- // Fallback logic in case we fail to create unique temporary directory.
- FilePath system_tmp_dir;
- bool success = PathService::Get(base::DIR_TEMP, &system_tmp_dir);
-
- // We're severly screwed if we can't get the system temporary
- // directory. Die now to avoid writing to the filesystem root
- // or other bad places.
- CHECK(success);
-
- FilePath fallback_dir(system_tmp_dir.AppendASCII("TestingProfilePath"));
- file_util::Delete(fallback_dir, true);
- file_util::CreateDirectory(fallback_dir);
- if (!temp_dir_.Set(fallback_dir)) {
- // That shouldn't happen, but if it does, try to recover.
- LOG(ERROR) << "Failed to use a fallback temporary directory.";
-
- // We're screwed if this fails, see CHECK above.
- CHECK(temp_dir_.Set(system_tmp_dir));
- }
- }
-
+ CreateTempProfileDir();
profile_path_ = temp_dir_.path();
Init();
@@ -220,6 +198,69 @@ TestingProfile::TestingProfile(const FilePath& path,
}
}
+TestingProfile::TestingProfile(
+ const FilePath& path,
+ Delegate* delegate,
+ scoped_refptr<ExtensionSpecialStoragePolicy> extension_policy,
+ scoped_ptr<PrefService> prefs,
+ scoped_ptr<policy::UserCloudPolicyManager> user_cloud_policy_manager)
+ : start_time_(Time::Now()),
+ prefs_(prefs.release()),
+ testing_prefs_(NULL),
+ incognito_(false),
+ last_session_exited_cleanly_(true),
+ extension_special_storage_policy_(extension_policy),
+ user_cloud_policy_manager_(user_cloud_policy_manager.release()),
+ profile_path_(path),
+ profile_dependency_manager_(ProfileDependencyManager::GetInstance()),
+ delegate_(delegate) {
+
+ // If no profile path was supplied, create one.
+ if (profile_path_.empty()) {
+ CreateTempProfileDir();
+ profile_path_ = temp_dir_.path();
+ }
+
+ Init();
+ // If caller supplied a delegate, delay the FinishInit invocation until other
+ // tasks have run.
+ // TODO(atwilson): See if this is still required once we convert the current
+ // users of the constructor that takes a Delegate* param.
+ if (delegate_) {
+ MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(&TestingProfile::FinishInit,
+ base::Unretained(this)));
+ } else {
+ FinishInit();
+ }
+}
+
+void TestingProfile::CreateTempProfileDir() {
+ if (!temp_dir_.CreateUniqueTempDir()) {
+ LOG(ERROR) << "Failed to create unique temporary directory.";
+
+ // Fallback logic in case we fail to create unique temporary directory.
+ FilePath system_tmp_dir;
+ bool success = PathService::Get(base::DIR_TEMP, &system_tmp_dir);
+
+ // We're severly screwed if we can't get the system temporary
+ // directory. Die now to avoid writing to the filesystem root
+ // or other bad places.
+ CHECK(success);
+
+ FilePath fallback_dir(system_tmp_dir.AppendASCII("TestingProfilePath"));
+ file_util::Delete(fallback_dir, true);
+ file_util::CreateDirectory(fallback_dir);
+ if (!temp_dir_.Set(fallback_dir)) {
+ // That shouldn't happen, but if it does, try to recover.
+ LOG(ERROR) << "Failed to use a fallback temporary directory.";
+
+ // We're screwed if this fails, see CHECK above.
+ CHECK(temp_dir_.Set(system_tmp_dir));
+ }
+ }
+}
+
void TestingProfile::Init() {
if (!file_util::PathExists(profile_path_))
file_util::CreateDirectory(profile_path_);
@@ -494,6 +535,10 @@ net::CookieMonster* TestingProfile::GetCookieMonster() {
GetCookieMonster();
}
+policy::UserCloudPolicyManager* TestingProfile::GetUserCloudPolicyManager() {
+ return user_cloud_policy_manager_.get();
+}
+
policy::PolicyService* TestingProfile::GetPolicyService() {
if (!policy_service_.get()) {
#if defined(ENABLE_CONFIGURATION_POLICY)
@@ -732,3 +777,46 @@ base::Callback<ChromeURLDataManagerBackend*(void)>
TestingProfile::GetChromeURLDataManagerBackendGetter() const {
return base::Callback<ChromeURLDataManagerBackend*(void)>();
}
+
+TestingProfile::Builder::Builder()
+ : build_called_(false),
+ delegate_(NULL) {
+}
+
+TestingProfile::Builder::~Builder() {
+}
+
+void TestingProfile::Builder::SetPath(const FilePath& path) {
+ path_ = path;
+}
+
+void TestingProfile::Builder::SetDelegate(Delegate* delegate) {
+ delegate_ = delegate;
+}
+
+void TestingProfile::Builder::SetExtensionSpecialStoragePolicy(
+ scoped_refptr<ExtensionSpecialStoragePolicy> policy) {
+ extension_policy_ = policy;
+}
+
+void TestingProfile::Builder::SetPrefService(scoped_ptr<PrefService> prefs) {
+ pref_service_ = prefs.Pass();
+}
+
+void TestingProfile::Builder::SetUserCloudPolicyManager(
+ scoped_ptr<policy::UserCloudPolicyManager> manager) {
+ user_cloud_policy_manager_ = manager.Pass();
+}
+
+scoped_ptr<TestingProfile> TestingProfile::Builder::Build() {
+ DCHECK(!build_called_);
+ build_called_ = true;
+ return scoped_ptr<TestingProfile>(new TestingProfile(
+ path_,
+ delegate_,
+ extension_policy_,
+ pref_service_.Pass(),
+ user_cloud_policy_manager_.Pass()));
+}
+
+
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index 0e34cdd..493f903 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -58,6 +58,54 @@ class TestingProfile : public Profile {
// Default constructor that cannot be used with multi-profiles.
TestingProfile();
+ // Helper class for building an instance of TestingProfile (allows injecting
+ // mocks for various services prior to profile initialization).
+ // TODO(atwilson): Remove non-default constructors and various setters in
+ // favor of using the Builder API.
+ class Builder {
+ public:
+ Builder();
+ ~Builder();
+
+ // Sets a Delegate to be called back when the Profile is fully initialized.
+ // This causes the final initialization to be performed via a task so the
+ // caller must run a MessageLoop. Caller maintains ownership of the Delegate
+ // and must manage its lifetime so it continues to exist until profile
+ // initialization is complete.
+ void SetDelegate(Delegate* delegate);
+
+ // Sets the ExtensionSpecialStoragePolicy to be returned by
+ // GetExtensionSpecialStoragePolicy().
+ void SetExtensionSpecialStoragePolicy(
+ scoped_refptr<ExtensionSpecialStoragePolicy> policy);
+
+ // Sets the path to the directory to be used to hold profile data.
+ void SetPath(const FilePath& path);
+
+ // Sets the PrefService to be used by this profile.
+ void SetPrefService(scoped_ptr<PrefService> prefs);
+
+ // Sets the UserCloudPolicyManager to be used by this profile.
+ void SetUserCloudPolicyManager(
+ scoped_ptr<policy::UserCloudPolicyManager> manager);
+
+ // Creates the TestingProfile using previously-set settings.
+ scoped_ptr<TestingProfile> Build();
+
+ private:
+ // If true, Build() has already been called.
+ bool build_called_;
+
+ // Various staging variables where values are held until Build() is invoked.
+ scoped_ptr<policy::UserCloudPolicyManager> user_cloud_policy_manager_;
+ scoped_ptr<PrefService> pref_service_;
+ scoped_refptr<ExtensionSpecialStoragePolicy> extension_policy_;
+ FilePath path_;
+ Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(Builder);
+ };
+
// Multi-profile aware constructor that takes the path to a directory managed
// for this profile. This constructor is meant to be used by
// TestingProfileManager::CreateTestingProfile. If you need to create multi-
@@ -71,6 +119,14 @@ class TestingProfile : public Profile {
// for unittesting the ProfileManager.
TestingProfile(const FilePath& path, Delegate* delegate);
+ // Full constructor allowing the setting of all possible instance data.
+ // Callers should use Builder::Build() instead of invoking this constructor.
+ TestingProfile(const FilePath& path,
+ Delegate* delegate,
+ scoped_refptr<ExtensionSpecialStoragePolicy> extension_policy,
+ scoped_ptr<PrefService> prefs,
+ scoped_ptr<policy::UserCloudPolicyManager> manager);
+
virtual ~TestingProfile();
// Creates the favicon service. Consequent calls would recreate the service.
@@ -167,6 +223,8 @@ class TestingProfile : public Profile {
// this by calling CreateRequestContext(). See the note at GetRequestContext
// for more information.
net::CookieMonster* GetCookieMonster();
+
+ virtual policy::UserCloudPolicyManager* GetUserCloudPolicyManager() OVERRIDE;
virtual policy::PolicyService* GetPolicyService() OVERRIDE;
// Sets the profile's PrefService. If a pref service hasn't been explicitly
// set GetPrefs creates one, so normally you need not invoke this. If you need
@@ -242,6 +300,9 @@ class TestingProfile : public Profile {
TestingPrefService* testing_prefs_;
private:
+ // Creates a temporary directory for use by this profile.
+ void CreateTempProfileDir();
+
// Common initialization between the two constructors.
void Init();
@@ -289,6 +350,9 @@ class TestingProfile : public Profile {
// The proxy prefs tracker.
scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
+ // UserCloudPolicyManager returned by GetUserCloudPolicyManager().
+ scoped_ptr<policy::UserCloudPolicyManager> user_cloud_policy_manager_;
+
// We use a temporary directory to store testing profile data. In a multi-
// profile environment, this is invalid and the directory is managed by the
// TestingProfileManager.