Home | History | Annotate | Download | only in prefs
      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/pref_registry/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 }
    188