Commit 82110212 authored by bauerb@chromium.org's avatar bauerb@chromium.org

Add ManagedUserSharedSettingsService.

ManagedUserSharedSettingsService syncs settings that can be modified/accessed both by a supervised user and their manager (for example, the avatar).

BUG=316168

Review URL: https://codereview.chromium.org/123293003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243680 0039d316-1c4b-4281-b951-d872f2087c98
parent c829088c
// Copyright 2014 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_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_SERVICE_H_
#define CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_SERVICE_H_
#include "base/callback.h"
#include "base/callback_list.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/managed_mode/managed_users.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "sync/api/syncable_service.h"
class PrefService;
namespace base {
class DictionaryValue;
class Value;
}
namespace user_prefs {
class PrefRegistrySyncable;
}
// ManagedUserSharedSettingsService syncs settings (as key-value pairs) that can
// be modified both by a supervised user and their manager.
// A supervised user can only modify their own settings, whereas a manager can
// modify settings for all their supervised users.
//
// The shared settings are stored in the user preferences in a multi-level
// dictionary. The first level is the MU ID, the second level is the key for the
// setting, and the third level is a dictionary with a "value" key for the value
// and an "acknowledged" flag, which is used to wait for the Sync server to
// acknowledge that it has seen a setting change (see
// ManagedUserSharedSettingsUpdate for how to use this).
class ManagedUserSharedSettingsService : public BrowserContextKeyedService,
public syncer::SyncableService {
public:
// Called whenever a setting changes (see Subscribe() below).
typedef base::Callback<void(const std::string& /* mu_id */,
const std::string& /* key */)> ChangeCallback;
typedef base::CallbackList<
void(const std::string& /* mu_id */, const std::string& /* key */)>
ChangeCallbackList;
// This constructor is public only for testing. Use
// |ManagedUserSyncServiceFactory::GetForProfile(...)| instead to get an
// instance of this service in production code.
explicit ManagedUserSharedSettingsService(PrefService* prefs);
virtual ~ManagedUserSharedSettingsService();
// Returns the value for the given |key| and the supervised user identified by
// |mu_id|. If either the supervised user or the key does not exist, NULL is
// returned. Note that if the profile that owns this service belongs to a
// supervised user, callers will only see settings for their own |mu_id|, i.e.
// a non-matching |mu_id| is treated as non-existent.
const base::Value* GetValue(const std::string& mu_id, const std::string& key);
// Sets the value for the given |key| and the supervised user identified by
// |mu_id|. If the profile that owns this service belongs to a supervised
// user, |mu_id| must be their own.
void SetValue(const std::string& mu_id,
const std::string& key,
const base::Value& value);
// Subscribes to changes in the synced settings. The callback will be notified
// whenever any setting for any supervised user is changed via Sync (but not
// for local changes). Subscribers should filter the settings and users they
// are interested in with the |mu_id| and |key| parameters to the callback.
scoped_ptr<ChangeCallbackList::Subscription> Subscribe(
const ChangeCallback& cb);
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Public for testing.
void SetValueInternal(const std::string& mu_id,
const std::string& key,
const base::Value& value,
bool acknowledged);
// Public for testing.
static syncer::SyncData CreateSyncDataForSetting(const std::string& mu_id,
const std::string& key,
const base::Value& value,
bool acknowledged);
// BrowserContextKeyedService implementation:
virtual void Shutdown() OVERRIDE;
// SyncableService implementation:
virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
syncer::ModelType type,
const syncer::SyncDataList& initial_sync_data,
scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
OVERRIDE;
virtual syncer::SyncError ProcessSyncChanges(
const tracked_objects::Location& from_here,
const syncer::SyncChangeList& change_list) OVERRIDE;
private:
friend class ManagedUserSharedSettingsUpdate;
scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
scoped_ptr<syncer::SyncErrorFactory> error_handler_;
ChangeCallbackList callbacks_;
PrefService* prefs_;
};
#endif // CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_SERVICE_H_
// Copyright 2014 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/managed_mode/managed_user_shared_settings_service_factory.h"
#include "chrome/browser/managed_mode/managed_user_shared_settings_service.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
// static
ManagedUserSharedSettingsService*
ManagedUserSharedSettingsServiceFactory::GetForBrowserContext(
content::BrowserContext* profile) {
return static_cast<ManagedUserSharedSettingsService*>(
GetInstance()->GetServiceForBrowserContext(profile, true));
}
// static
ManagedUserSharedSettingsServiceFactory*
ManagedUserSharedSettingsServiceFactory::GetInstance() {
return Singleton<ManagedUserSharedSettingsServiceFactory>::get();
}
ManagedUserSharedSettingsServiceFactory::
ManagedUserSharedSettingsServiceFactory()
: BrowserContextKeyedServiceFactory(
"ManagedUserSharedSettingsService",
BrowserContextDependencyManager::GetInstance()) {}
ManagedUserSharedSettingsServiceFactory::
~ManagedUserSharedSettingsServiceFactory() {}
BrowserContextKeyedService*
ManagedUserSharedSettingsServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* profile) const {
return new ManagedUserSharedSettingsService(
user_prefs::UserPrefs::Get(profile));
}
// Copyright 2014 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_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_SERVICE_FACTORY_H_
#define CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_SERVICE_FACTORY_H_
#include "base/memory/singleton.h"
#include "chrome/browser/managed_mode/managed_users.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
class ManagedUserSharedSettingsService;
class ManagedUserSharedSettingsServiceFactory
: public BrowserContextKeyedServiceFactory {
public:
static ManagedUserSharedSettingsService* GetForBrowserContext(
content::BrowserContext* profile);
static ManagedUserSharedSettingsServiceFactory* GetInstance();
private:
friend struct DefaultSingletonTraits<ManagedUserSharedSettingsServiceFactory>;
ManagedUserSharedSettingsServiceFactory();
virtual ~ManagedUserSharedSettingsServiceFactory();
// BrowserContextKeyedServiceFactory:
virtual BrowserContextKeyedService* BuildServiceInstanceFor(
content::BrowserContext* profile) const OVERRIDE;
};
#endif // CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_SERVICE_FACTORY_H_
// Copyright 2014 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/managed_mode/managed_user_shared_settings_update.h"
#include "base/bind.h"
#include "base/values.h"
#include "chrome/browser/managed_mode/managed_user_shared_settings_service.h"
ManagedUserSharedSettingsUpdate::ManagedUserSharedSettingsUpdate(
ManagedUserSharedSettingsService* service,
const std::string& mu_id,
const std::string& key,
scoped_ptr<base::Value> value,
const base::Callback<void(bool)>& success_callback)
: service_(service),
mu_id_(mu_id),
key_(key),
value_(value.Pass()),
callback_(success_callback) {
service->SetValueInternal(mu_id, key, *value_, false);
subscription_ = service->Subscribe(
base::Bind(&ManagedUserSharedSettingsUpdate::OnSettingChanged,
base::Unretained(this)));
}
ManagedUserSharedSettingsUpdate::~ManagedUserSharedSettingsUpdate() {}
void ManagedUserSharedSettingsUpdate::OnSettingChanged(const std::string& mu_id,
const std::string& key) {
if (mu_id != mu_id_)
return;
if (key != key_)
return;
const base::Value* value = service_->GetValue(mu_id, key);
callback_.Run(value->Equals(value_.get()));
}
// Copyright 2014 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_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_UPDATE_H_
#define CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_UPDATE_H_
#include <string>
#include "base/callback.h"
#include "base/callback_list.h"
#include "base/memory/scoped_ptr.h"
namespace base {
class Value;
}
class ManagedUserSharedSettingsService;
// Lets clients of ManagedUserSharedSettingsService change settings and wait for
// the Sync server to acknowledge the change. The callback passed in the
// constructor will be called with a true success value after the Sync server
// has flipped the acknowledgement flag for the setting. If another client
// changes the value in the mean time, the callback will be run with a false
// success value. If the object is destroyed before that, the callback will not
// be run. Note that any changes made to the setting will not be undone when
// destroying the object, even if the update was not successful or was canceled.
class ManagedUserSharedSettingsUpdate {
public:
ManagedUserSharedSettingsUpdate(
ManagedUserSharedSettingsService* service,
const std::string& mu_id,
const std::string& key,
scoped_ptr<base::Value> value,
const base::Callback<void(bool)>& success_callback);
~ManagedUserSharedSettingsUpdate();
private:
typedef base::CallbackList<void(const std::string&, const std::string&)>
CallbackList;
void OnSettingChanged(const std::string& mu_id,
const std::string& key);
ManagedUserSharedSettingsService* service_;
std::string mu_id_;
std::string key_;
scoped_ptr<base::Value> value_;
base::Callback<void(bool)> callback_;
scoped_ptr<CallbackList::Subscription> subscription_;
};
#endif // CHROME_BROWSER_MANAGED_MODE_MANAGED_USER_SHARED_SETTINGS_UPDATE_H_
// Copyright 2014 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/bind.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/managed_mode/managed_user_shared_settings_service.h"
#include "chrome/browser/managed_mode/managed_user_shared_settings_update.h"
#include "chrome/test/base/testing_profile.h"
#include "sync/api/sync_change.h"
#include "testing/gtest/include/gtest/gtest.h"
class ManagedUserSharedSettingsUpdateTest : public testing::Test {
public:
ManagedUserSharedSettingsUpdateTest() : service_(profile_.GetPrefs()) {}
virtual ~ManagedUserSharedSettingsUpdateTest() {}
void OnSettingUpdated(bool success) {
result_.reset(new bool(success));
}
protected:
TestingProfile profile_;
ManagedUserSharedSettingsService service_;
scoped_ptr<bool> result_;
};
TEST_F(ManagedUserSharedSettingsUpdateTest, Success) {
ManagedUserSharedSettingsUpdate update(
&service_,
"abcdef",
"name",
scoped_ptr<base::Value>(new base::StringValue("Hans Moleman")),
base::Bind(&ManagedUserSharedSettingsUpdateTest::OnSettingUpdated,
base::Unretained(this)));
syncer::SyncChangeList changes;
changes.push_back(syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
ManagedUserSharedSettingsService::CreateSyncDataForSetting(
"abcdef", "name", base::StringValue("Hans Moleman"), true)));
syncer::SyncError error = service_.ProcessSyncChanges(FROM_HERE, changes);
EXPECT_FALSE(error.IsSet()) << error.ToString();
ASSERT_TRUE(result_);
EXPECT_TRUE(*result_);
}
TEST_F(ManagedUserSharedSettingsUpdateTest, Failure) {
ManagedUserSharedSettingsUpdate update(
&service_,
"abcdef",
"name",
scoped_ptr<base::Value>(new base::StringValue("Hans Moleman")),
base::Bind(&ManagedUserSharedSettingsUpdateTest::OnSettingUpdated,
base::Unretained(this)));
// Syncing down a different change will cause the update to fail.
syncer::SyncChangeList changes;
changes.push_back(syncer::SyncChange(
FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
ManagedUserSharedSettingsService::CreateSyncDataForSetting(
"abcdef",
"name",
base::StringValue("Barney Gumble"),
true)));
syncer::SyncError error = service_.ProcessSyncChanges(FROM_HERE, changes);
EXPECT_FALSE(error.IsSet()) << error.ToString();
ASSERT_TRUE(result_);
EXPECT_FALSE(*result_);
}
TEST_F(ManagedUserSharedSettingsUpdateTest, Cancel) {
{
ManagedUserSharedSettingsUpdate update(
&service_,
"abcdef",
"name",
scoped_ptr<base::Value>(new base::StringValue("Hans Moleman")),
base::Bind(&ManagedUserSharedSettingsUpdateTest::OnSettingUpdated,
base::Unretained(this)));
ASSERT_FALSE(result_);
}
ASSERT_FALSE(result_);
}
...@@ -112,6 +112,7 @@ ...@@ -112,6 +112,7 @@
#if defined(ENABLE_MANAGED_USERS) #if defined(ENABLE_MANAGED_USERS)
#include "chrome/browser/managed_mode/managed_user_service.h" #include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/managed_mode/managed_user_shared_settings_service.h"
#include "chrome/browser/managed_mode/managed_user_sync_service.h" #include "chrome/browser/managed_mode/managed_user_sync_service.h"
#endif #endif
...@@ -387,6 +388,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { ...@@ -387,6 +388,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
#if defined(ENABLE_MANAGED_USERS) #if defined(ENABLE_MANAGED_USERS)
ManagedUserService::RegisterProfilePrefs(registry); ManagedUserService::RegisterProfilePrefs(registry);
ManagedUserSharedSettingsService::RegisterProfilePrefs(registry);
ManagedUserSyncService::RegisterProfilePrefs(registry); ManagedUserSyncService::RegisterProfilePrefs(registry);
#endif #endif
......
...@@ -72,6 +72,8 @@ ...@@ -72,6 +72,8 @@
#if defined(ENABLE_MANAGED_USERS) #if defined(ENABLE_MANAGED_USERS)
#include "chrome/browser/managed_mode/managed_user_settings_service.h" #include "chrome/browser/managed_mode/managed_user_settings_service.h"
#include "chrome/browser/managed_mode/managed_user_settings_service_factory.h" #include "chrome/browser/managed_mode/managed_user_settings_service_factory.h"
#include "chrome/browser/managed_mode/managed_user_shared_settings_service.h"
#include "chrome/browser/managed_mode/managed_user_shared_settings_service_factory.h"
#include "chrome/browser/managed_mode/managed_user_sync_service.h" #include "chrome/browser/managed_mode/managed_user_sync_service.h"
#include "chrome/browser/managed_mode/managed_user_sync_service_factory.h" #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
#endif #endif
...@@ -227,6 +229,9 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes( ...@@ -227,6 +229,9 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
new UIDataTypeController( new UIDataTypeController(
syncer::MANAGED_USERS, this, profile_, pss)); syncer::MANAGED_USERS, this, profile_, pss));
} }
pss->RegisterDataTypeController(
new UIDataTypeController(
syncer::MANAGED_USER_SHARED_SETTINGS, this, profile_, pss));
#endif #endif
} }
...@@ -434,6 +439,9 @@ base::WeakPtr<syncer::SyncableService> ProfileSyncComponentsFactoryImpl:: ...@@ -434,6 +439,9 @@ base::WeakPtr<syncer::SyncableService> ProfileSyncComponentsFactoryImpl::
case syncer::MANAGED_USERS: case syncer::MANAGED_USERS:
return ManagedUserSyncServiceFactory::GetForProfile(profile_)-> return ManagedUserSyncServiceFactory::GetForProfile(profile_)->
AsWeakPtr(); AsWeakPtr();
case syncer::MANAGED_USER_SHARED_SETTINGS:
return ManagedUserSharedSettingsServiceFactory::GetForBrowserContext(
profile_)->AsWeakPtr();
#endif #endif
case syncer::ARTICLES: { case syncer::ARTICLES: {
dom_distiller::DomDistillerService* service = dom_distiller::DomDistillerService* service =
......
...@@ -59,6 +59,7 @@ class ProfileSyncComponentsFactoryImplTest : public testing::Test { ...@@ -59,6 +59,7 @@ class ProfileSyncComponentsFactoryImplTest : public testing::Test {
datatypes.push_back(syncer::FAVICON_IMAGES); datatypes.push_back(syncer::FAVICON_IMAGES);
datatypes.push_back(syncer::SYNCED_NOTIFICATIONS); datatypes.push_back(syncer::SYNCED_NOTIFICATIONS);
datatypes.push_back(syncer::MANAGED_USERS); datatypes.push_back(syncer::MANAGED_USERS);
datatypes.push_back(syncer::MANAGED_USER_SHARED_SETTINGS);
return datatypes; return datatypes;
} }
......
...@@ -1036,6 +1036,12 @@ ...@@ -1036,6 +1036,12 @@
'browser/managed_mode/managed_user_service.h', 'browser/managed_mode/managed_user_service.h',
'browser/managed_mode/managed_user_service_factory.cc', 'browser/managed_mode/managed_user_service_factory.cc',
'browser/managed_mode/managed_user_service_factory.h', 'browser/managed_mode/managed_user_service_factory.h',
'browser/managed_mode/managed_user_shared_settings_service.cc',
'browser/managed_mode/managed_user_shared_settings_service.h',
'browser/managed_mode/managed_user_shared_settings_service_factory.cc',
'browser/managed_mode/managed_user_shared_settings_service_factory.h',
'browser/managed_mode/managed_user_shared_settings_update.cc',
'browser/managed_mode/managed_user_shared_settings_update.h',
'browser/managed_mode/managed_user_sync_service.cc', 'browser/managed_mode/managed_user_sync_service.cc',
'browser/managed_mode/managed_user_sync_service.h', 'browser/managed_mode/managed_user_sync_service.h',
'browser/managed_mode/managed_user_sync_service_factory.cc', 'browser/managed_mode/managed_user_sync_service_factory.cc',
......
...@@ -1006,6 +1006,8 @@ ...@@ -1006,6 +1006,8 @@
'browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc', 'browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc',
'browser/managed_mode/managed_user_registration_utility_unittest.cc', 'browser/managed_mode/managed_user_registration_utility_unittest.cc',
'browser/managed_mode/managed_user_settings_service_unittest.cc', 'browser/managed_mode/managed_user_settings_service_unittest.cc',
'browser/managed_mode/managed_user_shared_settings_service_unittest.cc',
'browser/managed_mode/managed_user_shared_settings_update_unittest.cc',
'browser/managed_mode/supervised_user_pref_store_unittest.cc', 'browser/managed_mode/supervised_user_pref_store_unittest.cc',
'browser/media/desktop_media_list_ash_unittest.cc', 'browser/media/desktop_media_list_ash_unittest.cc',
'browser/media/native_desktop_media_list_unittest.cc', 'browser/media/native_desktop_media_list_unittest.cc',
......
...@@ -47,6 +47,11 @@ const char kManagedUserCustodianEmail[] = "profile.managed.custodian_email"; ...@@ -47,6 +47,11 @@ const char kManagedUserCustodianEmail[] = "profile.managed.custodian_email";
// starts a session. // starts a session.
const char kManagedUserCustodianName[] = "profile.managed.custodian_name"; const char kManagedUserCustodianName[] = "profile.managed.custodian_name";
// Stores settings that can be modified both by a supervised user and their
// manager. See ManagedUserSharedSettingsService for a description of
// the format.
const char kManagedUserSharedSettings[] = "profile.managed.shared_settings";
// An integer that keeps track of the profile icon version. This allows us to // An integer that keeps track of the profile icon version. This allows us to
// determine the state of the profile icon for icon format changes. // determine the state of the profile icon for icon format changes.
const char kProfileIconVersion[] = "profile.icon_version"; const char kProfileIconVersion[] = "profile.icon_version";
......
...@@ -25,6 +25,7 @@ extern const char kManagedModeManualHosts[]; ...@@ -25,6 +25,7 @@ extern const char kManagedModeManualHosts[];
extern const char kManagedModeManualURLs[]; extern const char kManagedModeManualURLs[];
extern const char kManagedUserCustodianEmail[]; extern const char kManagedUserCustodianEmail[];
extern const char kManagedUserCustodianName[]; extern const char kManagedUserCustodianName[];
extern const char kManagedUserSharedSettings[];
extern const char kProfileIconVersion[]; extern const char kProfileIconVersion[];
extern const char kRestoreOnStartup[]; extern const char kRestoreOnStartup[];
extern const char kRestoreOnStartupMigrated[]; extern const char kRestoreOnStartupMigrated[];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment