1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/prefs/tracked/segregated_pref_store.h"
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/logging.h"
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/stl_util.h"
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/values.h"
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
11effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochSegregatedPrefStore::AggregatingObserver::AggregatingObserver(
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SegregatedPrefStore* outer)
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    : outer_(outer),
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      failed_sub_initializations_(0),
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      successful_sub_initializations_(0) {}
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::AggregatingObserver::OnPrefValueChanged(
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const std::string& key) {
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // There is no need to tell clients about changes if they have not yet been
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // told about initialization.
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (failed_sub_initializations_ + successful_sub_initializations_ < 2)
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  FOR_EACH_OBSERVER(
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      PrefStore::Observer, outer_->observers_, OnPrefValueChanged(key));
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::AggregatingObserver::OnInitializationCompleted(
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool succeeded) {
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (succeeded)
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ++successful_sub_initializations_;
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  else
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ++failed_sub_initializations_;
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_LE(failed_sub_initializations_ + successful_sub_initializations_, 2);
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (failed_sub_initializations_ + successful_sub_initializations_ == 2) {
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (successful_sub_initializations_ == 2 && outer_->read_error_delegate_) {
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      PersistentPrefStore::PrefReadError read_error = outer_->GetReadError();
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (read_error != PersistentPrefStore::PREF_READ_ERROR_NONE)
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        outer_->read_error_delegate_->OnError(read_error);
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    FOR_EACH_OBSERVER(
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        PrefStore::Observer,
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        outer_->observers_,
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        OnInitializationCompleted(successful_sub_initializations_ == 2));
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
51effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochSegregatedPrefStore::SegregatedPrefStore(
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const scoped_refptr<PersistentPrefStore>& default_pref_store,
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const scoped_refptr<PersistentPrefStore>& selected_pref_store,
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::set<std::string>& selected_pref_names)
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    : default_pref_store_(default_pref_store),
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      selected_pref_store_(selected_pref_store),
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      selected_preference_names_(selected_pref_names),
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      aggregating_observer_(this) {
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  default_pref_store_->AddObserver(&aggregating_observer_);
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  selected_pref_store_->AddObserver(&aggregating_observer_);
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::AddObserver(Observer* observer) {
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  observers_.AddObserver(observer);
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::RemoveObserver(Observer* observer) {
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  observers_.RemoveObserver(observer);
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool SegregatedPrefStore::HasObservers() const {
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return observers_.might_have_observers();
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool SegregatedPrefStore::IsInitializationComplete() const {
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return default_pref_store_->IsInitializationComplete() &&
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         selected_pref_store_->IsInitializationComplete();
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool SegregatedPrefStore::GetValue(const std::string& key,
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                   const base::Value** result) const {
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return StoreForKey(key)->GetValue(key, result);
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::SetValue(const std::string& key, base::Value* value) {
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  StoreForKey(key)->SetValue(key, value);
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::RemoveValue(const std::string& key) {
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  StoreForKey(key)->RemoveValue(key);
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool SegregatedPrefStore::GetMutableValue(const std::string& key,
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                          base::Value** result) {
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return StoreForKey(key)->GetMutableValue(key, result);
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::ReportValueChanged(const std::string& key) {
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  StoreForKey(key)->ReportValueChanged(key);
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::SetValueSilently(const std::string& key,
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                           base::Value* value) {
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  StoreForKey(key)->SetValueSilently(key, value);
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool SegregatedPrefStore::ReadOnly() const {
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return selected_pref_store_->ReadOnly() ||
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         default_pref_store_->ReadOnly();
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
112effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochPersistentPrefStore::PrefReadError SegregatedPrefStore::GetReadError() const {
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PersistentPrefStore::PrefReadError read_error =
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      default_pref_store_->GetReadError();
115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (read_error == PersistentPrefStore::PREF_READ_ERROR_NONE) {
116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    read_error = selected_pref_store_->GetReadError();
117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Ignore NO_FILE from selected_pref_store_.
118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (read_error == PersistentPrefStore::PREF_READ_ERROR_NO_FILE)
119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      read_error = PersistentPrefStore::PREF_READ_ERROR_NONE;
120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return read_error;
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
124effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochPersistentPrefStore::PrefReadError SegregatedPrefStore::ReadPrefs() {
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Note: Both of these stores own PrefFilters which makes ReadPrefs
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // asynchronous. This is okay in this case as only the first call will be
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // truly asynchronous, the second call will then unblock the migration in
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TrackedPreferencesMigrator and complete synchronously.
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  default_pref_store_->ReadPrefs();
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PersistentPrefStore::PrefReadError selected_store_read_error =
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      selected_pref_store_->ReadPrefs();
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            selected_store_read_error);
134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return GetReadError();
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  read_error_delegate_.reset(error_delegate);
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  default_pref_store_->ReadPrefsAsync(NULL);
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  selected_pref_store_->ReadPrefsAsync(NULL);
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SegregatedPrefStore::CommitPendingWrite() {
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  default_pref_store_->CommitPendingWrite();
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  selected_pref_store_->CommitPendingWrite();
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
149effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochSegregatedPrefStore::~SegregatedPrefStore() {
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  default_pref_store_->RemoveObserver(&aggregating_observer_);
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  selected_pref_store_->RemoveObserver(&aggregating_observer_);
152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
154effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochPersistentPrefStore* SegregatedPrefStore::StoreForKey(const std::string& key) {
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return ContainsKey(selected_preference_names_, key) ? selected_pref_store_
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                      : default_pref_store_;
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const PersistentPrefStore* SegregatedPrefStore::StoreForKey(
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& key) const {
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return ContainsKey(selected_preference_names_, key) ? selected_pref_store_
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                      : default_pref_store_;
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
164