pref_service_syncable.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 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.
4
5#include "chrome/browser/prefs/pref_service_syncable.h"
6
7#include "base/bind.h"
8#include "base/files/file_path.h"
9#include "base/prefs/default_pref_store.h"
10#include "base/prefs/overlay_user_pref_store.h"
11#include "base/prefs/pref_notifier_impl.h"
12#include "base/prefs/pref_registry.h"
13#include "base/prefs/pref_value_store.h"
14#include "base/strings/string_number_conversions.h"
15#include "base/value_conversions.h"
16#include "chrome/browser/prefs/pref_model_associator.h"
17#include "chrome/browser/prefs/pref_service_syncable_observer.h"
18#include "chrome/browser/profiles/profile.h"
19#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
20#include "components/user_prefs/pref_registry_syncable.h"
21
22// static
23PrefServiceSyncable* PrefServiceSyncable::FromProfile(Profile* profile) {
24  return static_cast<PrefServiceSyncable*>(profile->GetPrefs());
25}
26
27// static
28PrefServiceSyncable* PrefServiceSyncable::IncognitoFromProfile(
29    Profile* profile) {
30  return static_cast<PrefServiceSyncable*>(profile->GetOffTheRecordPrefs());
31}
32
33PrefServiceSyncable::PrefServiceSyncable(
34    PrefNotifierImpl* pref_notifier,
35    PrefValueStore* pref_value_store,
36    PersistentPrefStore* user_prefs,
37    PrefRegistrySyncable* pref_registry,
38    base::Callback<void(PersistentPrefStore::PrefReadError)>
39        read_error_callback,
40    bool async)
41  : PrefService(pref_notifier,
42                pref_value_store,
43                user_prefs,
44                pref_registry,
45                read_error_callback,
46                async) {
47  pref_sync_associator_.SetPrefService(this);
48
49  // Let PrefModelAssociator know about changes to preference values.
50  pref_value_store->set_callback(
51      base::Bind(&PrefModelAssociator::ProcessPrefChange,
52                 base::Unretained(&pref_sync_associator_)));
53
54  // Add already-registered syncable preferences to PrefModelAssociator.
55  const std::set<std::string>& syncable_preferences =
56      pref_registry->syncable_preferences();
57  for (std::set<std::string>::const_iterator it = syncable_preferences.begin();
58       it != syncable_preferences.end();
59       ++it) {
60    AddRegisteredSyncablePreference(it->c_str());
61  }
62
63  // Watch for syncable preferences registered after this point.
64  pref_registry->SetSyncableRegistrationCallback(
65      base::Bind(&PrefServiceSyncable::AddRegisteredSyncablePreference,
66                 base::Unretained(this)));
67}
68
69PrefServiceSyncable::~PrefServiceSyncable() {
70  // Remove our callback from the registry, since it may outlive us.
71  PrefRegistrySyncable* registry =
72      static_cast<PrefRegistrySyncable*>(pref_registry_.get());
73  registry->SetSyncableRegistrationCallback(
74      PrefRegistrySyncable::SyncableRegistrationCallback());
75}
76
77PrefServiceSyncable* PrefServiceSyncable::CreateIncognitoPrefService(
78    PrefStore* incognito_extension_prefs) {
79  pref_service_forked_ = true;
80  PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
81  OverlayUserPrefStore* incognito_pref_store =
82      new OverlayUserPrefStore(user_pref_store_.get());
83  PrefsTabHelper::InitIncognitoUserPrefStore(incognito_pref_store);
84
85  scoped_refptr<PrefRegistrySyncable> forked_registry =
86      static_cast<PrefRegistrySyncable*>(
87          pref_registry_.get())->ForkForIncognito();
88  PrefServiceSyncable* incognito_service = new PrefServiceSyncable(
89      pref_notifier,
90      pref_value_store_->CloneAndSpecialize(
91          NULL,  // managed
92          incognito_extension_prefs,
93          NULL,  // command_line_prefs
94          incognito_pref_store,
95          NULL,  // recommended
96          forked_registry->defaults(),
97          pref_notifier),
98      incognito_pref_store,
99      forked_registry,
100      read_error_callback_,
101      false);
102  return incognito_service;
103}
104
105bool PrefServiceSyncable::IsSyncing() {
106  return pref_sync_associator_.models_associated();
107}
108
109void PrefServiceSyncable::AddObserver(PrefServiceSyncableObserver* observer) {
110  observer_list_.AddObserver(observer);
111}
112
113void PrefServiceSyncable::RemoveObserver(
114    PrefServiceSyncableObserver* observer) {
115  observer_list_.RemoveObserver(observer);
116}
117
118syncer::SyncableService* PrefServiceSyncable::GetSyncableService() {
119  return &pref_sync_associator_;
120}
121
122void PrefServiceSyncable::UpdateCommandLinePrefStore(
123    PrefStore* cmd_line_store) {
124  // If |pref_service_forked_| is true, then this PrefService and the forked
125  // copies will be out of sync.
126  DCHECK(!pref_service_forked_);
127  PrefService::UpdateCommandLinePrefStore(cmd_line_store);
128}
129
130void PrefServiceSyncable::AddRegisteredSyncablePreference(const char* path) {
131  DCHECK(FindPreference(path));
132  pref_sync_associator_.RegisterPref(path);
133}
134
135void PrefServiceSyncable::OnIsSyncingChanged() {
136  FOR_EACH_OBSERVER(PrefServiceSyncableObserver, observer_list_,
137                    OnIsSyncingChanged());
138}
139