profile: Add a way for each ProfileKeyedServiceFactory to specify its user prefernces.

To allow us to compile individual features in/out of a chrome build, we need to
attack browser_prefs.cc, which is a giant static registration. This used to be
done through another big code path starting in ProfileImpl which call
browser::RegisterUserPrefs() which linked to other static methods. Now this is
done through overridding ProfileKeyedServiceFactory::RegisterUserPrefs(), and
there are no additional dependencies.

BUG=none
TEST=none


Review URL: http://codereview.chromium.org/7901027

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@104412 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/background/background_contents_service.cc b/chrome/browser/background/background_contents_service.cc
index 9191ddb4..ce9b6c67 100644
--- a/chrome/browser/background/background_contents_service.cc
+++ b/chrome/browser/background/background_contents_service.cc
@@ -566,12 +566,6 @@
   return EmptyString16();
 }
 
-// static
-void BackgroundContentsService::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterDictionaryPref(prefs::kRegisteredBackgroundContents,
-                                PrefService::UNSYNCABLE_PREF);
-}
-
 void BackgroundContentsService::AddTabContents(
     TabContents* new_contents,
     WindowOpenDisposition disposition,
diff --git a/chrome/browser/background/background_contents_service.h b/chrome/browser/background/background_contents_service.h
index 88787f6..66ce301 100644
--- a/chrome/browser/background/background_contents_service.h
+++ b/chrome/browser/background/background_contents_service.h
@@ -58,8 +58,6 @@
   // Returns all currently opened BackgroundContents (used by the task manager).
   std::vector<BackgroundContents*> GetBackgroundContents() const;
 
-  static void RegisterUserPrefs(PrefService* prefs);
-
   // BackgroundContents::Delegate implementation.
   virtual void AddTabContents(TabContents* new_contents,
                               WindowOpenDisposition disposition,
diff --git a/chrome/browser/background/background_contents_service_factory.cc b/chrome/browser/background/background_contents_service_factory.cc
index d9139dc..026f6c3 100644
--- a/chrome/browser/background/background_contents_service_factory.cc
+++ b/chrome/browser/background/background_contents_service_factory.cc
@@ -6,8 +6,10 @@
 
 #include "base/command_line.h"
 #include "chrome/browser/background/background_contents_service.h"
+#include "chrome/browser/prefs/pref_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_dependency_manager.h"
+#include "chrome/common/pref_names.h"
 
 // static
 BackgroundContentsService* BackgroundContentsServiceFactory::GetForProfile(
@@ -35,6 +37,12 @@
                                        CommandLine::ForCurrentProcess());
 }
 
+void BackgroundContentsServiceFactory::RegisterUserPrefs(
+    PrefService* user_prefs) {
+  user_prefs->RegisterDictionaryPref(prefs::kRegisteredBackgroundContents,
+                                     PrefService::UNSYNCABLE_PREF);
+}
+
 bool BackgroundContentsServiceFactory::ServiceHasOwnInstanceInIncognito() {
   return true;
 }
diff --git a/chrome/browser/background/background_contents_service_factory.h b/chrome/browser/background/background_contents_service_factory.h
index 131f617..9e3e2895 100644
--- a/chrome/browser/background/background_contents_service_factory.h
+++ b/chrome/browser/background/background_contents_service_factory.h
@@ -30,6 +30,7 @@
   // ProfileKeyedServiceFactory:
   virtual ProfileKeyedService* BuildServiceInstanceFor(
       Profile* profile) const OVERRIDE;
+  virtual void RegisterUserPrefs(PrefService* user_prefs);
   // Use a separate background contents service for incognito.
   virtual bool ServiceHasOwnInstanceInIncognito() OVERRIDE;
   virtual bool ServiceIsCreatedWithProfile() OVERRIDE;
diff --git a/chrome/browser/background/background_contents_service_unittest.cc b/chrome/browser/background/background_contents_service_unittest.cc
index b6eac81f..c62b64ef 100644
--- a/chrome/browser/background/background_contents_service_unittest.cc
+++ b/chrome/browser/background/background_contents_service_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/utf_string_conversions.h"
 #include "chrome/browser/background/background_contents_service.h"
+#include "chrome/browser/background/background_contents_service_factory.h"
 #include "chrome/browser/prefs/pref_service.h"
 #include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/tab_contents/background_contents.h"
@@ -34,10 +35,6 @@
         prefs::kRegisteredBackgroundContents);
   }
 
-  void ClearPrefs(Profile* profile) {
-    profile->GetPrefs()->ClearPref(prefs::kRegisteredBackgroundContents);
-  }
-
   // Returns the stored pref URL for the passed app id.
   std::string GetPrefURLForApp(Profile* profile, const string16& appid) {
     const DictionaryValue* pref = GetPrefs(profile);
@@ -125,8 +122,9 @@
 
 TEST_F(BackgroundContentsServiceTest, BackgroundContentsUrlAdded) {
   TestingProfile profile;
-  ClearPrefs(&profile);
   BackgroundContentsService service(&profile, command_line_.get());
+  BackgroundContentsServiceFactory::GetInstance()->RegisterUserPrefsOnProfile(
+      &profile);
   GURL orig_url;
   GURL url("http://a/");
   GURL url2("http://a/");
@@ -151,8 +149,10 @@
 
 TEST_F(BackgroundContentsServiceTest, BackgroundContentsUrlAddedAndClosed) {
   TestingProfile profile;
-  ClearPrefs(&profile);
   BackgroundContentsService service(&profile, command_line_.get());
+  BackgroundContentsServiceFactory::GetInstance()->RegisterUserPrefsOnProfile(
+      &profile);
+
   GURL url("http://a/");
   MockBackgroundContents* contents = new MockBackgroundContents(&profile);
   EXPECT_EQ(0U, GetPrefs(&profile)->size());
@@ -170,8 +170,10 @@
 // crash) then is restarted. Should not persist URL twice.
 TEST_F(BackgroundContentsServiceTest, RestartBackgroundContents) {
   TestingProfile profile;
-  ClearPrefs(&profile);
   BackgroundContentsService service(&profile, command_line_.get());
+  BackgroundContentsServiceFactory::GetInstance()->RegisterUserPrefsOnProfile(
+      &profile);
+
   GURL url("http://a/");
   {
     scoped_ptr<MockBackgroundContents> contents(new MockBackgroundContents(
@@ -201,7 +203,8 @@
 TEST_F(BackgroundContentsServiceTest, TestApplicationIDLinkage) {
   TestingProfile profile;
   BackgroundContentsService service(&profile, command_line_.get());
-  ClearPrefs(&profile);
+  BackgroundContentsServiceFactory::GetInstance()->RegisterUserPrefsOnProfile(
+      &profile);
 
   EXPECT_EQ(NULL, service.GetAppBackgroundContents(ASCIIToUTF16("appid")));
   MockBackgroundContents* contents = new MockBackgroundContents(&profile,
diff --git a/chrome/browser/plugin_prefs.cc b/chrome/browser/plugin_prefs.cc
index dd7df34..6e5a132 100644
--- a/chrome/browser/plugin_prefs.cc
+++ b/chrome/browser/plugin_prefs.cc
@@ -85,6 +85,7 @@
   // ProfileKeyedServiceFactory methods:
   virtual ProfileKeyedService* BuildServiceInstanceFor(
       Profile* profile) const OVERRIDE;
+  virtual void RegisterUserPrefs(PrefService* prefs) OVERRIDE;
   virtual bool ServiceRedirectedInIncognito() OVERRIDE { return true; }
   virtual bool ServiceIsNULLWhileTesting() OVERRIDE { return true; }
   virtual bool ServiceIsCreatedWithProfile() OVERRIDE { return true; }
@@ -531,6 +532,28 @@
   return new PluginPrefsWrapper(plugin_prefs);
 }
 
+void PluginPrefs::Factory::RegisterUserPrefs(PrefService* prefs) {
+  FilePath internal_dir;
+  PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir);
+  prefs->RegisterFilePathPref(prefs::kPluginsLastInternalDirectory,
+                              internal_dir,
+                              PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kPluginsEnabledInternalPDF,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterBooleanPref(prefs::kPluginsEnabledNaCl,
+                             false,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kPluginsPluginsList,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kPluginsDisabledPlugins,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions,
+                          PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterListPref(prefs::kPluginsEnabledPlugins,
+                          PrefService::UNSYNCABLE_PREF);
+}
+
 PluginPrefs::PluginPrefs() : plugin_state_(g_default_plugin_state.Get()),
                              prefs_(NULL),
                              plugin_list_(NULL) {
@@ -618,26 +641,3 @@
       Source<PluginPrefs>(this),
       NotificationService::NoDetails());
 }
-
-/*static*/
-void PluginPrefs::RegisterPrefs(PrefService* prefs) {
-  FilePath internal_dir;
-  PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir);
-  prefs->RegisterFilePathPref(prefs::kPluginsLastInternalDirectory,
-                              internal_dir,
-                              PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterBooleanPref(prefs::kPluginsEnabledInternalPDF,
-                             false,
-                             PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterBooleanPref(prefs::kPluginsEnabledNaCl,
-                             false,
-                             PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterListPref(prefs::kPluginsPluginsList,
-                          PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterListPref(prefs::kPluginsDisabledPlugins,
-                          PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterListPref(prefs::kPluginsDisabledPluginsExceptions,
-                          PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterListPref(prefs::kPluginsEnabledPlugins,
-                          PrefService::UNSYNCABLE_PREF);
-}
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index fa46123..d08a4fe3 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -6,7 +6,6 @@
 
 #include "chrome/browser/about_flags.h"
 #include "chrome/browser/autofill/autofill_manager.h"
-#include "chrome/browser/background/background_contents_service.h"
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
@@ -33,7 +32,6 @@
 #include "chrome/browser/notifications/notification_ui_manager.h"
 #include "chrome/browser/page_info_model.h"
 #include "chrome/browser/password_manager/password_manager.h"
-#include "chrome/browser/plugin_prefs.h"
 #include "chrome/browser/policy/cloud_policy_subsystem.h"
 #include "chrome/browser/policy/url_blacklist_manager.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
@@ -45,7 +43,6 @@
 #include "chrome/browser/remoting/firewall_traversal_observer.h"
 #include "chrome/browser/renderer_host/web_cache_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
 #include "chrome/browser/sync/signin_manager.h"
 #include "chrome/browser/tabs/pinned_tab_codec.h"
@@ -155,7 +152,6 @@
   ExtensionSettingsHandler::RegisterUserPrefs(user_prefs);
   IncognitoModePrefs::RegisterUserPrefs(user_prefs);
   NewTabUI::RegisterUserPrefs(user_prefs);
-  PluginPrefs::RegisterPrefs(user_prefs);
   PluginsUI::RegisterUserPrefs(user_prefs);
   ProfileImpl::RegisterUserPrefs(user_prefs);
   PromoResourceService::RegisterUserPrefs(user_prefs);
@@ -173,9 +169,7 @@
 #if defined(OS_CHROMEOS)
   chromeos::Preferences::RegisterUserPrefs(user_prefs);
 #endif
-  BackgroundContentsService::RegisterUserPrefs(user_prefs);
   SigninManager::RegisterUserPrefs(user_prefs);
-  TemplateURLService::RegisterUserPrefs(user_prefs);
   InstantController::RegisterUserPrefs(user_prefs);
   NetPrefObserver::RegisterPrefs(user_prefs);
   ProtocolHandlerRegistry::RegisterPrefs(user_prefs);
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index df0cdb4..27232ce 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -100,6 +100,10 @@
   return FromBrowserContext(web_ui->tab_contents()->browser_context());
 }
 
+TestingProfile* Profile::AsTestingProfile() {
+  return NULL;
+}
+
 // static
 const char* const Profile::kProfileKey = "__PROFILE__";
 
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index ee1c908..74547eb8 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -79,6 +79,7 @@
 class SpeechInputPreferences;
 class SpellCheckHost;
 class TemplateURLFetcher;
+class TestingProfile;
 class TokenService;
 class UserScriptMaster;
 class UserStyleSheetWatcher;
@@ -205,6 +206,9 @@
 
   // content::BrowserContext implementation ------------------------------------
 
+  // Typesafe upcast.
+  virtual TestingProfile* AsTestingProfile();
+
   // Returns the name associated with this profile. This name is displayed in
   // the browser frame.
   virtual std::string GetProfileName() = 0;
diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc
index d9c720e7..c5e6cd3 100644
--- a/chrome/browser/profiles/profile_dependency_manager.cc
+++ b/chrome/browser/profiles/profile_dependency_manager.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/plugin_prefs.h"
 #include "chrome/browser/prerender/prerender_manager_factory.h"
 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_keyed_service.h"
 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
@@ -104,6 +105,13 @@
   for (std::vector<ProfileKeyedServiceFactory*>::reverse_iterator rit =
            destruction_order_.rbegin(); rit != destruction_order_.rend();
        ++rit) {
+    if (!profile->IsOffTheRecord() && !profile->AsTestingProfile()) {
+      // We only register preferences on normal profiles because the incognito
+      // profile shares the pref service with the normal one and the testing
+      // profile will often just insert its own PrefService.
+      (*rit)->RegisterUserPrefsOnProfile(profile);
+    }
+
     if (is_testing_profile && (*rit)->ServiceIsNULLWhileTesting()) {
       (*rit)->SetTestingFactory(profile, NULL);
     } else if ((*rit)->ServiceIsCreatedWithProfile()) {
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.cc b/chrome/browser/profiles/profile_keyed_service_factory.cc
index 1f334038..e755ae35 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.cc
+++ b/chrome/browser/profiles/profile_keyed_service_factory.cc
@@ -13,9 +13,22 @@
 
 void ProfileKeyedServiceFactory::SetTestingFactory(Profile* profile,
                                                    FactoryFunction factory) {
+  // Destroying the profile may cause us to lose data about whether |profile|
+  // has our preferences registered on it (since the profile object itself
+  // isn't dead). See if we need to readd it once we've gone through normal
+  // destruction.
+  bool add_profile = registered_preferences_.find(profile) !=
+                     registered_preferences_.end();
+
+  // We have to go through the shutdown and destroy mechanisms because there
+  // are unit tests that create a service on a profile and then change the
+  // testing service mid-test.
   ProfileShutdown(profile);
   ProfileDestroyed(profile);
 
+  if (add_profile)
+    registered_preferences_.insert(profile);
+
   factories_[profile] = factory;
 }
 
@@ -27,6 +40,39 @@
   return GetServiceForProfile(profile, true);
 }
 
+void ProfileKeyedServiceFactory::RegisterUserPrefsOnProfile(Profile* profile) {
+  // Safe timing for pref registration is hard. Previously, we made Profile
+  // responsible for all pref registration on every service that used
+  // Profile. Now we don't and there are timing issues.
+  //
+  // With normal profiles, prefs can simply be registered at
+  // ProfileDependencyManager::CreateProfileServices time. With incognito
+  // profiles, we just never register since incognito profiles share the same
+  // pref services with their parent profiles.
+  //
+  // Testing profiles throw two wrenches into the mix. One: PrefService isn't
+  // created at profile creation time so we have to move pref registration to
+  // service creation time when using a testing factory. We can't change
+  // PrefService because Two: some tests switch out the PrefService after the
+  // TestingProfile has been created but before it's ever used. So we key our
+  // check on Profile since there's already error checking code to prevent
+  // a secondary PrefService from existing.
+  //
+  // Even worse is Three: Now that services are responsible for declaring their
+  // preferences, we have to enforce a uniquenes check here because some tests
+  // create one profile and multiple services of the same type attached to that
+  // profile (serially, not parallel). This wasn't a problem when it was the
+  // Profile that was responsible for registering the preferences, but now is
+  // because of the timing issues introduced by One.
+  DCHECK(!profile->IsOffTheRecord());
+
+  std::set<Profile*>::iterator it = registered_preferences_.find(profile);
+  if (it == registered_preferences_.end()) {
+    RegisterUserPrefs(profile->GetPrefs());
+    registered_preferences_.insert(profile);
+  }
+}
+
 ProfileKeyedServiceFactory::ProfileKeyedServiceFactory(
     ProfileDependencyManager* manager)
     : dependency_manager_(manager) {
@@ -73,6 +119,7 @@
     std::map<Profile*, FactoryFunction>::iterator jt = factories_.find(profile);
     if (jt != factories_.end()) {
       if (jt->second) {
+        RegisterUserPrefsOnProfile(profile);
         service = jt->second(profile);
       } else {
         service = NULL;
@@ -135,4 +182,5 @@
   // object that lives at the same address (see other comments about unit tests
   // in this file).
   factories_.erase(profile);
+  registered_preferences_.erase(profile);
 }
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.h b/chrome/browser/profiles/profile_keyed_service_factory.h
index 90c43087..3cac950 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.h
+++ b/chrome/browser/profiles/profile_keyed_service_factory.h
@@ -6,7 +6,9 @@
 #define CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_FACTORY_H_
 
 #include <map>
+#include <set>
 
+class PrefService;
 class Profile;
 class ProfileDependencyManager;
 class ProfileKeyedService;
@@ -38,6 +40,12 @@
   ProfileKeyedService* SetTestingFactoryAndUse(Profile* profile,
                                                FactoryFunction factory);
 
+  // Registers preferences used in this service on the pref service of
+  // |profile|. This is the public interface and is safe to be called multiple
+  // times because testing code can have multiple services of the same type
+  // attached to a single |profile|.
+  void RegisterUserPrefsOnProfile(Profile* profile);
+
  protected:
   // ProfileKeyedServiceFactories must communicate with a
   // ProfileDependencyManager. For all non-test code, write your subclass
@@ -68,6 +76,11 @@
   virtual ProfileKeyedService* BuildServiceInstanceFor(
       Profile* profile) const = 0;
 
+  // Register any user preferences on this service. This is called during
+  // CreateProfileService() since preferences are registered on a per Profile
+  // basis.
+  virtual void RegisterUserPrefs(PrefService* user_prefs) {}
+
   // By default, if we are asked for a service with an Incognito profile, we
   // pass back NULL. To redirect to the Incognito's original profile or to
   // create another instance, even for Incognito windows, override one of the
@@ -111,6 +124,9 @@
   // The mapping between a Profile and its overridden FactoryFunction.
   std::map<Profile*, FactoryFunction> factories_;
 
+  // Profiles that have this service's preferences registered on them.
+  std::set<Profile*> registered_preferences_;
+
   // Which ProfileDependencyManager we should communicate with. In real code,
   // this will always be ProfileDependencyManager::GetInstance(), but unit
   // tests will want to use their own copy.
diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc
index b44f2d32..0aa8599 100644
--- a/chrome/browser/search_engines/template_url_service.cc
+++ b/chrome/browser/search_engines/template_url_service.cc
@@ -828,40 +828,6 @@
 }
 
 // static
-void TemplateURLService::RegisterUserPrefs(PrefService* prefs) {
-  prefs->RegisterBooleanPref(prefs::kDefaultSearchProviderEnabled,
-                             true,
-                             PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderName,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderID,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderPrepopulateID,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderSuggestURL,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderSearchURL,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderInstantURL,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderKeyword,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderIconURL,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-  prefs->RegisterStringPref(prefs::kDefaultSearchProviderEncodings,
-                            std::string(),
-                            PrefService::UNSYNCABLE_PREF);
-}
-
-// static
 SyncData TemplateURLService::CreateSyncDataFromTemplateURL(
     const TemplateURL& turl) {
   sync_pb::EntitySpecifics specifics;
diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h
index 2846cb7e..9cc3918 100644
--- a/chrome/browser/search_engines/template_url_service.h
+++ b/chrome/browser/search_engines/template_url_service.h
@@ -281,9 +281,6 @@
     return search_engine_dialog_chosen_slot_;
   }
 
-  // Registers the preferences used to save a TemplateURL to prefs.
-  static void RegisterUserPrefs(PrefService* prefs);
-
   // Returns a SyncData with a sync representation of the search engine data
   // from |turl|.
   static SyncData CreateSyncDataFromTemplateURL(const TemplateURL& turl);
diff --git a/chrome/browser/search_engines/template_url_service_factory.cc b/chrome/browser/search_engines/template_url_service_factory.cc
index ddbe5a5..e3f0e0e 100644
--- a/chrome/browser/search_engines/template_url_service_factory.cc
+++ b/chrome/browser/search_engines/template_url_service_factory.cc
@@ -4,8 +4,10 @@
 
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 
-#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/prefs/pref_service.h"
 #include "chrome/browser/profiles/profile_dependency_manager.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/common/pref_names.h"
 
 TemplateURLService* TemplateURLServiceFactory::GetForProfile(Profile* profile) {
   return static_cast<TemplateURLService*>(
@@ -32,6 +34,39 @@
   return new TemplateURLService(profile);
 }
 
+void TemplateURLServiceFactory::RegisterUserPrefs(PrefService* prefs) {
+  prefs->RegisterBooleanPref(prefs::kDefaultSearchProviderEnabled,
+                             true,
+                             PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderName,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderID,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderPrepopulateID,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderSuggestURL,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderSearchURL,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderInstantURL,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderKeyword,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderIconURL,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+  prefs->RegisterStringPref(prefs::kDefaultSearchProviderEncodings,
+                            std::string(),
+                            PrefService::UNSYNCABLE_PREF);
+}
+
 bool TemplateURLServiceFactory::ServiceRedirectedInIncognito() {
   return true;
 }
diff --git a/chrome/browser/search_engines/template_url_service_factory.h b/chrome/browser/search_engines/template_url_service_factory.h
index 8d3dbe2..b70c5d0 100644
--- a/chrome/browser/search_engines/template_url_service_factory.h
+++ b/chrome/browser/search_engines/template_url_service_factory.h
@@ -9,6 +9,7 @@
 #include "base/memory/singleton.h"
 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
 
+class PrefService;
 class Profile;
 class TemplateURLService;
 
@@ -28,6 +29,7 @@
 
   // ProfileKeyedServiceFactory:
   virtual ProfileKeyedService* BuildServiceInstanceFor(Profile* profile) const;
+  virtual void RegisterUserPrefs(PrefService* user_prefs);
   virtual bool ServiceRedirectedInIncognito();
   virtual bool ServiceIsNULLWhileTesting();
   virtual void ProfileShutdown(Profile* profile);