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

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

Issue 23376002: Move ManagedModePolicyProvider functionality to ManagedUserSettingsService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 7 years, 3 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_settings_service.h" 5 #include "chrome/browser/managed_mode/managed_user_settings_service.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/prefs/json_pref_store.h" 10 #include "base/prefs/json_pref_store.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "base/threading/sequenced_worker_pool.h" 12 #include "base/threading/sequenced_worker_pool.h"
13 #include "chrome/browser/managed_mode/managed_mode_url_filter.h" 13 #include "chrome/browser/managed_mode/managed_mode_url_filter.h"
14 #include "chrome/browser/prefs/incognito_mode_prefs.h" 14 #include "chrome/browser/prefs/incognito_mode_prefs.h"
15 #include "chrome/common/chrome_constants.h" 15 #include "chrome/common/chrome_constants.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/user_metrics.h" 17 #include "content/public/browser/user_metrics.h"
18 #include "sync/api/sync_change.h"
19 #include "sync/api/sync_error_factory.h"
20 #include "sync/protocol/sync.pb.h"
18 21
19 using base::DictionaryValue; 22 using base::DictionaryValue;
23 using base::JSONReader;
20 using base::Value; 24 using base::Value;
21 using content::BrowserThread; 25 using content::BrowserThread;
22 using content::UserMetricsAction; 26 using content::UserMetricsAction;
27 using syncer::MANAGED_USER_SETTINGS;
28 using syncer::ModelType;
29 using syncer::SyncChange;
30 using syncer::SyncChangeList;
31 using syncer::SyncChangeProcessor;
32 using syncer::SyncData;
33 using syncer::SyncDataList;
34 using syncer::SyncError;
35 using syncer::SyncErrorFactory;
36 using syncer::SyncMergeResult;
23 37
24 const char kAtomicSettings[] = "atomic_settings"; 38 const char kAtomicSettings[] = "atomic_settings";
25 const char kManagedUserInternalItemPrefix[] = "X-"; 39 const char kManagedUserInternalItemPrefix[] = "X-";
26 const char kQueuedItems[] = "queued_items"; 40 const char kQueuedItems[] = "queued_items";
27 const char kSplitSettingKeySeparator = ':'; 41 const char kSplitSettingKeySeparator = ':';
28 const char kSplitSettings[] = "split_settings"; 42 const char kSplitSettings[] = "split_settings";
29 43
30 namespace { 44 namespace {
31 45
32 bool SettingShouldApplyToPrefs(const std::string& name) { 46 bool SettingShouldApplyToPrefs(const std::string& name) {
33 return !StartsWithASCII(name, kManagedUserInternalItemPrefix, false); 47 return !StartsWithASCII(name, kManagedUserInternalItemPrefix, false);
34 } 48 }
35 49
36 } // namespace 50 } // namespace
37 51
38 ManagedUserSettingsService::ManagedUserSettingsService() 52 ManagedUserSettingsService::ManagedUserSettingsService()
39 : active_(false), local_settings_(new DictionaryValue) {} 53 : active_(false), local_settings_(new DictionaryValue) {}
40 54
41 ManagedUserSettingsService::~ManagedUserSettingsService() {} 55 ManagedUserSettingsService::~ManagedUserSettingsService() {}
42 56
43 void ManagedUserSettingsService::Init( 57 void ManagedUserSettingsService::Init(
58 base::FilePath profile_path,
59 base::SequencedTaskRunner* sequenced_task_runner,
60 bool load_synchronously) {
61 base::FilePath path =
62 profile_path.Append(chrome::kManagedUserSettingsFilename);
63 PersistentPrefStore* store = new JsonPrefStore(path, sequenced_task_runner);
64 Init(store);
65 if (load_synchronously)
66 store_->ReadPrefs();
67 else
68 store_->ReadPrefsAsync(NULL);
69 }
70
71 void ManagedUserSettingsService::Init(
44 scoped_refptr<PersistentPrefStore> store) { 72 scoped_refptr<PersistentPrefStore> store) {
45 DCHECK(!store_); 73 DCHECK(!store_);
46 store_ = store; 74 store_ = store;
47 store_->AddObserver(this); 75 store_->AddObserver(this);
48 } 76 }
49 77
50 void ManagedUserSettingsService::Subscribe(const SettingsCallback& callback) { 78 void ManagedUserSettingsService::Subscribe(const SettingsCallback& callback) {
51 if (IsReady()) { 79 if (IsReady()) {
52 scoped_ptr<base::DictionaryValue> settings = GetSettings(); 80 scoped_ptr<base::DictionaryValue> settings = GetSettings();
53 callback.Run(settings.get()); 81 callback.Run(settings.get());
54 } 82 }
55 83
56 subscribers_.push_back(callback); 84 subscribers_.push_back(callback);
57 } 85 }
58 86
59 void ManagedUserSettingsService::Activate() { 87 void ManagedUserSettingsService::Activate() {
60 active_ = true; 88 active_ = true;
61 InformSubscribers(); 89 InformSubscribers();
62 } 90 }
63 91
64 bool ManagedUserSettingsService::IsReady() { 92 bool ManagedUserSettingsService::IsReady() {
65 return store_->IsInitializationComplete(); 93 return store_->IsInitializationComplete();
66 } 94 }
67 95
68 void ManagedUserSettingsService::Clear() { 96 void ManagedUserSettingsService::Clear() {
69 store_->RemoveValue(kAtomicSettings); 97 store_->RemoveValue(kAtomicSettings);
70 store_->RemoveValue(kSplitSettings); 98 store_->RemoveValue(kSplitSettings);
71 } 99 }
100
101 // static
102 std::string ManagedUserSettingsService::MakeSplitSettingKey(
103 const std::string& prefix,
104 const std::string& key) {
105 return prefix + kSplitSettingKeySeparator + key;
106 }
107
108 void ManagedUserSettingsService::UploadItem(const std::string& key,
109 scoped_ptr<Value> value) {
110 DCHECK(!SettingShouldApplyToPrefs(key));
111
112 std::string key_suffix = key;
113 DictionaryValue* dict = NULL;
114 if (sync_processor_) {
115 content::RecordAction(UserMetricsAction("ManagedUsers_UploadItem_Syncing"));
116 dict = GetDictionaryAndSplitKey(&key_suffix);
117 DCHECK(GetQueuedItems()->empty());
118 SyncChangeList change_list;
119 SyncData data = CreateSyncDataForSetting(key, *value);
120 SyncChange::SyncChangeType change_type =
121 dict->HasKey(key_suffix) ? SyncChange::ACTION_UPDATE
122 : SyncChange::ACTION_ADD;
123 change_list.push_back(SyncChange(FROM_HERE, change_type, data));
124 SyncError error =
125 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list);
126 DCHECK(!error.IsSet()) << error.ToString();
127 } else {
128 content::RecordAction(UserMetricsAction("ManagedUsers_UploadItem_Queued"));
Pam (message me for reviews) 2013/09/09 15:13:49 A quick comment here explaining when (whence) queu
Bernhard Bauer 2013/09/09 15:31:31 Done.
129 dict = GetQueuedItems();
130 }
131 dict->SetWithoutPathExpansion(key_suffix, value.release());
132 }
133
72 void ManagedUserSettingsService::SetLocalSettingForTesting( 134 void ManagedUserSettingsService::SetLocalSettingForTesting(
73 const std::string& key, 135 const std::string& key,
74 scoped_ptr<Value> value) { 136 scoped_ptr<Value> value) {
75 if (value) 137 if (value)
76 local_settings_->SetWithoutPathExpansion(key, value.release()); 138 local_settings_->SetWithoutPathExpansion(key, value.release());
77 else 139 else
78 local_settings_->RemoveWithoutPathExpansion(key, NULL); 140 local_settings_->RemoveWithoutPathExpansion(key, NULL);
79 141
80 InformSubscribers(); 142 InformSubscribers();
81 } 143 }
82 144
145 // static
146 SyncData ManagedUserSettingsService::CreateSyncDataForSetting(
147 const std::string& name,
148 const Value& value) {
149 std::string json_value;
150 base::JSONWriter::Write(&value, &json_value);
151 ::sync_pb::EntitySpecifics specifics;
152 specifics.mutable_managed_user_setting()->set_name(name);
153 specifics.mutable_managed_user_setting()->set_value(json_value);
154 return SyncData::CreateLocalData(name, name, specifics);
155 }
156
83 void ManagedUserSettingsService::Shutdown() { 157 void ManagedUserSettingsService::Shutdown() {
84 store_->RemoveObserver(this); 158 store_->RemoveObserver(this);
85 } 159 }
160
161 SyncMergeResult ManagedUserSettingsService::MergeDataAndStartSyncing(
Pam (message me for reviews) 2013/09/09 15:13:49 I'm assuming the bulk of this is copied from the p
Bernhard Bauer 2013/09/09 15:31:31 That is correct.
162 ModelType type,
163 const SyncDataList& initial_sync_data,
164 scoped_ptr<SyncChangeProcessor> sync_processor,
165 scoped_ptr<SyncErrorFactory> error_handler) {
166 DCHECK_EQ(MANAGED_USER_SETTINGS, type);
167 sync_processor_ = sync_processor.Pass();
168 error_handler_ = error_handler.Pass();
169
170 // Clear all atomic and split settings, then recreate them from Sync data.
171 Clear();
172 for (SyncDataList::const_iterator it = initial_sync_data.begin();
173 it != initial_sync_data.end(); ++it) {
174 DCHECK_EQ(MANAGED_USER_SETTINGS, it->GetDataType());
175 const ::sync_pb::ManagedUserSettingSpecifics& managed_user_setting =
176 it->GetSpecifics().managed_user_setting();
177 scoped_ptr<Value> value(JSONReader::Read(managed_user_setting.value()));
178 std::string name_suffix = managed_user_setting.name();
179 DictionaryValue* dict = GetDictionaryAndSplitKey(&name_suffix);
180 dict->SetWithoutPathExpansion(name_suffix, value.release());
181 }
182 store_->ReportValueChanged(kAtomicSettings);
183 store_->ReportValueChanged(kSplitSettings);
184 InformSubscribers();
185
186 // Upload all the queued up items (either with an ADD or an UPDATE action,
187 // depending on whether they already exist) and move them to split settings.
188 SyncChangeList change_list;
189 DictionaryValue* queued_items = GetQueuedItems();
190 for (DictionaryValue::Iterator it(*queued_items); !it.IsAtEnd();
191 it.Advance()) {
192 std::string key_suffix = it.key();
193 DictionaryValue* dict = GetDictionaryAndSplitKey(&key_suffix);
194 SyncData data = CreateSyncDataForSetting(it.key(), it.value());
195 SyncChange::SyncChangeType change_type =
196 dict->HasKey(key_suffix) ? SyncChange::ACTION_UPDATE
197 : SyncChange::ACTION_ADD;
198 change_list.push_back(SyncChange(FROM_HERE, change_type, data));
199 dict->SetWithoutPathExpansion(key_suffix, it.value().DeepCopy());
200 }
201 queued_items->Clear();
202
203 SyncMergeResult result(MANAGED_USER_SETTINGS);
204 // Process all the accumulated changes from the queued items.
205 if (change_list.size() > 0) {
206 store_->ReportValueChanged(kQueuedItems);
207 result.set_error(
208 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list));
209 }
210
211 // TODO(bauerb): Statistics?
212 return result;
213 }
214
215 void ManagedUserSettingsService::StopSyncing(ModelType type) {
216 DCHECK_EQ(syncer::MANAGED_USER_SETTINGS, type);
217 sync_processor_.reset();
218 error_handler_.reset();
219 }
220
221 SyncDataList ManagedUserSettingsService::GetAllSyncData(
222 ModelType type) const {
223 DCHECK_EQ(syncer::MANAGED_USER_SETTINGS, type);
224 SyncDataList data;
225 for (DictionaryValue::Iterator it(*GetAtomicSettings()); !it.IsAtEnd();
226 it.Advance()) {
227 data.push_back(CreateSyncDataForSetting(it.key(), it.value()));
228 }
229 for (DictionaryValue::Iterator it(*GetSplitSettings()); !it.IsAtEnd();
230 it.Advance()) {
231 const DictionaryValue* dict = NULL;
232 it.value().GetAsDictionary(&dict);
233 for (DictionaryValue::Iterator jt(*dict); !jt.IsAtEnd(); jt.Advance()) {
234 data.push_back(CreateSyncDataForSetting(
235 MakeSplitSettingKey(it.key(), jt.key()), jt.value()));
236 }
237 }
238 DCHECK_EQ(0u, GetQueuedItems()->size());
239 return data;
240 }
241
242 SyncError ManagedUserSettingsService::ProcessSyncChanges(
243 const tracked_objects::Location& from_here,
244 const SyncChangeList& change_list) {
245 for (SyncChangeList::const_iterator it = change_list.begin();
246 it != change_list.end(); ++it) {
247 SyncData data = it->sync_data();
248 DCHECK_EQ(MANAGED_USER_SETTINGS, data.GetDataType());
249 const ::sync_pb::ManagedUserSettingSpecifics& managed_user_setting =
250 data.GetSpecifics().managed_user_setting();
251 std::string key = managed_user_setting.name();
252 DictionaryValue* dict = GetDictionaryAndSplitKey(&key);
253 switch (it->change_type()) {
254 case SyncChange::ACTION_ADD:
255 case SyncChange::ACTION_UPDATE: {
256 scoped_ptr<Value> value(JSONReader::Read(managed_user_setting.value()));
257 if (dict->HasKey(key)) {
258 DLOG_IF(WARNING, it->change_type() == SyncChange::ACTION_ADD)
259 << "Value for key " << key << " already exists";
260 } else {
261 DLOG_IF(WARNING, it->change_type() == SyncChange::ACTION_UPDATE)
262 << "Value for key " << key << " doesn't exist yet";
263 }
264 dict->SetWithoutPathExpansion(key, value.release());
265 break;
266 }
267 case SyncChange::ACTION_DELETE: {
268 DLOG_IF(WARNING, !dict->HasKey(key)) << "Trying to delete nonexistent "
269 << "key " << key;
270 dict->RemoveWithoutPathExpansion(key, NULL);
271 break;
272 }
273 case SyncChange::ACTION_INVALID: {
274 NOTREACHED();
275 break;
276 }
277 }
278 }
279 store_->ReportValueChanged(kAtomicSettings);
280 store_->ReportValueChanged(kSplitSettings);
281 InformSubscribers();
282
283 SyncError error;
284 return error;
285 }
286
86 void ManagedUserSettingsService::OnPrefValueChanged(const std::string& key) {} 287 void ManagedUserSettingsService::OnPrefValueChanged(const std::string& key) {}
87 288
88 void ManagedUserSettingsService::OnInitializationCompleted(bool success) { 289 void ManagedUserSettingsService::OnInitializationCompleted(bool success) {
89 DCHECK(success); 290 DCHECK(success);
90 DCHECK(IsReady()); 291 DCHECK(IsReady());
91 InformSubscribers(); 292 InformSubscribers();
92 } 293 }
93 294
94 DictionaryValue* ManagedUserSettingsService::GetOrCreateDictionary( 295 DictionaryValue* ManagedUserSettingsService::GetOrCreateDictionary(
95 const std::string& key) const { 296 const std::string& key) const {
(...skipping 15 matching lines...) Expand all
111 } 312 }
112 313
113 DictionaryValue* ManagedUserSettingsService::GetSplitSettings() const { 314 DictionaryValue* ManagedUserSettingsService::GetSplitSettings() const {
114 return GetOrCreateDictionary(kSplitSettings); 315 return GetOrCreateDictionary(kSplitSettings);
115 } 316 }
116 317
117 DictionaryValue* ManagedUserSettingsService::GetQueuedItems() const { 318 DictionaryValue* ManagedUserSettingsService::GetQueuedItems() const {
118 return GetOrCreateDictionary(kQueuedItems); 319 return GetOrCreateDictionary(kQueuedItems);
119 } 320 }
120 321
322 DictionaryValue* ManagedUserSettingsService::GetDictionaryAndSplitKey(
323 std::string* key) const {
324 size_t pos = key->find_first_of(kSplitSettingKeySeparator);
325 if (pos == std::string::npos)
326 return GetAtomicSettings();
327
328 DictionaryValue* split_settings = GetSplitSettings();
329 std::string prefix = key->substr(0, pos);
330 DictionaryValue* dict = NULL;
331 if (!split_settings->GetDictionary(prefix, &dict)) {
332 dict = new DictionaryValue;
333 DCHECK(!split_settings->HasKey(prefix));
334 split_settings->Set(prefix, dict);
335 }
336 key->erase(0, pos + 1);
337 return dict;
338 }
339
121 scoped_ptr<DictionaryValue> ManagedUserSettingsService::GetSettings() { 340 scoped_ptr<DictionaryValue> ManagedUserSettingsService::GetSettings() {
122 DCHECK(IsReady()); 341 DCHECK(IsReady());
123 if (!active_) 342 if (!active_)
124 return scoped_ptr<base::DictionaryValue>(); 343 return scoped_ptr<base::DictionaryValue>();
125 344
126 scoped_ptr<DictionaryValue> settings(local_settings_->DeepCopy()); 345 scoped_ptr<DictionaryValue> settings(local_settings_->DeepCopy());
127 346
128 DictionaryValue* atomic_settings = GetAtomicSettings(); 347 DictionaryValue* atomic_settings = GetAtomicSettings();
129 for (DictionaryValue::Iterator it(*atomic_settings); !it.IsAtEnd(); 348 for (DictionaryValue::Iterator it(*atomic_settings); !it.IsAtEnd();
130 it.Advance()) { 349 it.Advance()) {
(...skipping 18 matching lines...) Expand all
149 void ManagedUserSettingsService::InformSubscribers() { 368 void ManagedUserSettingsService::InformSubscribers() {
150 if (!IsReady()) 369 if (!IsReady())
151 return; 370 return;
152 371
153 scoped_ptr<base::DictionaryValue> settings = GetSettings(); 372 scoped_ptr<base::DictionaryValue> settings = GetSettings();
154 for (std::vector<SettingsCallback>::iterator it = subscribers_.begin(); 373 for (std::vector<SettingsCallback>::iterator it = subscribers_.begin();
155 it != subscribers_.end(); ++it) { 374 it != subscribers_.end(); ++it) {
156 it->Run(settings.get()); 375 it->Run(settings.get());
157 } 376 }
158 } 377 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698