1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SHARED_SETTINGS_SERVICE_H_
6#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SHARED_SETTINGS_SERVICE_H_
7
8#include "base/callback.h"
9#include "base/callback_list.h"
10#include "base/memory/scoped_ptr.h"
11#include "chrome/browser/supervised_user/supervised_users.h"
12#include "components/keyed_service/core/keyed_service.h"
13#include "sync/api/syncable_service.h"
14
15class PrefService;
16
17namespace base {
18class DictionaryValue;
19class Value;
20}
21
22namespace user_prefs {
23class PrefRegistrySyncable;
24}
25
26// SupervisedUserSharedSettingsService syncs settings (as key-value pairs) that
27// can be modified both by a supervised user and their manager.
28// A supervised user can only modify their own settings, whereas a manager can
29// modify settings for all their supervised users.
30//
31// The shared settings are stored in the user preferences in a multi-level
32// dictionary. The first level is the SU ID (called "managed user ID" on the
33// server for historic reasons), the second level is the key for the setting,
34// and the third level is a dictionary with a "value" key for the value and an
35// "acknowledged" flag, which is used to wait for the Sync server to acknowledge
36// that it has seen a setting change (see SupervisedUserSharedSettingsUpdate for
37// how to use this).
38class SupervisedUserSharedSettingsService : public KeyedService,
39                                            public syncer::SyncableService {
40 public:
41  // Called whenever a setting changes (see Subscribe() below).
42  typedef base::Callback<void(const std::string& /* su_id */,
43                              const std::string& /* key */)> ChangeCallback;
44  typedef base::CallbackList<
45      void(const std::string& /* su_id */, const std::string& /* key */)>
46      ChangeCallbackList;
47
48  // This constructor is public only for testing. Use
49  // |SupervisedUserSharedSettingsServiceFactory::GetForProfile(...)| instead to
50  // get an instance of this service in production code.
51  explicit SupervisedUserSharedSettingsService(PrefService* prefs);
52  virtual ~SupervisedUserSharedSettingsService();
53
54  // Returns the value for the given |key| and the supervised user identified by
55  // |su_id|. If either the supervised user or the key does not exist, NULL is
56  // returned. Note that if the profile that owns this service belongs to a
57  // supervised user, callers will only see settings for their own |su_id|, i.e.
58  // a non-matching |su_id| is treated as non-existent.
59  const base::Value* GetValue(const std::string& su_id, const std::string& key);
60
61  // Sets the value for the given |key| and the supervised user identified by
62  // |su_id|. If the profile that owns this service belongs to a supervised
63  // user, |su_id| must be their own.
64  void SetValue(const std::string& su_id,
65                const std::string& key,
66                const base::Value& value);
67
68  // Subscribes to changes in the synced settings. The callback will be notified
69  // whenever any setting for any supervised user is changed via Sync (but not
70  // for local changes). Subscribers should filter the settings and users they
71  // are interested in with the |su_id| and |key| parameters to the callback.
72  scoped_ptr<ChangeCallbackList::Subscription> Subscribe(
73      const ChangeCallback& cb);
74
75  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
76
77  // Public for testing.
78  void SetValueInternal(const std::string& su_id,
79                        const std::string& key,
80                        const base::Value& value,
81                        bool acknowledged);
82
83  // Public for testing.
84  static syncer::SyncData CreateSyncDataForSetting(const std::string& su_id,
85                                                   const std::string& key,
86                                                   const base::Value& value,
87                                                   bool acknowledged);
88
89  // KeyedService implementation:
90  virtual void Shutdown() OVERRIDE;
91
92  // SyncableService implementation:
93  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
94      syncer::ModelType type,
95      const syncer::SyncDataList& initial_sync_data,
96      scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
97      scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
98  virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
99  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
100      OVERRIDE;
101  virtual syncer::SyncError ProcessSyncChanges(
102      const tracked_objects::Location& from_here,
103      const syncer::SyncChangeList& change_list) OVERRIDE;
104
105 private:
106  scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
107  scoped_ptr<syncer::SyncErrorFactory> error_handler_;
108
109  ChangeCallbackList callbacks_;
110
111  PrefService* prefs_;
112};
113
114#endif  // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SHARED_SETTINGS_SERVICE_H_
115