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"
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 "chrome/browser/prefs/pref_hash_store_impl.h"
17 #include "chrome/browser/prefs/tracked/pref_service_hash_store_contents.h"
18 #include "chrome/browser/prefs/tracked/segregated_pref_store.h"
19 #include "chrome/browser/prefs/tracked/tracked_preferences_migration.h"
20 #include "chrome/common/chrome_constants.h"
21 #include "chrome/common/pref_names.h"
22 #include "components/pref_registry/pref_registry_syncable.h"
24 // TODO(erikwright): Enable this on Chrome OS and Android once MACs are moved
25 // out of Local State. This will resolve a race condition on Android and a
26 // privacy issue on ChromeOS. http://crbug.com/349158
27 const bool ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking
=
28 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
34 ProfilePrefStoreManager::ProfilePrefStoreManager(
35 const base::FilePath
& profile_path
,
36 const std::vector
<PrefHashFilter::TrackedPreferenceMetadata
>&
37 tracking_configuration
,
38 size_t reporting_ids_count
,
39 const std::string
& seed
,
40 const std::string
& device_id
,
41 PrefService
* local_state
)
42 : profile_path_(profile_path
),
43 tracking_configuration_(tracking_configuration
),
44 reporting_ids_count_(reporting_ids_count
),
46 device_id_(device_id
),
47 local_state_(local_state
) {}
49 ProfilePrefStoreManager::~ProfilePrefStoreManager() {}
52 void ProfilePrefStoreManager::RegisterPrefs(PrefRegistrySimple
* registry
) {
53 PrefServiceHashStoreContents::RegisterPrefs(registry
);
57 void ProfilePrefStoreManager::RegisterProfilePrefs(
58 user_prefs::PrefRegistrySyncable
* registry
) {
59 PrefHashFilter::RegisterProfilePrefs(registry
);
63 base::FilePath
ProfilePrefStoreManager::GetPrefFilePathFromProfilePath(
64 const base::FilePath
& profile_path
) {
65 return profile_path
.Append(chrome::kPreferencesFilename
);
69 void ProfilePrefStoreManager::ResetAllPrefHashStores(PrefService
* local_state
) {
70 PrefServiceHashStoreContents::ResetAllPrefHashStores(local_state
);
74 base::Time
ProfilePrefStoreManager::GetResetTime(PrefService
* pref_service
) {
75 return PrefHashFilter::GetResetTime(pref_service
);
79 void ProfilePrefStoreManager::ClearResetTime(PrefService
* pref_service
) {
80 PrefHashFilter::ClearResetTime(pref_service
);
83 PersistentPrefStore
* ProfilePrefStoreManager::CreateProfilePrefStore(
84 const scoped_refptr
<base::SequencedTaskRunner
>& io_task_runner
,
85 const base::Closure
& on_reset_on_load
,
86 TrackedPreferenceValidationDelegate
* validation_delegate
) {
87 scoped_ptr
<PrefFilter
> pref_filter
;
88 if (!kPlatformSupportsPreferenceTracking
) {
89 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_
),
91 scoped_ptr
<PrefFilter
>());
94 std::vector
<PrefHashFilter::TrackedPreferenceMetadata
>
95 unprotected_configuration
;
96 std::vector
<PrefHashFilter::TrackedPreferenceMetadata
>
97 protected_configuration
;
98 std::set
<std::string
> protected_pref_names
;
99 std::set
<std::string
> unprotected_pref_names
;
100 for (std::vector
<PrefHashFilter::TrackedPreferenceMetadata
>::const_iterator
101 it
= tracking_configuration_
.begin();
102 it
!= tracking_configuration_
.end();
104 if (it
->enforcement_level
> PrefHashFilter::NO_ENFORCEMENT
) {
105 protected_configuration
.push_back(*it
);
106 protected_pref_names
.insert(it
->name
);
108 unprotected_configuration
.push_back(*it
);
109 unprotected_pref_names
.insert(it
->name
);
113 scoped_ptr
<PrefHashFilter
> unprotected_pref_hash_filter(
114 new PrefHashFilter(GetPrefHashStore(false),
115 unprotected_configuration
,
118 reporting_ids_count_
,
120 scoped_ptr
<PrefHashFilter
> protected_pref_hash_filter(
121 new PrefHashFilter(GetPrefHashStore(true),
122 protected_configuration
,
125 reporting_ids_count_
,
128 PrefHashFilter
* raw_unprotected_pref_hash_filter
=
129 unprotected_pref_hash_filter
.get();
130 PrefHashFilter
* raw_protected_pref_hash_filter
=
131 protected_pref_hash_filter
.get();
133 scoped_refptr
<JsonPrefStore
> unprotected_pref_store(
134 new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_
),
135 io_task_runner
.get(),
136 unprotected_pref_hash_filter
.PassAs
<PrefFilter
>()));
137 // TODO(gab): Remove kDeprecatedProtectedPreferencesFilename as an alternate
139 scoped_refptr
<JsonPrefStore
> protected_pref_store(new JsonPrefStore(
140 profile_path_
.Append(chrome::kSecurePreferencesFilename
),
141 profile_path_
.Append(chrome::kProtectedPreferencesFilenameDeprecated
),
142 io_task_runner
.get(),
143 protected_pref_hash_filter
.PassAs
<PrefFilter
>()));
145 SetupTrackedPreferencesMigration(
146 unprotected_pref_names
,
147 protected_pref_names
,
148 base::Bind(&JsonPrefStore::RemoveValueSilently
,
149 unprotected_pref_store
->AsWeakPtr()),
150 base::Bind(&JsonPrefStore::RemoveValueSilently
,
151 protected_pref_store
->AsWeakPtr()),
152 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteCallback
,
153 unprotected_pref_store
->AsWeakPtr()),
154 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteCallback
,
155 protected_pref_store
->AsWeakPtr()),
156 GetPrefHashStore(false),
157 GetPrefHashStore(true),
158 scoped_ptr
<HashStoreContents
>(new PrefServiceHashStoreContents(
159 profile_path_
.AsUTF8Unsafe(), local_state_
)),
160 raw_unprotected_pref_hash_filter
,
161 raw_protected_pref_hash_filter
);
163 return new SegregatedPrefStore(unprotected_pref_store
, protected_pref_store
,
164 protected_pref_names
);
167 bool ProfilePrefStoreManager::InitializePrefsFromMasterPrefs(
168 const base::DictionaryValue
& master_prefs
) {
169 // Create the profile directory if it doesn't exist yet (very possible on
171 if (!base::CreateDirectory(profile_path_
))
174 const base::DictionaryValue
* to_serialize
= &master_prefs
;
175 scoped_ptr
<base::DictionaryValue
> copy
;
177 if (kPlatformSupportsPreferenceTracking
) {
178 copy
.reset(master_prefs
.DeepCopy());
179 to_serialize
= copy
.get();
180 PrefHashFilter(GetPrefHashStore(false),
181 tracking_configuration_
,
184 reporting_ids_count_
,
185 false).Initialize(copy
.get());
188 // This will write out to a single combined file which will be immediately
189 // migrated to two files on load.
190 JSONFileValueSerializer
serializer(
191 GetPrefFilePathFromProfilePath(profile_path_
));
193 // Call Serialize (which does IO) on the main thread, which would _normally_
194 // be verboten. In this case however, we require this IO to synchronously
195 // complete before Chrome can start (as master preferences seed the Local
196 // State and Preferences files). This won't trip ThreadIORestrictions as they
197 // won't have kicked in yet on the main thread.
198 bool success
= serializer
.Serialize(*to_serialize
);
200 UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success
);
205 ProfilePrefStoreManager::CreateDeprecatedCombinedProfilePrefStore(
206 const scoped_refptr
<base::SequencedTaskRunner
>& io_task_runner
) {
207 scoped_ptr
<PrefFilter
> pref_filter
;
208 if (kPlatformSupportsPreferenceTracking
) {
209 scoped_ptr
<PrefHashStoreImpl
> pref_hash_store_impl(
210 new PrefHashStoreImpl(seed_
, device_id_
, true));
211 pref_hash_store_impl
->set_legacy_hash_store_contents(
212 scoped_ptr
<HashStoreContents
>(new PrefServiceHashStoreContents(
213 profile_path_
.AsUTF8Unsafe(), local_state_
)));
215 new PrefHashFilter(pref_hash_store_impl
.PassAs
<PrefHashStore
>(),
216 tracking_configuration_
,
219 reporting_ids_count_
,
222 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_
),
223 io_task_runner
.get(),
227 scoped_ptr
<PrefHashStore
> ProfilePrefStoreManager::GetPrefHashStore(
228 bool use_super_mac
) {
229 DCHECK(kPlatformSupportsPreferenceTracking
);
231 return scoped_ptr
<PrefHashStore
>(new PrefHashStoreImpl(