ExtensionSyncService: listen for relevant changes instead of being explicitly called...
[chromium-blink-merge.git] / chrome / browser / prefs / profile_pref_store_manager.cc
blob415189d4f37b0374aaeaa17e16497b637a5f4f06
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.
5 #include "chrome/browser/prefs/profile_pref_store_manager.h"
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/files/file_util.h"
10 #include "base/json/json_file_value_serializer.h"
11 #include "base/logging.h"
12 #include "base/metrics/histogram.h"
13 #include "base/prefs/json_pref_store.h"
14 #include "base/prefs/persistent_pref_store.h"
15 #include "base/prefs/pref_registry_simple.h"
16 #include "base/sequenced_task_runner.h"
17 #include "chrome/common/chrome_constants.h"
18 #include "components/pref_registry/pref_registry_syncable.h"
19 #include "components/user_prefs/tracked/pref_hash_store_impl.h"
20 #include "components/user_prefs/tracked/pref_service_hash_store_contents.h"
21 #include "components/user_prefs/tracked/segregated_pref_store.h"
22 #include "components/user_prefs/tracked/tracked_preferences_migration.h"
24 namespace {
26 void RemoveValueSilently(const base::WeakPtr<JsonPrefStore> pref_store,
27 const std::string& key) {
28 if (pref_store) {
29 pref_store->RemoveValueSilently(
30 key, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
34 } // namespace
36 // Preference tracking and protection is not required on platforms where other
37 // apps do not have access to chrome's persistent storage.
38 const bool ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking =
39 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(OS_IOS)
40 false;
41 #else
42 true;
43 #endif
45 ProfilePrefStoreManager::ProfilePrefStoreManager(
46 const base::FilePath& profile_path,
47 const std::vector<PrefHashFilter::TrackedPreferenceMetadata>&
48 tracking_configuration,
49 size_t reporting_ids_count,
50 const std::string& seed,
51 const std::string& device_id,
52 PrefService* local_state)
53 : profile_path_(profile_path),
54 tracking_configuration_(tracking_configuration),
55 reporting_ids_count_(reporting_ids_count),
56 seed_(seed),
57 device_id_(device_id),
58 local_state_(local_state) {}
60 ProfilePrefStoreManager::~ProfilePrefStoreManager() {}
62 // static
63 void ProfilePrefStoreManager::RegisterPrefs(PrefRegistrySimple* registry) {
64 PrefServiceHashStoreContents::RegisterPrefs(registry);
67 // static
68 void ProfilePrefStoreManager::RegisterProfilePrefs(
69 user_prefs::PrefRegistrySyncable* registry) {
70 PrefHashFilter::RegisterProfilePrefs(registry);
73 // static
74 base::FilePath ProfilePrefStoreManager::GetPrefFilePathFromProfilePath(
75 const base::FilePath& profile_path) {
76 return profile_path.Append(chrome::kPreferencesFilename);
79 // static
80 void ProfilePrefStoreManager::ResetAllPrefHashStores(PrefService* local_state) {
81 PrefServiceHashStoreContents::ResetAllPrefHashStores(local_state);
84 // static
85 base::Time ProfilePrefStoreManager::GetResetTime(PrefService* pref_service) {
86 return PrefHashFilter::GetResetTime(pref_service);
89 // static
90 void ProfilePrefStoreManager::ClearResetTime(PrefService* pref_service) {
91 PrefHashFilter::ClearResetTime(pref_service);
94 PersistentPrefStore* ProfilePrefStoreManager::CreateProfilePrefStore(
95 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner,
96 const base::Closure& on_reset_on_load,
97 TrackedPreferenceValidationDelegate* validation_delegate) {
98 scoped_ptr<PrefFilter> pref_filter;
99 if (!kPlatformSupportsPreferenceTracking) {
100 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_),
101 io_task_runner.get(),
102 scoped_ptr<PrefFilter>());
105 std::vector<PrefHashFilter::TrackedPreferenceMetadata>
106 unprotected_configuration;
107 std::vector<PrefHashFilter::TrackedPreferenceMetadata>
108 protected_configuration;
109 std::set<std::string> protected_pref_names;
110 std::set<std::string> unprotected_pref_names;
111 for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::const_iterator
112 it = tracking_configuration_.begin();
113 it != tracking_configuration_.end();
114 ++it) {
115 if (it->enforcement_level > PrefHashFilter::NO_ENFORCEMENT) {
116 protected_configuration.push_back(*it);
117 protected_pref_names.insert(it->name);
118 } else {
119 unprotected_configuration.push_back(*it);
120 unprotected_pref_names.insert(it->name);
124 scoped_ptr<PrefHashFilter> unprotected_pref_hash_filter(
125 new PrefHashFilter(GetPrefHashStore(false),
126 unprotected_configuration,
127 base::Closure(),
128 validation_delegate,
129 reporting_ids_count_,
130 false));
131 scoped_ptr<PrefHashFilter> protected_pref_hash_filter(
132 new PrefHashFilter(GetPrefHashStore(true),
133 protected_configuration,
134 on_reset_on_load,
135 validation_delegate,
136 reporting_ids_count_,
137 true));
139 PrefHashFilter* raw_unprotected_pref_hash_filter =
140 unprotected_pref_hash_filter.get();
141 PrefHashFilter* raw_protected_pref_hash_filter =
142 protected_pref_hash_filter.get();
144 scoped_refptr<JsonPrefStore> unprotected_pref_store(
145 new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_),
146 io_task_runner.get(),
147 unprotected_pref_hash_filter.Pass()));
148 // TODO(gab): Remove kDeprecatedProtectedPreferencesFilename as an alternate
149 // file in M40+.
150 scoped_refptr<JsonPrefStore> protected_pref_store(new JsonPrefStore(
151 profile_path_.Append(chrome::kSecurePreferencesFilename),
152 profile_path_.Append(chrome::kProtectedPreferencesFilenameDeprecated),
153 io_task_runner.get(),
154 protected_pref_hash_filter.Pass()));
156 SetupTrackedPreferencesMigration(
157 unprotected_pref_names, protected_pref_names,
158 base::Bind(&RemoveValueSilently, unprotected_pref_store->AsWeakPtr()),
159 base::Bind(&RemoveValueSilently, protected_pref_store->AsWeakPtr()),
160 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteCallback,
161 unprotected_pref_store->AsWeakPtr()),
162 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteCallback,
163 protected_pref_store->AsWeakPtr()),
164 GetPrefHashStore(false), GetPrefHashStore(true),
165 scoped_ptr<HashStoreContents>(new PrefServiceHashStoreContents(
166 profile_path_.AsUTF8Unsafe(), local_state_)),
167 raw_unprotected_pref_hash_filter, raw_protected_pref_hash_filter);
169 return new SegregatedPrefStore(unprotected_pref_store, protected_pref_store,
170 protected_pref_names);
173 bool ProfilePrefStoreManager::InitializePrefsFromMasterPrefs(
174 const base::DictionaryValue& master_prefs) {
175 // Create the profile directory if it doesn't exist yet (very possible on
176 // first run).
177 if (!base::CreateDirectory(profile_path_))
178 return false;
180 const base::DictionaryValue* to_serialize = &master_prefs;
181 scoped_ptr<base::DictionaryValue> copy;
183 if (kPlatformSupportsPreferenceTracking) {
184 copy.reset(master_prefs.DeepCopy());
185 to_serialize = copy.get();
186 PrefHashFilter(GetPrefHashStore(false),
187 tracking_configuration_,
188 base::Closure(),
189 NULL,
190 reporting_ids_count_,
191 false).Initialize(copy.get());
194 // This will write out to a single combined file which will be immediately
195 // migrated to two files on load.
196 JSONFileValueSerializer serializer(
197 GetPrefFilePathFromProfilePath(profile_path_));
199 // Call Serialize (which does IO) on the main thread, which would _normally_
200 // be verboten. In this case however, we require this IO to synchronously
201 // complete before Chrome can start (as master preferences seed the Local
202 // State and Preferences files). This won't trip ThreadIORestrictions as they
203 // won't have kicked in yet on the main thread.
204 bool success = serializer.Serialize(*to_serialize);
206 UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success);
207 return success;
210 PersistentPrefStore*
211 ProfilePrefStoreManager::CreateDeprecatedCombinedProfilePrefStore(
212 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) {
213 scoped_ptr<PrefFilter> pref_filter;
214 if (kPlatformSupportsPreferenceTracking) {
215 scoped_ptr<PrefHashStoreImpl> pref_hash_store_impl(
216 new PrefHashStoreImpl(seed_, device_id_, true));
217 pref_hash_store_impl->set_legacy_hash_store_contents(
218 scoped_ptr<HashStoreContents>(new PrefServiceHashStoreContents(
219 profile_path_.AsUTF8Unsafe(), local_state_)));
220 pref_filter.reset(new PrefHashFilter(pref_hash_store_impl.Pass(),
221 tracking_configuration_,
222 base::Closure(),
223 NULL,
224 reporting_ids_count_,
225 false));
227 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_),
228 io_task_runner.get(),
229 pref_filter.Pass());
232 scoped_ptr<PrefHashStore> ProfilePrefStoreManager::GetPrefHashStore(
233 bool use_super_mac) {
234 DCHECK(kPlatformSupportsPreferenceTracking);
236 return scoped_ptr<PrefHashStore>(new PrefHashStoreImpl(
237 seed_,
238 device_id_,
239 use_super_mac));