15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/prefs/pref_hash_filter.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/prefs/pref_service.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/prefs/pref_store.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/time.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/values.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/prefs/pref_hash_store.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/prefs/pref_hash_store_transaction.h"
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/prefs/tracked/dictionary_hash_store_contents.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/prefs/tracked/tracked_atomic_preference.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/prefs/tracked/tracked_split_preference.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/common/pref_names.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CleanupDeprecatedTrackedPreferences(
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::DictionaryValue* pref_store_contents,
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    PrefHashStoreTransaction* hash_store_transaction) {
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Add deprecated previously tracked preferences below for them to be cleaned
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // up from both the pref files and the hash store.
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static const char* kDeprecatedTrackedPreferences[] = {
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // TODO(gab): Remove in M41+.
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "extensions.known_disabled",
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kDeprecatedTrackedPreferences); ++i) {
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const char* key = kDeprecatedTrackedPreferences[i];
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    pref_store_contents->Remove(key, NULL);
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    hash_store_transaction->ClearHash(key);
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PrefHashFilter::PrefHashFilter(
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<PrefHashStore> pref_hash_store,
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::vector<TrackedPreferenceMetadata>& tracked_preferences,
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::Closure& on_reset_on_load,
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    TrackedPreferenceValidationDelegate* delegate,
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    size_t reporting_ids_count,
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool report_super_mac_validity)
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : pref_hash_store_(pref_hash_store.Pass()),
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      on_reset_on_load_(on_reset_on_load),
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      report_super_mac_validity_(report_super_mac_validity) {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(pref_hash_store_);
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_GE(reporting_ids_count, tracked_preferences.size());
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < tracked_preferences.size(); ++i) {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const TrackedPreferenceMetadata& metadata = tracked_preferences[i];
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<TrackedPreference> tracked_preference;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (metadata.strategy) {
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case TRACKING_STRATEGY_ATOMIC:
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        tracked_preference.reset(
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            new TrackedAtomicPreference(metadata.name,
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        metadata.reporting_id,
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        reporting_ids_count,
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        metadata.enforcement_level,
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        delegate));
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case TRACKING_STRATEGY_SPLIT:
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        tracked_preference.reset(
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            new TrackedSplitPreference(metadata.name,
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       metadata.reporting_id,
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       reporting_ids_count,
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       metadata.enforcement_level,
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       delegate));
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(tracked_preference);
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool is_new = tracked_paths_.add(metadata.name,
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     tracked_preference.Pass()).second;
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(is_new);
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PrefHashFilter::~PrefHashFilter() {
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Ensure new values for all |changed_paths_| have been flushed to
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |pref_hash_store_| already.
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(changed_paths_.empty());
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PrefHashFilter::RegisterProfilePrefs(
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // See GetResetTime for why this is a StringPref and not Int64Pref.
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  registry->RegisterStringPref(
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      prefs::kPreferenceResetTime,
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Int64ToString(base::Time().ToInternalValue()),
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)base::Time PrefHashFilter::GetResetTime(PrefService* user_prefs) {
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Provide our own implementation (identical to the PrefService::GetInt64) in
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // order to ensure it remains consistent with the way we store this value
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // (which we do via a PrefStore, preventing us from reusing
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // PrefService::SetInt64).
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int64 internal_value = base::Time().ToInternalValue();
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!base::StringToInt64(
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          user_prefs->GetString(prefs::kPreferenceResetTime),
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          &internal_value)) {
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Somehow the value stored on disk is not a valid int64.
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED();
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return base::Time();
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return base::Time::FromInternalValue(internal_value);
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PrefHashFilter::ClearResetTime(PrefService* user_prefs) {
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  user_prefs->ClearPref(prefs::kPreferenceResetTime);
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void PrefHashFilter::Initialize(base::DictionaryValue* pref_store_contents) {
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<PrefHashStoreTransaction> hash_store_transaction(
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pref_hash_store_->BeginTransaction(scoped_ptr<HashStoreContents>(
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          new DictionaryHashStoreContents(pref_store_contents))));
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (TrackedPreferencesMap::const_iterator it = tracked_paths_.begin();
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != tracked_paths_.end(); ++it) {
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& initialized_path = it->first;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const TrackedPreference* initialized_preference = it->second;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Value* value = NULL;
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pref_store_contents->Get(initialized_path, &value);
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    initialized_preference->OnNewValue(value, hash_store_transaction.get());
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Marks |path| has having changed if it is part of |tracked_paths_|. A new hash
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// will be stored for it the next time FilterSerializeData() is invoked.
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PrefHashFilter::FilterUpdate(const std::string& path) {
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TrackedPreferencesMap::const_iterator it = tracked_paths_.find(path);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (it != tracked_paths_.end())
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    changed_paths_.insert(std::make_pair(path, it->second));
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Updates the stored hashes for |changed_paths_| before serializing data to
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// disk. This is required as storing the hash everytime a pref's value changes
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// is too expensive (see perf regression @ http://crbug.com/331273).
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PrefHashFilter::FilterSerializeData(
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::DictionaryValue* pref_store_contents) {
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!changed_paths_.empty()) {
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::TimeTicks checkpoint = base::TimeTicks::Now();
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<PrefHashStoreTransaction> hash_store_transaction(
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          pref_hash_store_->BeginTransaction(scoped_ptr<HashStoreContents>(
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              new DictionaryHashStoreContents(pref_store_contents))));
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for (ChangedPathsMap::const_iterator it = changed_paths_.begin();
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           it != changed_paths_.end(); ++it) {
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        const std::string& changed_path = it->first;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        const TrackedPreference* changed_preference = it->second;
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        const base::Value* value = NULL;
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        pref_store_contents->Get(changed_path, &value);
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        changed_preference->OnNewValue(value, hash_store_transaction.get());
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      changed_paths_.clear();
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TODO(gab): Remove this histogram by Feb 21 2014; after sufficient timing
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // data has been gathered from the wild to be confident this doesn't
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // significantly affect performance on the UI thread.
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_TIMES("Settings.FilterSerializeDataTime",
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        base::TimeTicks::Now() - checkpoint);
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PrefHashFilter::FinalizeFilterOnLoad(
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PostFilterOnLoadCallback& post_filter_on_load_callback,
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> pref_store_contents,
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool prefs_altered) {
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(pref_store_contents);
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeTicks checkpoint = base::TimeTicks::Now();
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool did_reset = false;
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<PrefHashStoreTransaction> hash_store_transaction(
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pref_hash_store_->BeginTransaction(scoped_ptr<HashStoreContents>(
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            new DictionaryHashStoreContents(pref_store_contents.get()))));
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CleanupDeprecatedTrackedPreferences(
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        pref_store_contents.get(), hash_store_transaction.get());
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (report_super_mac_validity_) {
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted",
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                            hash_store_transaction->IsSuperMACValid());
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (TrackedPreferencesMap::const_iterator it = tracked_paths_.begin();
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         it != tracked_paths_.end(); ++it) {
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (it->second->EnforceAndReport(pref_store_contents.get(),
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       hash_store_transaction.get())) {
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        did_reset = true;
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        prefs_altered = true;
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (hash_store_transaction->StampSuperMac())
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      prefs_altered = true;
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (did_reset) {
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    pref_store_contents->Set(prefs::kPreferenceResetTime,
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             new base::StringValue(base::Int64ToString(
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 base::Time::Now().ToInternalValue())));
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FilterUpdate(prefs::kPreferenceResetTime);
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!on_reset_on_load_.is_null())
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      on_reset_on_load_.Run();
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(gab): Remove this histogram by Feb 21 2014; after sufficient timing
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // data has been gathered from the wild to be confident this doesn't
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // significantly affect startup.
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UMA_HISTOGRAM_TIMES("Settings.FilterOnLoadTime",
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      base::TimeTicks::Now() - checkpoint);
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  post_filter_on_load_callback.Run(pref_store_contents.Pass(), prefs_altered);
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
228