OLD | NEW |
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/prefs/pref_metrics_service.h" | 5 #include "chrome/browser/prefs/pref_metrics_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 | 97 |
98 // For unit testing only. | 98 // For unit testing only. |
99 PrefMetricsService::PrefMetricsService(Profile* profile, | 99 PrefMetricsService::PrefMetricsService(Profile* profile, |
100 PrefService* local_state, | 100 PrefService* local_state, |
101 const std::string& device_id, | 101 const std::string& device_id, |
102 const char** tracked_pref_paths, | 102 const char** tracked_pref_paths, |
103 int tracked_pref_path_count) | 103 int tracked_pref_path_count) |
104 : profile_(profile), | 104 : profile_(profile), |
105 prefs_(profile->GetPrefs()), | 105 prefs_(profile->GetPrefs()), |
106 local_state_(local_state), | 106 local_state_(local_state), |
| 107 profile_name_(profile_->GetPath().AsUTF8Unsafe()), |
107 pref_hash_seed_(kSHA256DigestSize, 0), | 108 pref_hash_seed_(kSHA256DigestSize, 0), |
108 device_id_(device_id), | 109 device_id_(device_id), |
109 tracked_pref_paths_(tracked_pref_paths), | 110 tracked_pref_paths_(tracked_pref_paths), |
110 tracked_pref_path_count_(tracked_pref_path_count), | 111 tracked_pref_path_count_(tracked_pref_path_count), |
111 checked_tracked_prefs_(false), | 112 checked_tracked_prefs_(false), |
112 weak_factory_(this) { | 113 weak_factory_(this) { |
113 CheckTrackedPreferences(); | 114 CheckTrackedPreferences(); |
114 } | 115 } |
115 | 116 |
116 PrefMetricsService::~PrefMetricsService() { | 117 PrefMetricsService::~PrefMetricsService() { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 // profile. To make the system more resistant to spoofing, pref values are | 278 // profile. To make the system more resistant to spoofing, pref values are |
278 // hashed with the pref path and the device id. | 279 // hashed with the pref path and the device id. |
279 void PrefMetricsService::CheckTrackedPreferences() { | 280 void PrefMetricsService::CheckTrackedPreferences() { |
280 DCHECK(!checked_tracked_prefs_); | 281 DCHECK(!checked_tracked_prefs_); |
281 | 282 |
282 const base::DictionaryValue* pref_hash_dicts = | 283 const base::DictionaryValue* pref_hash_dicts = |
283 local_state_->GetDictionary(prefs::kProfilePreferenceHashes); | 284 local_state_->GetDictionary(prefs::kProfilePreferenceHashes); |
284 // Get the hashed prefs dictionary if it exists. If it doesn't, it will be | 285 // Get the hashed prefs dictionary if it exists. If it doesn't, it will be |
285 // created if we set preference values below. | 286 // created if we set preference values below. |
286 const base::DictionaryValue* hashed_prefs = NULL; | 287 const base::DictionaryValue* hashed_prefs = NULL; |
287 pref_hash_dicts->GetDictionary(profile_name_, &hashed_prefs); | 288 pref_hash_dicts->GetDictionaryWithoutPathExpansion(profile_name_, |
| 289 &hashed_prefs); |
288 for (int i = 0; i < tracked_pref_path_count_; ++i) { | 290 for (int i = 0; i < tracked_pref_path_count_; ++i) { |
289 // Skip prefs that haven't been registered. | 291 // Skip prefs that haven't been registered. |
290 if (!prefs_->FindPreference(tracked_pref_paths_[i])) | 292 if (!prefs_->FindPreference(tracked_pref_paths_[i])) |
291 continue; | 293 continue; |
292 | 294 |
293 bool changed = false; | 295 bool changed = false; |
294 const base::Value* value = prefs_->GetUserPrefValue(tracked_pref_paths_[i]); | 296 const base::Value* value = prefs_->GetUserPrefValue(tracked_pref_paths_[i]); |
295 if (value) { | 297 if (value) { |
296 std::string value_hash = | 298 std::string value_hash = |
297 GetHashedPrefValue(tracked_pref_paths_[i], value); | 299 GetHashedPrefValue(tracked_pref_paths_[i], value); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 const base::Value* value = prefs_->GetUserPrefValue(path); | 346 const base::Value* value = prefs_->GetUserPrefValue(path); |
345 // If the pref value is now the default, remove the hash. | 347 // If the pref value is now the default, remove the hash. |
346 const ListValue* list_value; | 348 const ListValue* list_value; |
347 const DictionaryValue* dict_value; | 349 const DictionaryValue* dict_value; |
348 if (!value || | 350 if (!value || |
349 (value->GetAsList(&list_value) && list_value->GetSize() == 0) || | 351 (value->GetAsList(&list_value) && list_value->GetSize() == 0) || |
350 (value->GetAsDictionary(&dict_value) && dict_value->size() == 0)) { | 352 (value->GetAsDictionary(&dict_value) && dict_value->size() == 0)) { |
351 RemoveTrackedPreference(path); | 353 RemoveTrackedPreference(path); |
352 } else { | 354 } else { |
353 DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes); | 355 DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes); |
354 update->SetString(GetHashedPrefPath(path), | 356 DictionaryValue* child_dictionary = NULL; |
355 GetHashedPrefValue(path, value)); | 357 |
| 358 // Get the dictionary corresponding to the profile name, |
| 359 // which may have a '.' |
| 360 if (!update->GetDictionaryWithoutPathExpansion(profile_name_, |
| 361 &child_dictionary)) { |
| 362 child_dictionary = new DictionaryValue; |
| 363 update->SetWithoutPathExpansion(profile_name_, child_dictionary); |
| 364 } |
| 365 child_dictionary->SetString(path, GetHashedPrefValue(path, value)); |
356 } | 366 } |
357 } | 367 } |
358 | 368 |
359 bool PrefMetricsService::RemoveTrackedPreference(const char* path) { | 369 bool PrefMetricsService::RemoveTrackedPreference(const char* path) { |
360 DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes); | 370 DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes); |
361 return update->Remove(GetHashedPrefPath(path), NULL); | 371 DictionaryValue* child_dictionary = NULL; |
362 } | |
363 | 372 |
364 std::string PrefMetricsService::GetHashedPrefPath(const char* path) { | 373 if (!update->GetDictionaryWithoutPathExpansion(profile_name_, |
365 std::string hash_pref_path(profile_name_); | 374 &child_dictionary)) { |
366 hash_pref_path.append("."); | 375 return false; |
367 hash_pref_path.append(path); | 376 } |
368 return hash_pref_path; | 377 return child_dictionary->Remove(path, NULL); |
369 } | 378 } |
370 | 379 |
371 std::string PrefMetricsService::GetHashedPrefValue( | 380 std::string PrefMetricsService::GetHashedPrefValue( |
372 const char* path, | 381 const char* path, |
373 const base::Value* value) { | 382 const base::Value* value) { |
374 DCHECK(value); | 383 DCHECK(value); |
375 | 384 |
376 // Dictionary values may contain empty lists and sub-dictionaries. Make a | 385 // Dictionary values may contain empty lists and sub-dictionaries. Make a |
377 // deep copy with those removed to make the hash more stable. | 386 // deep copy with those removed to make the hash more stable. |
378 const DictionaryValue* dict_value; | 387 const DictionaryValue* dict_value; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 } | 454 } |
446 | 455 |
447 bool PrefMetricsService::Factory::ServiceIsNULLWhileTesting() const { | 456 bool PrefMetricsService::Factory::ServiceIsNULLWhileTesting() const { |
448 return false; | 457 return false; |
449 } | 458 } |
450 | 459 |
451 content::BrowserContext* PrefMetricsService::Factory::GetBrowserContextToUse( | 460 content::BrowserContext* PrefMetricsService::Factory::GetBrowserContextToUse( |
452 content::BrowserContext* context) const { | 461 content::BrowserContext* context) const { |
453 return chrome::GetBrowserContextRedirectedInIncognito(context); | 462 return chrome::GetBrowserContextRedirectedInIncognito(context); |
454 } | 463 } |
OLD | NEW |