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_SYNC_SERVICE_H_
6#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SYNC_SERVICE_H_
7
8#include <vector>
9
10#include "base/callback_forward.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/observer_list.h"
13#include "base/prefs/pref_change_registrar.h"
14#include "chrome/browser/supervised_user/supervised_user_sync_service_observer.h"
15#include "chrome/browser/supervised_user/supervised_users.h"
16#include "components/keyed_service/core/keyed_service.h"
17#include "sync/api/syncable_service.h"
18
19namespace base {
20class DictionaryValue;
21}
22
23namespace user_prefs {
24class PrefRegistrySyncable;
25}
26
27class PrefService;
28
29class SupervisedUserSyncService : public KeyedService,
30                                  public syncer::SyncableService {
31 public:
32  // For use with GetSupervisedUsersAsync() below.
33  typedef base::Callback<void(const base::DictionaryValue*)>
34      SupervisedUsersCallback;
35
36  // Dictionary keys for entry values of |prefs::kSupervisedUsers|.
37  static const char kAcknowledged[];
38  static const char kChromeAvatar[];
39  static const char kChromeOsAvatar[];
40  static const char kMasterKey[];
41  static const char kPasswordSignatureKey[];
42  static const char kPasswordEncryptionKey[];
43  static const char kName[];
44
45  // Represents a non-existing avatar on Chrome and Chrome OS.
46  static const int kNoAvatar;
47
48  virtual ~SupervisedUserSyncService();
49
50  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
51
52  // Extracts the avatar index from the input |avatar_str| and set
53  // |avatar_index| to hold the extracted value. Returns true if the
54  // index was extracted successfully and false otherwise.
55  // |avatar_str| should have the format: "chrome-avatar-index:INDEX"
56  // where INDEX is the integer to be extracted. |avatar_str| can be empty
57  // in case there is no avatar synced for a supervised user in which case
58  // |avatar_index| is set to -1.
59  static bool GetAvatarIndex(const std::string& avatar_str,
60                             int* avatar_index);
61
62  // Given an |avatar_index|, it returns a string of the form:
63  // "chrome-avatar-index:INDEX" where INDEX = |avatar_index|.
64  // It is exposed for testing purposes only.
65  static std::string BuildAvatarString(int avatar_index);
66
67  void AddObserver(SupervisedUserSyncServiceObserver* observer);
68  void RemoveObserver(SupervisedUserSyncServiceObserver* observer);
69
70  void AddSupervisedUser(const std::string& id,
71                         const std::string& name,
72                         const std::string& master_key,
73                         const std::string& signature_key,
74                         const std::string& encryption_key,
75                         int avatar_index);
76  void UpdateSupervisedUser(const std::string& id,
77                            const std::string& name,
78                            const std::string& master_key,
79                            const std::string& signature_key,
80                            const std::string& encryption_key,
81                            int avatar_index);
82
83  void DeleteSupervisedUser(const std::string& id);
84
85  // Updates the supervised user avatar only if the supervised user has
86  // no avatar and |avatar_index| is set to some value other than
87  // |kNoAvatar|. If |avatar_index| equals |kNoAvatar| and the
88  // supervised user has an avatar, it will be cleared. However,
89  // to clear an avatar call the convenience method
90  // |ClearSupervisedUserAvatar()|.
91  // Returns true if the avatar value is changed (either updated or cleared)
92  // and false otherwise.
93  bool UpdateSupervisedUserAvatarIfNeeded(const std::string& id,
94                                          int avatar_index);
95  void ClearSupervisedUserAvatar(const std::string& id);
96
97  // Returns a dictionary containing all supervised users supervised by this
98  // custodian. This method should only be called once this service has started
99  // syncing supervised users (i.e. has finished its initial merge of local and
100  // server-side data, via MergeDataAndStartSyncing), as the stored data might
101  // be outdated before that.
102  const base::DictionaryValue* GetSupervisedUsers();
103
104  // Calls the passed |callback| with a dictionary containing all supervised
105  // users managed by this custodian.
106  void GetSupervisedUsersAsync(const SupervisedUsersCallback& callback);
107
108  // KeyedService implementation:
109  virtual void Shutdown() OVERRIDE;
110
111  // SyncableService implementation:
112  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
113      syncer::ModelType type,
114      const syncer::SyncDataList& initial_sync_data,
115      scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
116      scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
117  virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
118  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
119      OVERRIDE;
120  virtual syncer::SyncError ProcessSyncChanges(
121      const tracked_objects::Location& from_here,
122      const syncer::SyncChangeList& change_list) OVERRIDE;
123
124 private:
125  friend class SupervisedUserSyncServiceFactory;
126
127  // Use |SupervisedUserSyncServiceFactory::GetForProfile(...)| to get an
128  // instance of this service.
129  explicit SupervisedUserSyncService(PrefService* prefs);
130
131  void OnLastSignedInUsernameChange();
132
133  scoped_ptr<base::DictionaryValue> CreateDictionary(
134      const std::string& name,
135      const std::string& master_key,
136      const std::string& signature_key,
137      const std::string& encryption_key,
138      int avatar_index);
139
140  void UpdateSupervisedUserImpl(const std::string& id,
141                                const std::string& name,
142                                const std::string& master_key,
143                                const std::string& signature_key,
144                                const std::string& encryption_key,
145                                int avatar_index,
146                                bool add_user);
147
148  void NotifySupervisedUserAcknowledged(const std::string& supervised_user_id);
149  void NotifySupervisedUsersSyncingStopped();
150  void NotifySupervisedUsersChanged();
151
152  void DispatchCallbacks();
153
154  PrefService* prefs_;
155  PrefChangeRegistrar pref_change_registrar_;
156
157  scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
158  scoped_ptr<syncer::SyncErrorFactory> error_handler_;
159
160  ObserverList<SupervisedUserSyncServiceObserver> observers_;
161
162  std::vector<SupervisedUsersCallback> callbacks_;
163
164  DISALLOW_COPY_AND_ASSIGN(SupervisedUserSyncService);
165};
166
167#endif  // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SYNC_SERVICE_H_
168