| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/managed_mode/managed_user_shared_settings_service.h" | 5 #include "chrome/browser/managed_mode/managed_user_shared_settings_service.h" |
| 6 | 6 |
| 7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 10 #include "base/prefs/scoped_user_pref_update.h" | 10 #include "base/prefs/scoped_user_pref_update.h" |
| 11 #include "base/values.h" | 11 #include "base/values.h" |
| 12 #include "chrome/common/pref_names.h" | 12 #include "chrome/common/pref_names.h" |
| 13 #include "components/pref_registry/pref_registry_syncable.h" | 13 #include "components/pref_registry/pref_registry_syncable.h" |
| 14 #include "sync/api/sync_change.h" | 14 #include "sync/api/sync_change.h" |
| 15 #include "sync/api/sync_data.h" | 15 #include "sync/api/sync_data.h" |
| 16 #include "sync/api/sync_error.h" | 16 #include "sync/api/sync_error.h" |
| 17 #include "sync/api/sync_error_factory.h" | 17 #include "sync/api/sync_error_factory.h" |
| 18 #include "sync/api/sync_merge_result.h" | 18 #include "sync/api/sync_merge_result.h" |
| 19 #include "sync/protocol/sync.pb.h" | 19 #include "sync/protocol/sync.pb.h" |
| 20 | 20 |
| 21 using base::DictionaryValue; | 21 using base::DictionaryValue; |
| 22 using base::Value; | 22 using base::Value; |
| 23 using syncer::MANAGED_USER_SHARED_SETTINGS; | 23 using syncer::SUPERVISED_USER_SHARED_SETTINGS; |
| 24 using syncer::ModelType; | 24 using syncer::ModelType; |
| 25 using syncer::SyncChange; | 25 using syncer::SyncChange; |
| 26 using syncer::SyncChangeList; | 26 using syncer::SyncChangeList; |
| 27 using syncer::SyncChangeProcessor; | 27 using syncer::SyncChangeProcessor; |
| 28 using syncer::SyncData; | 28 using syncer::SyncData; |
| 29 using syncer::SyncDataList; | 29 using syncer::SyncDataList; |
| 30 using syncer::SyncError; | 30 using syncer::SyncError; |
| 31 using syncer::SyncErrorFactory; | 31 using syncer::SyncErrorFactory; |
| 32 using syncer::SyncMergeResult; | 32 using syncer::SyncMergeResult; |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 const char kAcknowledged[] = "acknowledged"; | 36 const char kAcknowledged[] = "acknowledged"; |
| 37 const char kValue[] = "value"; | 37 const char kValue[] = "value"; |
| 38 | 38 |
| 39 DictionaryValue* FindOrCreateDictionary(DictionaryValue* parent, | 39 DictionaryValue* FindOrCreateDictionary(DictionaryValue* parent, |
| 40 const std::string& key) { | 40 const std::string& key) { |
| 41 DictionaryValue* dict = NULL; | 41 DictionaryValue* dict = NULL; |
| 42 if (!parent->GetDictionaryWithoutPathExpansion(key, &dict)) { | 42 if (!parent->GetDictionaryWithoutPathExpansion(key, &dict)) { |
| 43 dict = new DictionaryValue; | 43 dict = new DictionaryValue; |
| 44 parent->SetWithoutPathExpansion(key, dict); | 44 parent->SetWithoutPathExpansion(key, dict); |
| 45 } | 45 } |
| 46 return dict; | 46 return dict; |
| 47 } | 47 } |
| 48 | 48 |
| 49 class ScopedManagedUserSharedSettingsUpdate { | 49 class ScopedManagedUserSharedSettingsUpdate { |
| 50 public: | 50 public: |
| 51 ScopedManagedUserSharedSettingsUpdate(PrefService* prefs, | 51 ScopedManagedUserSharedSettingsUpdate(PrefService* prefs, |
| 52 const std::string& mu_id) | 52 const std::string& mu_id) |
| 53 : update_(prefs, prefs::kManagedUserSharedSettings), mu_id_(mu_id) { | 53 : update_(prefs, prefs::kSupervisedUserSharedSettings), mu_id_(mu_id) { |
| 54 DCHECK(!mu_id.empty()); | 54 DCHECK(!mu_id.empty()); |
| 55 | 55 |
| 56 // A supervised user can only modify their own settings. | 56 // A supervised user can only modify their own settings. |
| 57 std::string id = prefs->GetString(prefs::kManagedUserId); | 57 std::string id = prefs->GetString(prefs::kSupervisedUserId); |
| 58 DCHECK(id.empty() || id == mu_id); | 58 DCHECK(id.empty() || id == mu_id); |
| 59 } | 59 } |
| 60 | 60 |
| 61 DictionaryValue* Get() { | 61 DictionaryValue* Get() { |
| 62 return FindOrCreateDictionary(update_.Get(), mu_id_); | 62 return FindOrCreateDictionary(update_.Get(), mu_id_); |
| 63 } | 63 } |
| 64 | 64 |
| 65 private: | 65 private: |
| 66 DictionaryPrefUpdate update_; | 66 DictionaryPrefUpdate update_; |
| 67 std::string mu_id_; | 67 std::string mu_id_; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 SyncChangeList changes; | 121 SyncChangeList changes; |
| 122 changes.push_back(SyncChange(FROM_HERE, change_type, data)); | 122 changes.push_back(SyncChange(FROM_HERE, change_type, data)); |
| 123 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 123 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 124 DCHECK(!error.IsSet()) << error.ToString(); | 124 DCHECK(!error.IsSet()) << error.ToString(); |
| 125 } | 125 } |
| 126 | 126 |
| 127 const Value* ManagedUserSharedSettingsService::GetValue( | 127 const Value* ManagedUserSharedSettingsService::GetValue( |
| 128 const std::string& mu_id, | 128 const std::string& mu_id, |
| 129 const std::string& key) { | 129 const std::string& key) { |
| 130 const DictionaryValue* data = | 130 const DictionaryValue* data = |
| 131 prefs_->GetDictionary(prefs::kManagedUserSharedSettings); | 131 prefs_->GetDictionary(prefs::kSupervisedUserSharedSettings); |
| 132 const DictionaryValue* dict = NULL; | 132 const DictionaryValue* dict = NULL; |
| 133 if (!data->GetDictionaryWithoutPathExpansion(mu_id, &dict)) | 133 if (!data->GetDictionaryWithoutPathExpansion(mu_id, &dict)) |
| 134 return NULL; | 134 return NULL; |
| 135 | 135 |
| 136 const DictionaryValue* settings = NULL; | 136 const DictionaryValue* settings = NULL; |
| 137 if (!dict->GetDictionaryWithoutPathExpansion(key, &settings)) | 137 if (!dict->GetDictionaryWithoutPathExpansion(key, &settings)) |
| 138 return NULL; | 138 return NULL; |
| 139 | 139 |
| 140 const Value* value = NULL; | 140 const Value* value = NULL; |
| 141 if (!settings->GetWithoutPathExpansion(kValue, &value)) | 141 if (!settings->GetWithoutPathExpansion(kValue, &value)) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 154 scoped_ptr<ManagedUserSharedSettingsService::ChangeCallbackList::Subscription> | 154 scoped_ptr<ManagedUserSharedSettingsService::ChangeCallbackList::Subscription> |
| 155 ManagedUserSharedSettingsService::Subscribe( | 155 ManagedUserSharedSettingsService::Subscribe( |
| 156 const ManagedUserSharedSettingsService::ChangeCallback& cb) { | 156 const ManagedUserSharedSettingsService::ChangeCallback& cb) { |
| 157 return callbacks_.Add(cb); | 157 return callbacks_.Add(cb); |
| 158 } | 158 } |
| 159 | 159 |
| 160 // static | 160 // static |
| 161 void ManagedUserSharedSettingsService::RegisterProfilePrefs( | 161 void ManagedUserSharedSettingsService::RegisterProfilePrefs( |
| 162 user_prefs::PrefRegistrySyncable* registry) { | 162 user_prefs::PrefRegistrySyncable* registry) { |
| 163 registry->RegisterDictionaryPref( | 163 registry->RegisterDictionaryPref( |
| 164 prefs::kManagedUserSharedSettings, | 164 prefs::kSupervisedUserSharedSettings, |
| 165 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 165 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 166 } | 166 } |
| 167 | 167 |
| 168 // static | 168 // static |
| 169 SyncData ManagedUserSharedSettingsService::CreateSyncDataForSetting( | 169 SyncData ManagedUserSharedSettingsService::CreateSyncDataForSetting( |
| 170 const std::string& mu_id, | 170 const std::string& mu_id, |
| 171 const std::string& key, | 171 const std::string& key, |
| 172 const Value& value, | 172 const Value& value, |
| 173 bool acknowledged) { | 173 bool acknowledged) { |
| 174 std::string json_value; | 174 std::string json_value; |
| 175 base::JSONWriter::Write(&value, &json_value); | 175 base::JSONWriter::Write(&value, &json_value); |
| 176 ::sync_pb::EntitySpecifics specifics; | 176 ::sync_pb::EntitySpecifics specifics; |
| 177 specifics.mutable_managed_user_shared_setting()->set_mu_id(mu_id); | 177 specifics.mutable_managed_user_shared_setting()->set_mu_id(mu_id); |
| 178 specifics.mutable_managed_user_shared_setting()->set_key(key); | 178 specifics.mutable_managed_user_shared_setting()->set_key(key); |
| 179 specifics.mutable_managed_user_shared_setting()->set_value(json_value); | 179 specifics.mutable_managed_user_shared_setting()->set_value(json_value); |
| 180 specifics.mutable_managed_user_shared_setting()->set_acknowledged( | 180 specifics.mutable_managed_user_shared_setting()->set_acknowledged( |
| 181 acknowledged); | 181 acknowledged); |
| 182 std::string title = mu_id + ":" + key; | 182 std::string title = mu_id + ":" + key; |
| 183 return SyncData::CreateLocalData(title, title, specifics); | 183 return SyncData::CreateLocalData(title, title, specifics); |
| 184 } | 184 } |
| 185 | 185 |
| 186 void ManagedUserSharedSettingsService::Shutdown() {} | 186 void ManagedUserSharedSettingsService::Shutdown() {} |
| 187 | 187 |
| 188 syncer::SyncMergeResult | 188 syncer::SyncMergeResult |
| 189 ManagedUserSharedSettingsService::MergeDataAndStartSyncing( | 189 ManagedUserSharedSettingsService::MergeDataAndStartSyncing( |
| 190 syncer::ModelType type, | 190 syncer::ModelType type, |
| 191 const syncer::SyncDataList& initial_sync_data, | 191 const syncer::SyncDataList& initial_sync_data, |
| 192 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, | 192 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, |
| 193 scoped_ptr<syncer::SyncErrorFactory> error_handler) { | 193 scoped_ptr<syncer::SyncErrorFactory> error_handler) { |
| 194 DCHECK_EQ(MANAGED_USER_SHARED_SETTINGS, type); | 194 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, type); |
| 195 sync_processor_ = sync_processor.Pass(); | 195 sync_processor_ = sync_processor.Pass(); |
| 196 error_handler_ = error_handler.Pass(); | 196 error_handler_ = error_handler.Pass(); |
| 197 | 197 |
| 198 // We keep a map from MU ID to the set of keys that we have seen in the | 198 // We keep a map from MU ID to the set of keys that we have seen in the |
| 199 // initial sync data. | 199 // initial sync data. |
| 200 std::map<std::string, std::set<std::string> > seen_keys; | 200 std::map<std::string, std::set<std::string> > seen_keys; |
| 201 | 201 |
| 202 // Iterate over all initial sync data, and update it locally. This means that | 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. | 203 // the value from the server always wins over a local value. |
| 204 for (SyncDataList::const_iterator it = initial_sync_data.begin(); | 204 for (SyncDataList::const_iterator it = initial_sync_data.begin(); |
| 205 it != initial_sync_data.end(); | 205 it != initial_sync_data.end(); |
| 206 ++it) { | 206 ++it) { |
| 207 DCHECK_EQ(MANAGED_USER_SHARED_SETTINGS, it->GetDataType()); | 207 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, it->GetDataType()); |
| 208 const ::sync_pb::ManagedUserSharedSettingSpecifics& | 208 const ::sync_pb::ManagedUserSharedSettingSpecifics& |
| 209 managed_user_shared_setting = | 209 managed_user_shared_setting = |
| 210 it->GetSpecifics().managed_user_shared_setting(); | 210 it->GetSpecifics().managed_user_shared_setting(); |
| 211 scoped_ptr<Value> value( | 211 scoped_ptr<Value> value( |
| 212 base::JSONReader::Read(managed_user_shared_setting.value())); | 212 base::JSONReader::Read(managed_user_shared_setting.value())); |
| 213 const std::string& mu_id = managed_user_shared_setting.mu_id(); | 213 const std::string& mu_id = managed_user_shared_setting.mu_id(); |
| 214 ScopedManagedUserSharedSettingsUpdate update(prefs_, mu_id); | 214 ScopedManagedUserSharedSettingsUpdate update(prefs_, mu_id); |
| 215 const std::string& key = managed_user_shared_setting.key(); | 215 const std::string& key = managed_user_shared_setting.key(); |
| 216 DictionaryValue* dict = FindOrCreateDictionary(update.Get(), key); | 216 DictionaryValue* dict = FindOrCreateDictionary(update.Get(), key); |
| 217 dict->SetWithoutPathExpansion(kValue, value.release()); | 217 dict->SetWithoutPathExpansion(kValue, value.release()); |
| 218 | 218 |
| 219 // Every setting we get from the server should have the acknowledged flag | 219 // Every setting we get from the server should have the acknowledged flag |
| 220 // set. | 220 // set. |
| 221 DCHECK(managed_user_shared_setting.acknowledged()); | 221 DCHECK(managed_user_shared_setting.acknowledged()); |
| 222 dict->SetBooleanWithoutPathExpansion( | 222 dict->SetBooleanWithoutPathExpansion( |
| 223 kAcknowledged, managed_user_shared_setting.acknowledged()); | 223 kAcknowledged, managed_user_shared_setting.acknowledged()); |
| 224 callbacks_.Notify(mu_id, key); | 224 callbacks_.Notify(mu_id, key); |
| 225 | 225 |
| 226 seen_keys[mu_id].insert(key); | 226 seen_keys[mu_id].insert(key); |
| 227 } | 227 } |
| 228 | 228 |
| 229 // Iterate over all settings that we have locally, which includes settings | 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|. | 230 // that were just synced down. We filter those out using |seen_keys|. |
| 231 SyncChangeList change_list; | 231 SyncChangeList change_list; |
| 232 const DictionaryValue* all_settings = | 232 const DictionaryValue* all_settings = |
| 233 prefs_->GetDictionary(prefs::kManagedUserSharedSettings); | 233 prefs_->GetDictionary(prefs::kSupervisedUserSharedSettings); |
| 234 for (DictionaryValue::Iterator it(*all_settings); !it.IsAtEnd(); | 234 for (DictionaryValue::Iterator it(*all_settings); !it.IsAtEnd(); |
| 235 it.Advance()) { | 235 it.Advance()) { |
| 236 const DictionaryValue* dict = NULL; | 236 const DictionaryValue* dict = NULL; |
| 237 bool success = it.value().GetAsDictionary(&dict); | 237 bool success = it.value().GetAsDictionary(&dict); |
| 238 DCHECK(success); | 238 DCHECK(success); |
| 239 | 239 |
| 240 const std::set<std::string>& seen = seen_keys[it.key()]; | 240 const std::set<std::string>& seen = seen_keys[it.key()]; |
| 241 for (DictionaryValue::Iterator jt(*dict); !jt.IsAtEnd(); jt.Advance()) { | 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 | 242 // We only need to upload settings that we haven't seen in the initial |
| 243 // sync data (which means they were added locally). | 243 // sync data (which means they were added locally). |
| 244 if (seen.count(jt.key()) > 0) | 244 if (seen.count(jt.key()) > 0) |
| 245 continue; | 245 continue; |
| 246 | 246 |
| 247 SyncData data = CreateSyncDataForValue(it.key(), jt.key(), jt.value()); | 247 SyncData data = CreateSyncDataForValue(it.key(), jt.key(), jt.value()); |
| 248 DCHECK(data.IsValid()); | 248 DCHECK(data.IsValid()); |
| 249 change_list.push_back( | 249 change_list.push_back( |
| 250 SyncChange(FROM_HERE, SyncChange::ACTION_ADD, data)); | 250 SyncChange(FROM_HERE, SyncChange::ACTION_ADD, data)); |
| 251 } | 251 } |
| 252 } | 252 } |
| 253 | 253 |
| 254 SyncMergeResult result(MANAGED_USER_SHARED_SETTINGS); | 254 SyncMergeResult result(SUPERVISED_USER_SHARED_SETTINGS); |
| 255 // Process all the accumulated changes. | 255 // Process all the accumulated changes. |
| 256 if (change_list.size() > 0) { | 256 if (change_list.size() > 0) { |
| 257 result.set_error( | 257 result.set_error( |
| 258 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list)); | 258 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list)); |
| 259 } | 259 } |
| 260 | 260 |
| 261 // TODO(bauerb): Statistics? | 261 // TODO(bauerb): Statistics? |
| 262 return result; | 262 return result; |
| 263 } | 263 } |
| 264 | 264 |
| 265 void ManagedUserSharedSettingsService::StopSyncing(syncer::ModelType type) { | 265 void ManagedUserSharedSettingsService::StopSyncing(syncer::ModelType type) { |
| 266 DCHECK_EQ(MANAGED_USER_SHARED_SETTINGS, type); | 266 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, type); |
| 267 sync_processor_.reset(); | 267 sync_processor_.reset(); |
| 268 error_handler_.reset(); | 268 error_handler_.reset(); |
| 269 } | 269 } |
| 270 | 270 |
| 271 syncer::SyncDataList ManagedUserSharedSettingsService::GetAllSyncData( | 271 syncer::SyncDataList ManagedUserSharedSettingsService::GetAllSyncData( |
| 272 syncer::ModelType type) const { | 272 syncer::ModelType type) const { |
| 273 DCHECK_EQ(MANAGED_USER_SHARED_SETTINGS, type); | 273 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, type); |
| 274 SyncDataList data; | 274 SyncDataList data; |
| 275 const DictionaryValue* all_settings = | 275 const DictionaryValue* all_settings = |
| 276 prefs_->GetDictionary(prefs::kManagedUserSharedSettings); | 276 prefs_->GetDictionary(prefs::kSupervisedUserSharedSettings); |
| 277 for (DictionaryValue::Iterator it(*all_settings); !it.IsAtEnd(); | 277 for (DictionaryValue::Iterator it(*all_settings); !it.IsAtEnd(); |
| 278 it.Advance()) { | 278 it.Advance()) { |
| 279 const DictionaryValue* dict = NULL; | 279 const DictionaryValue* dict = NULL; |
| 280 bool success = it.value().GetAsDictionary(&dict); | 280 bool success = it.value().GetAsDictionary(&dict); |
| 281 DCHECK(success); | 281 DCHECK(success); |
| 282 for (DictionaryValue::Iterator jt(*dict); !jt.IsAtEnd(); jt.Advance()) { | 282 for (DictionaryValue::Iterator jt(*dict); !jt.IsAtEnd(); jt.Advance()) { |
| 283 data.push_back(CreateSyncDataForValue(it.key(), jt.key(), jt.value())); | 283 data.push_back(CreateSyncDataForValue(it.key(), jt.key(), jt.value())); |
| 284 } | 284 } |
| 285 } | 285 } |
| 286 return data; | 286 return data; |
| 287 } | 287 } |
| 288 | 288 |
| 289 syncer::SyncError ManagedUserSharedSettingsService::ProcessSyncChanges( | 289 syncer::SyncError ManagedUserSharedSettingsService::ProcessSyncChanges( |
| 290 const tracked_objects::Location& from_here, | 290 const tracked_objects::Location& from_here, |
| 291 const syncer::SyncChangeList& change_list) { | 291 const syncer::SyncChangeList& change_list) { |
| 292 for (SyncChangeList::const_iterator it = change_list.begin(); | 292 for (SyncChangeList::const_iterator it = change_list.begin(); |
| 293 it != change_list.end(); | 293 it != change_list.end(); |
| 294 ++it) { | 294 ++it) { |
| 295 SyncData data = it->sync_data(); | 295 SyncData data = it->sync_data(); |
| 296 DCHECK_EQ(MANAGED_USER_SHARED_SETTINGS, data.GetDataType()); | 296 DCHECK_EQ(SUPERVISED_USER_SHARED_SETTINGS, data.GetDataType()); |
| 297 const ::sync_pb::ManagedUserSharedSettingSpecifics& | 297 const ::sync_pb::ManagedUserSharedSettingSpecifics& |
| 298 managed_user_shared_setting = | 298 managed_user_shared_setting = |
| 299 data.GetSpecifics().managed_user_shared_setting(); | 299 data.GetSpecifics().managed_user_shared_setting(); |
| 300 const std::string& key = managed_user_shared_setting.key(); | 300 const std::string& key = managed_user_shared_setting.key(); |
| 301 const std::string& mu_id = managed_user_shared_setting.mu_id(); | 301 const std::string& mu_id = managed_user_shared_setting.mu_id(); |
| 302 ScopedManagedUserSharedSettingsUpdate update(prefs_, mu_id); | 302 ScopedManagedUserSharedSettingsUpdate update(prefs_, mu_id); |
| 303 DictionaryValue* update_dict = update.Get(); | 303 DictionaryValue* update_dict = update.Get(); |
| 304 DictionaryValue* dict = NULL; | 304 DictionaryValue* dict = NULL; |
| 305 bool has_key = update_dict->GetDictionaryWithoutPathExpansion(key, &dict); | 305 bool has_key = update_dict->GetDictionaryWithoutPathExpansion(key, &dict); |
| 306 switch (it->change_type()) { | 306 switch (it->change_type()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 337 NOTREACHED(); | 337 NOTREACHED(); |
| 338 break; | 338 break; |
| 339 } | 339 } |
| 340 } | 340 } |
| 341 callbacks_.Notify(mu_id, key); | 341 callbacks_.Notify(mu_id, key); |
| 342 } | 342 } |
| 343 | 343 |
| 344 SyncError error; | 344 SyncError error; |
| 345 return error; | 345 return error; |
| 346 } | 346 } |
| OLD | NEW |