Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / prefs / pref_hash_store_impl.cc
blob144351c2af0567ca39838f2babc3699042236d2b
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
3 // found in the LICENSE file.
5 #include "chrome/browser/prefs/pref_hash_store_impl.h"
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/prefs/scoped_user_pref_update.h"
12 #include "base/values.h"
13 #include "chrome/common/pref_names.h"
15 PrefHashStoreImpl::PrefHashStoreImpl(const std::string& hash_store_id,
16 const std::string& seed,
17 const std::string& device_id,
18 PrefService* local_state)
19 : hash_store_id_(hash_store_id),
20 pref_hash_calculator_(seed, device_id),
21 local_state_(local_state),
22 initial_hashes_dictionary_trusted_(IsHashDictionaryTrusted()) {
23 UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted",
24 initial_hashes_dictionary_trusted_);
27 // static
28 void PrefHashStoreImpl::RegisterPrefs(PrefRegistrySimple* registry) {
29 // Register the top level dictionary to map profile names to dictionaries of
30 // tracked preferences.
31 registry->RegisterDictionaryPref(prefs::kProfilePreferenceHashes);
34 PrefHashStore::ValueState PrefHashStoreImpl::CheckValue(
35 const std::string& path, const base::Value* initial_value) const {
36 const base::DictionaryValue* pref_hash_dicts =
37 local_state_->GetDictionary(prefs::kProfilePreferenceHashes);
38 const base::DictionaryValue* hashed_prefs = NULL;
39 pref_hash_dicts->GetDictionaryWithoutPathExpansion(hash_store_id_,
40 &hashed_prefs);
42 std::string last_hash;
43 if (!hashed_prefs || !hashed_prefs->GetString(path, &last_hash)) {
44 // In the absence of a hash for this pref, always trust a NULL value, but
45 // only trust an existing value if the initial hashes dictionary is trusted.
46 return (!initial_value || initial_hashes_dictionary_trusted_) ?
47 TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE;
50 PrefHashCalculator::ValidationResult validation_result =
51 pref_hash_calculator_.Validate(path, initial_value, last_hash);
52 switch (validation_result) {
53 case PrefHashCalculator::VALID:
54 return UNCHANGED;
55 case PrefHashCalculator::VALID_LEGACY:
56 return MIGRATED;
57 case PrefHashCalculator::INVALID:
58 return initial_value ? CHANGED : CLEARED;
60 NOTREACHED() << "Unexpected PrefHashCalculator::ValidationResult: "
61 << validation_result;
62 return UNTRUSTED_UNKNOWN_VALUE;
65 void PrefHashStoreImpl::StoreHash(
66 const std::string& path, const base::Value* new_value) {
67 DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes);
69 // Get the dictionary corresponding to the profile name, which may have a
70 // '.'
71 base::DictionaryValue* hashes_dict = NULL;
72 if (!update->GetDictionaryWithoutPathExpansion(hash_store_id_,
73 &hashes_dict)) {
74 hashes_dict = new base::DictionaryValue;
75 update->SetWithoutPathExpansion(hash_store_id_, hashes_dict);
78 hashes_dict->SetString(
79 path, pref_hash_calculator_.Calculate(path, new_value));
81 // Get the dictionary where the hash of hashes are stored.
82 base::DictionaryValue* hash_of_hashes_dict = NULL;
83 if (!update->GetDictionaryWithoutPathExpansion(internals::kHashOfHashesPref,
84 &hash_of_hashes_dict)) {
85 hash_of_hashes_dict = new base::DictionaryValue;
86 update->SetWithoutPathExpansion(internals::kHashOfHashesPref,
87 hash_of_hashes_dict);
89 // Use the |hash_store_id_| as the hashed path to avoid having the hash
90 // depend on kProfilePreferenceHashes.
91 std::string hash_of_hashes(pref_hash_calculator_.Calculate(hash_store_id_,
92 hashes_dict));
93 hash_of_hashes_dict->SetStringWithoutPathExpansion(hash_store_id_,
94 hash_of_hashes);
97 bool PrefHashStoreImpl::IsHashDictionaryTrusted() const {
98 const base::DictionaryValue* pref_hash_dicts =
99 local_state_->GetDictionary(prefs::kProfilePreferenceHashes);
100 const base::DictionaryValue* hashes_dict = NULL;
101 const base::DictionaryValue* hash_of_hashes_dict = NULL;
102 std::string hash_of_hashes;
103 // The absence of the hashes dictionary isn't trusted. Nor is the absence of
104 // the hash of hashes for this |hash_store_id_|.
105 if (!pref_hash_dicts->GetDictionaryWithoutPathExpansion(
106 hash_store_id_, &hashes_dict) ||
107 !pref_hash_dicts->GetDictionaryWithoutPathExpansion(
108 internals::kHashOfHashesPref, &hash_of_hashes_dict) ||
109 !hash_of_hashes_dict->GetStringWithoutPathExpansion(
110 hash_store_id_, &hash_of_hashes)) {
111 return false;
114 return pref_hash_calculator_.Validate(
115 hash_store_id_, hashes_dict, hash_of_hashes) == PrefHashCalculator::VALID;