- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / prefs / pref_service_syncable.cc
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
23 PrefServiceSyncable* PrefServiceSyncable::FromProfile(Profile* profile) {
24   return static_cast<PrefServiceSyncable*>(profile->GetPrefs());
25 }
26
27 // static
28 PrefServiceSyncable* PrefServiceSyncable::IncognitoFromProfile(
29     Profile* profile) {
30   return static_cast<PrefServiceSyncable*>(profile->GetOffTheRecordPrefs());
31 }
32
33 PrefServiceSyncable::PrefServiceSyncable(
34     PrefNotifierImpl* pref_notifier,
35     PrefValueStore* pref_value_store,
36     PersistentPrefStore* user_prefs,
37     user_prefs::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_(syncer::PREFERENCES),
48     priority_pref_sync_associator_(syncer::PRIORITY_PREFERENCES) {
49   pref_sync_associator_.SetPrefService(this);
50   priority_pref_sync_associator_.SetPrefService(this);
51
52   // Let PrefModelAssociators know about changes to preference values.
53   pref_value_store->set_callback(
54       base::Bind(&PrefServiceSyncable::ProcessPrefChange,
55                  base::Unretained(this)));
56
57   // Add already-registered syncable preferences to PrefModelAssociator.
58   const user_prefs::PrefRegistrySyncable::PrefToStatus& syncable_preferences =
59       pref_registry->syncable_preferences();
60   for (user_prefs::PrefRegistrySyncable::PrefToStatus::const_iterator it =
61            syncable_preferences.begin();
62        it != syncable_preferences.end();
63        ++it) {
64     AddRegisteredSyncablePreference(it->first.c_str(), it->second);
65   }
66
67   // Watch for syncable preferences registered after this point.
68   pref_registry->SetSyncableRegistrationCallback(
69       base::Bind(&PrefServiceSyncable::AddRegisteredSyncablePreference,
70                  base::Unretained(this)));
71 }
72
73 PrefServiceSyncable::~PrefServiceSyncable() {
74   // Remove our callback from the registry, since it may outlive us.
75   user_prefs::PrefRegistrySyncable* registry =
76       static_cast<user_prefs::PrefRegistrySyncable*>(pref_registry_.get());
77   registry->SetSyncableRegistrationCallback(
78       user_prefs::PrefRegistrySyncable::SyncableRegistrationCallback());
79 }
80
81 PrefServiceSyncable* PrefServiceSyncable::CreateIncognitoPrefService(
82     PrefStore* incognito_extension_prefs) {
83   pref_service_forked_ = true;
84   PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
85   OverlayUserPrefStore* incognito_pref_store =
86       new OverlayUserPrefStore(user_pref_store_.get());
87   PrefsTabHelper::InitIncognitoUserPrefStore(incognito_pref_store);
88
89   scoped_refptr<user_prefs::PrefRegistrySyncable> forked_registry =
90       static_cast<user_prefs::PrefRegistrySyncable*>(
91           pref_registry_.get())->ForkForIncognito();
92   PrefServiceSyncable* incognito_service = new PrefServiceSyncable(
93       pref_notifier,
94       pref_value_store_->CloneAndSpecialize(NULL,  // managed
95                                             NULL,  // supervised_user
96                                             incognito_extension_prefs,
97                                             NULL,  // command_line_prefs
98                                             incognito_pref_store,
99                                             NULL,  // recommended
100                                             forked_registry->defaults().get(),
101                                             pref_notifier),
102       incognito_pref_store,
103       forked_registry.get(),
104       read_error_callback_,
105       false);
106   return incognito_service;
107 }
108
109 bool PrefServiceSyncable::IsSyncing() {
110   return pref_sync_associator_.models_associated();
111 }
112
113 bool PrefServiceSyncable::IsPrioritySyncing() {
114   return priority_pref_sync_associator_.models_associated();
115 }
116
117 bool PrefServiceSyncable::IsPrefSynced(const std::string& name) const {
118   return pref_sync_associator_.IsPrefSynced(name) ||
119          priority_pref_sync_associator_.IsPrefSynced(name);
120 }
121
122 void PrefServiceSyncable::AddObserver(PrefServiceSyncableObserver* observer) {
123   observer_list_.AddObserver(observer);
124 }
125
126 void PrefServiceSyncable::RemoveObserver(
127     PrefServiceSyncableObserver* observer) {
128   observer_list_.RemoveObserver(observer);
129 }
130
131 syncer::SyncableService* PrefServiceSyncable::GetSyncableService(
132     const syncer::ModelType& type) {
133   if (type == syncer::PREFERENCES) {
134     return &pref_sync_associator_;
135   } else if (type == syncer::PRIORITY_PREFERENCES) {
136     return &priority_pref_sync_associator_;
137   } else {
138     NOTREACHED() << "invalid model type: " << type;
139     return NULL;
140   }
141 }
142
143 void PrefServiceSyncable::UpdateCommandLinePrefStore(
144     PrefStore* cmd_line_store) {
145   // If |pref_service_forked_| is true, then this PrefService and the forked
146   // copies will be out of sync.
147   DCHECK(!pref_service_forked_);
148   PrefService::UpdateCommandLinePrefStore(cmd_line_store);
149 }
150
151 void PrefServiceSyncable::AddSyncedPrefObserver(
152     const std::string& name,
153     SyncedPrefObserver* observer) {
154   pref_sync_associator_.AddSyncedPrefObserver(name, observer);
155   priority_pref_sync_associator_.AddSyncedPrefObserver(name, observer);
156 }
157
158 void PrefServiceSyncable::RemoveSyncedPrefObserver(
159     const std::string& name,
160     SyncedPrefObserver* observer) {
161   pref_sync_associator_.RemoveSyncedPrefObserver(name, observer);
162   priority_pref_sync_associator_.RemoveSyncedPrefObserver(name, observer);
163 }
164
165 void PrefServiceSyncable::AddRegisteredSyncablePreference(
166     const char* path,
167     const user_prefs::PrefRegistrySyncable::PrefSyncStatus sync_status) {
168   DCHECK(FindPreference(path));
169   if (sync_status == user_prefs::PrefRegistrySyncable::SYNCABLE_PREF) {
170     pref_sync_associator_.RegisterPref(path);
171   } else if (sync_status ==
172              user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF) {
173     priority_pref_sync_associator_.RegisterPref(path);
174   } else {
175     NOTREACHED() << "invalid sync_status: " << sync_status;
176   }
177 }
178
179 void PrefServiceSyncable::OnIsSyncingChanged() {
180   FOR_EACH_OBSERVER(PrefServiceSyncableObserver, observer_list_,
181                     OnIsSyncingChanged());
182 }
183
184 void PrefServiceSyncable::ProcessPrefChange(const std::string& name) {
185   pref_sync_associator_.ProcessPrefChange(name);
186   priority_pref_sync_associator_.ProcessPrefChange(name);
187 }