Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: chrome/browser/managed_mode/managed_user_shared_settings_service.cc

Issue 335833003: Rename "managed (mode|user)" to "supervised user" (part 2) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review comments (+ a few other cleanups) Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "chrome/browser/managed_mode/managed_user_shared_settings_service.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/values.h"
12 #include "chrome/common/pref_names.h"
13 #include "components/pref_registry/pref_registry_syncable.h"
14 #include "sync/api/sync_change.h"
15 #include "sync/api/sync_data.h"
16 #include "sync/api/sync_error.h"
17 #include "sync/api/sync_error_factory.h"
18 #include "sync/api/sync_merge_result.h"
19 #include "sync/protocol/sync.pb.h"
20
21 using base::DictionaryValue;
22 using base::Value;
23 using syncer::SUPERVISED_USER_SHARED_SETTINGS;
24 using syncer::ModelType;
25 using syncer::SyncChange;
26 using syncer::SyncChangeList;
27 using syncer::SyncChangeProcessor;
28 using syncer::SyncData;
29 using syncer::SyncDataList;
30 using syncer::SyncError;
31 using syncer::SyncErrorFactory;
32 using syncer::SyncMergeResult;
33
34 namespace {
35
36 const char kAcknowledged[] = "acknowledged";
37 const char kValue[] = "value";
38
39 DictionaryValue* FindOrCreateDictionary(DictionaryValue* parent,
40 const std::string& key) {
41 DictionaryValue* dict = NULL;
42 if (!parent->GetDictionaryWithoutPathExpansion(key, &dict)) {
43 dict = new DictionaryValue;
44 parent->SetWithoutPathExpansion(key, dict);
45 }
46 return dict;
47 }
48
49 class ScopedManagedUserSharedSettingsUpdate {
50 public:
51 ScopedManagedUserSharedSettingsUpdate(PrefService* prefs,
52 const std::string& mu_id)
53 : update_(prefs, prefs::kSupervisedUserSharedSettings), mu_id_(mu_id) {
54 DCHECK(!mu_id.empty());
55
56 // A supervised user can only modify their own settings.
57 std::string id = prefs->GetString(prefs::kSupervisedUserId);
58 DCHECK(id.empty() || id == mu_id);
59 }
60
61 DictionaryValue* Get() {
62 return FindOrCreateDictionary(update_.Get(), mu_id_);
63 }
64
65 private:
66 DictionaryPrefUpdate update_;
67 std::string mu_id_;
68 };
69
70 SyncData CreateSyncDataForValue(
71 const std::string& mu_id,
72 const std::string& key,
73 const Value& dict_value) {
74 const DictionaryValue* dict = NULL;
75 if (!dict_value.GetAsDictionary(&dict))
76 return SyncData();
77
78 const Value* value = NULL;
79 if (!dict->Get(kValue, &value))
80 return SyncData();
81
82 bool acknowledged = false;
83 dict->GetBoolean(kAcknowledged, &acknowledged);
84
85 return ManagedUserSharedSettingsService::CreateSyncDataForSetting(
86 mu_id, key, *value, acknowledged);
87 }
88
89 } // namespace
90
91
92 ManagedUserSharedSettingsService::ManagedUserSharedSettingsService(
93 PrefService* prefs)
94 : prefs_(prefs) {}
95
96 ManagedUserSharedSettingsService::~ManagedUserSharedSettingsService() {}
97
98 void ManagedUserSharedSettingsService::SetValueInternal(
99 const std::string& mu_id,
100 const std::string& key,
101 const Value& value,
102 bool acknowledged) {
103 ScopedManagedUserSharedSettingsUpdate update(prefs_, mu_id);
104 DictionaryValue* update_dict = update.Get();
105
106 DictionaryValue* dict = NULL;
107 bool has_key = update_dict->GetDictionaryWithoutPathExpansion(key, &dict);
108 if (!has_key) {
109 dict = new DictionaryValue;
110 update_dict->SetWithoutPathExpansion(key, dict);
111 }
112 dict->SetWithoutPathExpansion(kValue, value.DeepCopy());
113 dict->SetBooleanWithoutPathExpansion(kAcknowledged, acknowledged);
114
115 if (!sync_processor_)
116 return;
117
118 SyncData data = CreateSyncDataForSetting(mu_id, key, value, acknowledged);
119 SyncChange::SyncChangeType change_type =
120 has_key ? SyncChange::ACTION_UPDATE : SyncChange::ACTION_ADD;
121 SyncChangeList changes;
122 changes.push_back(SyncChange(FROM_HERE, change_type, data));
123 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, changes);
124 DCHECK(!error.IsSet()) << error.ToString();
125 }
126
127 const Value* ManagedUserSharedSettingsService::GetValue(
128 const std::string& mu_id,
129 const std::string& key) {
130 const DictionaryValue* data =
131 prefs_->GetDictionary(prefs::kSupervisedUserSharedSettings);
132 const DictionaryValue* dict = NULL;
133 if (!data->GetDictionaryWithoutPathExpansion(mu_id, &dict))
134 return NULL;
135
136 const DictionaryValue* settings = NULL;
137 if (!dict->GetDictionaryWithoutPathExpansion(key, &settings))
138 return NULL;
139
140 const Value* value = NULL;
141 if (!settings->GetWithoutPathExpansion(kValue, &value))
142 return NULL;
143
144 return value;
145 }
146
147 void ManagedUserSharedSettingsService::SetValue(
148 const std::string& mu_id,
149 const std::string& key,
150 const Value& value) {
151 SetValueInternal(mu_id, key, value, true);
152 }
153
154 scoped_ptr<ManagedUserSharedSettingsService::ChangeCallbackList::Subscription>
155 ManagedUserSharedSettingsService::Subscribe(
156 const ManagedUserSharedSettingsService::ChangeCallback& cb) {
157 return callbacks_.Add(cb);
158 }
159
160 // static
161 void ManagedUserSharedSettingsService::RegisterProfilePrefs(
162 user_prefs::PrefRegistrySyncable* registry) {
163 registry->RegisterDictionaryPref(
164 prefs::kSupervisedUserSharedSettings,
165 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
166 }
167
168 // static
169 SyncData ManagedUserSharedSettingsService::CreateSyncDataForSetting(
170 const std::string& mu_id,
171 const std::string& key,
172 const Value& value,
173 bool acknowledged) {
174 std::string json_value;
175 base::JSONWriter::Write(&value, &json_value);
176 ::sync_pb::EntitySpecifics specifics;
177 specifics.mutable_managed_user_shared_setting()->set_mu_id(mu_id);
178 specifics.mutable_managed_user_shared_setting()->set_key(key);
179 specifics.mutable_managed_user_shared_setting()->set_value(json_value);
180 specifics.mutable_managed_user_shared_setting()->set_acknowledged(
181 acknowledged);
182 std::string title = mu_id + ":" + key;
183 return SyncData::CreateLocalData(title, title, specifics);
184 }
185
186 void ManagedUserSharedSettingsService::Shutdown() {}
187
188 syncer::SyncMergeResult
189 ManagedUserSharedSettingsService::MergeDataAndStartSyncing(
190 syncer::ModelType type,
191 const syncer::SyncDataList& initial_sync_data,
192 scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
193 scoped_ptr<syncer::SyncErrorFactory> error_handler) {
194 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, type);
195 sync_processor_ = sync_processor.Pass();
196 error_handler_ = error_handler.Pass();
197
198 // We keep a map from MU ID to the set of keys that we have seen in the
199 // initial sync data.
200 std::map<std::string, std::set<std::string> > seen_keys;
201
202 // Iterate over all initial sync data, and update it locally. This means that
203 // the value from the server always wins over a local value.
204 for (SyncDataList::const_iterator it = initial_sync_data.begin();
205 it != initial_sync_data.end();
206 ++it) {
207 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, it->GetDataType());
208 const ::sync_pb::ManagedUserSharedSettingSpecifics&
209 managed_user_shared_setting =
210 it->GetSpecifics().managed_user_shared_setting();
211 scoped_ptr<Value> value(
212 base::JSONReader::Read(managed_user_shared_setting.value()));
213 const std::string& mu_id = managed_user_shared_setting.mu_id();
214 ScopedManagedUserSharedSettingsUpdate update(prefs_, mu_id);
215 const std::string& key = managed_user_shared_setting.key();
216 DictionaryValue* dict = FindOrCreateDictionary(update.Get(), key);
217 dict->SetWithoutPathExpansion(kValue, value.release());
218
219 // Every setting we get from the server should have the acknowledged flag
220 // set.
221 DCHECK(managed_user_shared_setting.acknowledged());
222 dict->SetBooleanWithoutPathExpansion(
223 kAcknowledged, managed_user_shared_setting.acknowledged());
224 callbacks_.Notify(mu_id, key);
225
226 seen_keys[mu_id].insert(key);
227 }
228
229 // Iterate over all settings that we have locally, which includes settings
230 // that were just synced down. We filter those out using |seen_keys|.
231 SyncChangeList change_list;
232 const DictionaryValue* all_settings =
233 prefs_->GetDictionary(prefs::kSupervisedUserSharedSettings);
234 for (DictionaryValue::Iterator it(*all_settings); !it.IsAtEnd();
235 it.Advance()) {
236 const DictionaryValue* dict = NULL;
237 bool success = it.value().GetAsDictionary(&dict);
238 DCHECK(success);
239
240 const std::set<std::string>& seen = seen_keys[it.key()];
241 for (DictionaryValue::Iterator jt(*dict); !jt.IsAtEnd(); jt.Advance()) {
242 // We only need to upload settings that we haven't seen in the initial
243 // sync data (which means they were added locally).
244 if (seen.count(jt.key()) > 0)
245 continue;
246
247 SyncData data = CreateSyncDataForValue(it.key(), jt.key(), jt.value());
248 DCHECK(data.IsValid());
249 change_list.push_back(
250 SyncChange(FROM_HERE, SyncChange::ACTION_ADD, data));
251 }
252 }
253
254 SyncMergeResult result(SUPERVISED_USER_SHARED_SETTINGS);
255 // Process all the accumulated changes.
256 if (change_list.size() > 0) {
257 result.set_error(
258 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list));
259 }
260
261 // TODO(bauerb): Statistics?
262 return result;
263 }
264
265 void ManagedUserSharedSettingsService::StopSyncing(syncer::ModelType type) {
266 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, type);
267 sync_processor_.reset();
268 error_handler_.reset();
269 }
270
271 syncer::SyncDataList ManagedUserSharedSettingsService::GetAllSyncData(
272 syncer::ModelType type) const {
273 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, type);
274 SyncDataList data;
275 const DictionaryValue* all_settings =
276 prefs_->GetDictionary(prefs::kSupervisedUserSharedSettings);
277 for (DictionaryValue::Iterator it(*all_settings); !it.IsAtEnd();
278 it.Advance()) {
279 const DictionaryValue* dict = NULL;
280 bool success = it.value().GetAsDictionary(&dict);
281 DCHECK(success);
282 for (DictionaryValue::Iterator jt(*dict); !jt.IsAtEnd(); jt.Advance()) {
283 data.push_back(CreateSyncDataForValue(it.key(), jt.key(), jt.value()));
284 }
285 }
286 return data;
287 }
288
289 syncer::SyncError ManagedUserSharedSettingsService::ProcessSyncChanges(
290 const tracked_objects::Location& from_here,
291 const syncer::SyncChangeList& change_list) {
292 for (SyncChangeList::const_iterator it = change_list.begin();
293 it != change_list.end();
294 ++it) {
295 SyncData data = it->sync_data();
296 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, data.GetDataType());
297 const ::sync_pb::ManagedUserSharedSettingSpecifics&
298 managed_user_shared_setting =
299 data.GetSpecifics().managed_user_shared_setting();
300 const std::string& key = managed_user_shared_setting.key();
301 const std::string& mu_id = managed_user_shared_setting.mu_id();
302 ScopedManagedUserSharedSettingsUpdate update(prefs_, mu_id);
303 DictionaryValue* update_dict = update.Get();
304 DictionaryValue* dict = NULL;
305 bool has_key = update_dict->GetDictionaryWithoutPathExpansion(key, &dict);
306 switch (it->change_type()) {
307 case SyncChange::ACTION_ADD:
308 case SyncChange::ACTION_UPDATE: {
309 // Every setting we get from the server should have the acknowledged
310 // flag set.
311 DCHECK(managed_user_shared_setting.acknowledged());
312
313 if (has_key) {
314 // If the managed user already exists, it should be an update action.
315 DCHECK_EQ(SyncChange::ACTION_UPDATE, it->change_type());
316 } else {
317 // Otherwise, it should be an add action.
318 DCHECK_EQ(SyncChange::ACTION_ADD, it->change_type());
319 dict = new DictionaryValue;
320 update_dict->SetWithoutPathExpansion(key, dict);
321 }
322 scoped_ptr<Value> value(
323 base::JSONReader::Read(managed_user_shared_setting.value()));
324 dict->SetWithoutPathExpansion(kValue, value.release());
325 dict->SetBooleanWithoutPathExpansion(
326 kAcknowledged, managed_user_shared_setting.acknowledged());
327 break;
328 }
329 case SyncChange::ACTION_DELETE: {
330 if (has_key)
331 update_dict->RemoveWithoutPathExpansion(key, NULL);
332 else
333 NOTREACHED() << "Trying to delete nonexistent key " << key;
334 break;
335 }
336 case SyncChange::ACTION_INVALID: {
337 NOTREACHED();
338 break;
339 }
340 }
341 callbacks_.Notify(mu_id, key);
342 }
343
344 SyncError error;
345 return error;
346 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698