Revert of Sync starting language and input method preferences (patchset #14 id:360001 of https://codereview.chromium.org/312023002/)

Reason for revert:
Causes NULL pointer dereference.

#0  chromeos::input_method::(anonymous namespace)::CheckAndResolveLocales (languages=0x0)
    at ../../chrome/browser/chromeos/input_method/input_method_syncer.cc:58
#1  0x00007f9466f9ddd2 in Run (this=<optimized out>) at ../../base/callback.h:396
#2  base::(anonymous namespace)::PostTaskAndReplyRelay::Run (this=0x647e3eb28c0)
    at ../../base/threading/post_task_and_reply_impl.cc:42
#3  0x00007f9466fa1257 in Run (this=0x7f9454cb1b10) at ../../base/callback.h:396
#4  base::SequencedWorkerPool::Inner::ThreadLoop (this=0x647e2117000, this_worker=this_worker@entry=0x647e34f5190)
    at ../../base/threading/sequenced_worker_pool.cc:760
#5  0x00007f9466fa199d in base::SequencedWorkerPool::Worker::Run (this=0x647e34f5190)
    at ../../base/threading/sequenced_worker_pool.cc:507
#6  0x00007f9466fa1d51 in base::SimpleThread::ThreadMain (this=0x647e34f5190) at ../../base/threading/simple_thread.cc:60
#7  0x00007f9466f9db30 in base::(anonymous namespace)::ThreadFunc (params=<optimized out>)
    at ../../base/threading/platform_thread_posix.cc:80
#8  0x00007f94654ae321 in start_thread (arg=0x7f9454cb2700) at pthread_create.c:309
#9  0x00007f94649527ed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Original issue's description:
> Sync starting language and input method preferences
>
> Users who use additional Chromebooks or who recreate their accounts have
> to manually set up their preferred languages, input methods and IMEs on
> each device, because only the locale (display language) syncs.
>
> We don't forcibly keep these settings in sync because different machines
> may use different built-in or peripheral keyboards. But we can make the
> set-up process smoother if we know what settings the user chose most
> recently.
>
> This CL creates syncable of the language and input
> methods preferences, so the server always has the latest changes.
>
> When, and only when, a user logs in and syncs for the first time on a
> device, we take the local variants the user has already chosen for this
> machine, and we add to them the global variants that come down from
> sync. This only happens at most once. It should only be additive, not
> remove any chosen settings.
>
> Some caveats:
>  * If the user makes a change to one language/input setting, sync all
>    three interdependent settings so the sync server's settings are
>    always internally consistent.
>
> BUG=298345
> R=nkostylev@chromium.org, yukishiino@chromium.org, hajimehoshi@chromium.org
> CC=nona@chromium.org
>
> Committed: https://crrev.com/cceac6fae685fd86d6f347d6712886549e372231
> Cr-Commit-Position: refs/heads/master@{#306164}

TBR=hajimehoshi@chromium.org,alemate@chromium.org,shuchen@chromium.org,yukishiino@chromium.org,dzhioev@chromium.org,dpolukhin@chromium.org,michaelpg@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=298345

Review URL: https://codereview.chromium.org/756363003

Cr-Commit-Position: refs/heads/master@{#306233}
diff --git a/chrome/browser/chromeos/input_method/input_method_syncer.cc b/chrome/browser/chromeos/input_method/input_method_syncer.cc
deleted file mode 100644
index 77166ca..0000000
--- a/chrome/browser/chromeos/input_method/input_method_syncer.cc
+++ /dev/null
@@ -1,328 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/input_method/input_method_syncer.h"
-
-#include <algorithm>
-#include <set>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/task_runner.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/prefs/pref_service_syncable.h"
-#include "chrome/common/pref_names.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/browser/browser_thread.h"
-#include "ui/base/ime/chromeos/component_extension_ime_manager.h"
-#include "ui/base/ime/chromeos/extension_ime_util.h"
-#include "ui/base/l10n/l10n_util.h"
-
-namespace chromeos {
-namespace input_method {
-namespace {
-
-// Checks input method IDs, converting engine IDs to input method IDs and
-// removing unsupported IDs from |values|.
-void CheckAndResolveInputMethodIDs(
-    const input_method::InputMethodDescriptors& supported_descriptors,
-    std::vector<std::string>* values) {
-  // Extract the supported input method IDs into a set.
-  std::set<std::string> supported_input_method_ids;
-  for (const auto& descriptor : supported_descriptors)
-    supported_input_method_ids.insert(descriptor.id());
-
-  // Convert engine IDs to input method extension IDs.
-  std::transform(values->begin(), values->end(), values->begin(),
-                 extension_ime_util::GetInputMethodIDByEngineID);
-
-  // Remove values that aren't found in the set of supported input method IDs.
-  std::vector<std::string>::iterator it = values->begin();
-  while (it != values->end()) {
-    if (it->size() && supported_input_method_ids.find(*it) !=
-                      supported_input_method_ids.end()) {
-      ++it;
-    } else {
-      it = values->erase(it);
-    }
-  }
-}
-
-// Checks whether each language is supported, replacing locales with variants
-// if they are available. Must be called on a thread that allows IO.
-void CheckAndResolveLocales(std::string* languages) {
-  DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-  if (languages->empty())
-    return;
-  std::vector<std::string> values;
-  base::SplitString(*languages, ',', &values);
-
-  const std::string app_locale = g_browser_process->GetApplicationLocale();
-
-  std::vector<std::string> accept_language_codes;
-  l10n_util::GetAcceptLanguagesForLocale(app_locale, &accept_language_codes);
-  std::sort(accept_language_codes.begin(), accept_language_codes.end());
-
-  // Remove unsupported language values.
-  std::vector<std::string>::iterator value_iter = values.begin();
-  while (value_iter != values.end()) {
-    if (binary_search(accept_language_codes.begin(),
-                      accept_language_codes.end(),
-                      *value_iter)) {
-      ++value_iter;
-      continue;
-    }
-
-    // If a language code resolves to a supported backup locale, replace it
-    // with the resolved locale.
-    std::string resolved_locale;
-    if (l10n_util::CheckAndResolveLocale(*value_iter, &resolved_locale)) {
-      if (binary_search(accept_language_codes.begin(),
-                        accept_language_codes.end(),
-                        resolved_locale)) {
-        *value_iter = resolved_locale;
-        ++value_iter;
-        continue;
-      }
-    }
-    value_iter = values.erase(value_iter);
-  }
-
-  *languages = JoinString(values, ',');
-}
-
-// Appends tokens from |src| that are not in |dest| to |dest|.
-void MergeLists(std::vector<std::string>* dest,
-                const std::vector<std::string>& src) {
-  // Keep track of already-added tokens.
-  std::set<std::string> unique_tokens(dest->begin(), dest->end());
-
-  for (const std::string& token : src) {
-    // Skip token if it's already in |dest|.
-    if (binary_search(unique_tokens.begin(), unique_tokens.end(), token))
-      continue;
-    dest->push_back(token);
-    unique_tokens.insert(token);
-  }
-}
-
-}  // anonymous namespace
-
-InputMethodSyncer::InputMethodSyncer(
-    PrefServiceSyncable* prefs,
-    scoped_refptr<input_method::InputMethodManager::State> ime_state)
-    : prefs_(prefs),
-      ime_state_(ime_state),
-      merging_(false),
-      weak_factory_(this) {
-}
-
-InputMethodSyncer::~InputMethodSyncer() {
-  prefs_->RemoveObserver(this);
-}
-
-// static
-void InputMethodSyncer::RegisterProfilePrefs(
-    user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterStringPref(
-      prefs::kLanguagePreferredLanguagesSyncable,
-      "",
-      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
-  registry->RegisterStringPref(
-      prefs::kLanguagePreloadEnginesSyncable,
-      "",
-      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
-  registry->RegisterStringPref(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      "",
-      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
-  registry->RegisterBooleanPref(
-      prefs::kLanguageShouldMergeInputMethods,
-      false,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-}
-
-void InputMethodSyncer::Initialize() {
-  // This causes OnIsSyncingChanged to be called when the value of
-  // PrefService::IsSyncing() changes.
-  prefs_->AddObserver(this);
-
-  preferred_languages_syncable_.Init(prefs::kLanguagePreferredLanguagesSyncable,
-                                     prefs_);
-  preload_engines_syncable_.Init(prefs::kLanguagePreloadEnginesSyncable,
-                                 prefs_);
-  enabled_extension_imes_syncable_.Init(
-      prefs::kLanguageEnabledExtensionImesSyncable, prefs_);
-
-  BooleanPrefMember::NamedChangeCallback callback =
-      base::Bind(&InputMethodSyncer::OnPreferenceChanged,
-                 base::Unretained(this));
-  preferred_languages_.Init(prefs::kLanguagePreferredLanguages,
-                            prefs_, callback);
-  preload_engines_.Init(prefs::kLanguagePreloadEngines,
-                        prefs_, callback);
-  enabled_extension_imes_.Init(
-      prefs::kLanguageEnabledExtensionImes, prefs_, callback);
-
-  // If we have already synced but haven't merged input methods yet, do so now.
-  if (prefs_->GetBoolean(prefs::kLanguageShouldMergeInputMethods) &&
-      !(preferred_languages_syncable_.GetValue().empty() &&
-        preload_engines_syncable_.GetValue().empty() &&
-        enabled_extension_imes_syncable_.GetValue().empty())) {
-    MergeSyncedPrefs();
-  }
-}
-
-void InputMethodSyncer::MergeSyncedPrefs() {
-  // This should only be done after the first ever sync.
-  DCHECK(prefs_->GetBoolean(prefs::kLanguageShouldMergeInputMethods));
-  prefs_->SetBoolean(prefs::kLanguageShouldMergeInputMethods, false);
-  merging_ = true;
-
-  std::string preferred_languages_syncable =
-      preferred_languages_syncable_.GetValue();
-  std::string preload_engines_syncable =
-      preload_engines_syncable_.GetValue();
-  std::string enabled_extension_imes_syncable =
-      enabled_extension_imes_syncable_.GetValue();
-
-  std::vector<std::string> synced_tokens;
-  std::vector<std::string> new_tokens;
-
-  // First, set the syncable prefs to the union of the local and synced prefs.
-  base::SplitString(
-      preferred_languages_syncable_.GetValue(), ',', &synced_tokens);
-  base::SplitString(preferred_languages_.GetValue(), ',', &new_tokens);
-
-  // Append the synced values to the current values.
-  MergeLists(&new_tokens, synced_tokens);
-  preferred_languages_syncable_.SetValue(JoinString(new_tokens, ','));
-
-  base::SplitString(
-      enabled_extension_imes_syncable_.GetValue(), ',', &synced_tokens);
-  base::SplitString(enabled_extension_imes_.GetValue(), ',', &new_tokens);
-
-  MergeLists(&new_tokens, synced_tokens);
-  enabled_extension_imes_syncable_.SetValue(JoinString(new_tokens, ','));
-
-  // Revert preload engines to legacy component IDs.
-  base::SplitString(preload_engines_.GetValue(), ',', &new_tokens);
-  std::transform(new_tokens.begin(), new_tokens.end(), new_tokens.begin(),
-                 extension_ime_util::GetComponentIDByInputMethodID);
-  base::SplitString(
-      preload_engines_syncable_.GetValue(), ',', &synced_tokens);
-
-  MergeLists(&new_tokens, synced_tokens);
-  preload_engines_syncable_.SetValue(JoinString(new_tokens, ','));
-
-  // Second, set the local prefs, incorporating new values from the sync server.
-  preload_engines_.SetValue(
-      AddSupportedInputMethodValues(preload_engines_.GetValue(),
-                                    preload_engines_syncable,
-                                    prefs::kLanguagePreloadEngines));
-  enabled_extension_imes_.SetValue(
-      AddSupportedInputMethodValues(enabled_extension_imes_.GetValue(),
-                                    enabled_extension_imes_syncable,
-                                    prefs::kLanguageEnabledExtensionImes));
-
-  // Remove unsupported locales before updating the local languages preference.
-  scoped_ptr<std::string> languages(new std::string(
-      AddSupportedInputMethodValues(preferred_languages_.GetValue(),
-                                    preferred_languages_syncable,
-                                    prefs::kLanguagePreferredLanguages)));
-  content::BrowserThread::GetBlockingPool()->PostTaskAndReply(
-      FROM_HERE,
-      base::Bind(&CheckAndResolveLocales, languages.get()),
-      base::Bind(&InputMethodSyncer::FinishMerge,
-                 weak_factory_.GetWeakPtr(),
-                 base::Passed(&languages)));
-}
-
-std::string InputMethodSyncer::AddSupportedInputMethodValues(
-    const std::string& pref,
-    const std::string& synced_pref,
-    const char* pref_name) {
-  std::vector<std::string> old_tokens;
-  std::vector<std::string> new_tokens;
-  base::SplitString(pref, ',', &old_tokens);
-  base::SplitString(synced_pref, ',', &new_tokens);
-
-  // Check and convert the new tokens.
-  if (pref_name == prefs::kLanguagePreloadEngines ||
-      pref_name == prefs::kLanguageEnabledExtensionImes) {
-    input_method::InputMethodManager* manager =
-        input_method::InputMethodManager::Get();
-    scoped_ptr<input_method::InputMethodDescriptors> supported_descriptors;
-
-    if (pref_name == prefs::kLanguagePreloadEngines) {
-      // Set the known input methods.
-      supported_descriptors = manager->GetSupportedInputMethods();
-      // Add the available component extension IMEs.
-      ComponentExtensionIMEManager* component_extension_manager =
-          manager->GetComponentExtensionIMEManager();
-      input_method::InputMethodDescriptors component_descriptors =
-          component_extension_manager->GetAllIMEAsInputMethodDescriptor();
-      supported_descriptors->insert(supported_descriptors->end(),
-                                    component_descriptors.begin(),
-                                    component_descriptors.end());
-    } else {
-      supported_descriptors.reset(new input_method::InputMethodDescriptors);
-      ime_state_->GetInputMethodExtensions(supported_descriptors.get());
-    }
-    CheckAndResolveInputMethodIDs(*supported_descriptors, &new_tokens);
-  } else if (pref_name != prefs::kLanguagePreferredLanguages) {
-    NOTREACHED() << "Attempting to merge an invalid preference.";
-    // kLanguagePreferredLanguages is checked in CheckAndResolveLocales().
-  }
-
-  // Do the actual merging.
-  MergeLists(&old_tokens, new_tokens);
-  return JoinString(old_tokens, ',');
-}
-
-void InputMethodSyncer::FinishMerge(
-    scoped_ptr<std::string> languages) {
-  // Since the merge only removed locales that are unsupported on this system,
-  // we don't need to update the syncable prefs. If the local preference changes
-  // later, the sync server will lose the values we dropped. That's okay since
-  // the values from this device should then become the new defaults anyway.
-  preferred_languages_.SetValue(*languages);
-
-  // We've finished merging.
-  merging_ = false;
-}
-
-void InputMethodSyncer::OnPreferenceChanged(const std::string& pref_name) {
-  DCHECK(pref_name == prefs::kLanguagePreferredLanguages ||
-         pref_name == prefs::kLanguagePreloadEngines ||
-         pref_name == prefs::kLanguageEnabledExtensionImes);
-
-  if (merging_ || prefs_->GetBoolean(prefs::kLanguageShouldMergeInputMethods))
-    return;
-
-  // Set the language and input prefs at the same time. Otherwise we may,
-  // e.g., use a stale languages setting but push a new preload engines setting.
-  preferred_languages_syncable_.SetValue(preferred_languages_.GetValue());
-  enabled_extension_imes_syncable_.SetValue(enabled_extension_imes_.GetValue());
-
-  // For preload engines, use legacy xkb IDs so the preference can sync
-  // across Chrome OS and Chromium OS.
-  std::vector<std::string> engines;
-  base::SplitString(preload_engines_.GetValue(), ',', &engines);
-  std::transform(engines.begin(), engines.end(), engines.begin(),
-                 extension_ime_util::GetComponentIDByInputMethodID);
-  preload_engines_syncable_.SetValue(JoinString(engines, ','));
-}
-
-void InputMethodSyncer::OnIsSyncingChanged() {
-  if (prefs_->GetBoolean(prefs::kLanguageShouldMergeInputMethods) &&
-      prefs_->IsSyncing()) {
-    MergeSyncedPrefs();
-  }
-}
-
-}  // namespace input_method
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/input_method_syncer.h b/chrome/browser/chromeos/input_method/input_method_syncer.h
deleted file mode 100644
index 08bee9a..0000000
--- a/chrome/browser/chromeos/input_method/input_method_syncer.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_SYNCER_H_
-#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_SYNCER_H_
-
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/prefs/pref_member.h"
-#include "chrome/browser/prefs/pref_service_syncable_observer.h"
-#include "ui/base/ime/chromeos/input_method_manager.h"
-
-class PrefServiceSyncable;
-
-namespace user_prefs {
-class PrefRegistrySyncable;
-}
-
-namespace chromeos {
-namespace input_method {
-
-// Helper class to handle syncing of language and input method preferences.
-// Changes to local preferences are handed up to the sync server. But Chrome OS
-// should not locally apply the corresponding preferences from the sync server,
-// except once: when the user first logs into the device.
-// Thus, the user's most recent changes to language and input method preferences
-// will be brought down when signing in to a new device but not in future syncs.
-class InputMethodSyncer : public PrefServiceSyncableObserver {
- public:
-  InputMethodSyncer(
-      PrefServiceSyncable* prefs,
-      scoped_refptr<input_method::InputMethodManager::State> ime_state);
-  virtual ~InputMethodSyncer();
-
-  // Registers the syncable input method prefs.
-  static void RegisterProfilePrefs(
-      user_prefs::PrefRegistrySyncable* registry);
-
-  // Must be called after InputMethodSyncer is created.
-  void Initialize();
-
- private:
-  // Adds the input methods from the syncable prefs to the device-local prefs.
-  // This should only be called once (after user's first sync) and only adds
-  // to, not removes from, the user's input method prefs.
-  void MergeSyncedPrefs();
-
-  // For the given input method pref, adds unique values from |synced_pref| to
-  // values in |pref|. The new values are converted from legacy engine IDs to
-  // input method IDs if necessary.
-  std::string AddSupportedInputMethodValues(
-      const std::string& pref,
-      const std::string& synced_pref,
-      const char* pref_name);
-
-  // Sets prefs::kLanguagePreferredLanguages and sets |merging_| to false.
-  void FinishMerge(scoped_ptr<std::string> languages);
-
-  // Callback method for preference changes. Updates the syncable prefs using
-  // the local pref values.
-  void OnPreferenceChanged(const std::string& pref_name);
-
-  // PrefServiceSyncableObserver implementation.
-  void OnIsSyncingChanged() override;
-
-  StringPrefMember preferred_languages_;
-  StringPrefMember preload_engines_;
-  StringPrefMember enabled_extension_imes_;
-  // These are syncable variants which don't change the device settings. We can
-  // set these to keep track of the user's most recent choices. That way, after
-  // the initial sync, we can add the user's synced choices to the values that
-  // have already been chosen at OOBE.
-  StringPrefMember preferred_languages_syncable_;
-  StringPrefMember preload_engines_syncable_;
-  StringPrefMember enabled_extension_imes_syncable_;
-
-  PrefServiceSyncable* prefs_;
-  scoped_refptr<input_method::InputMethodManager::State> ime_state_;
-
-  // Used to ignore PrefChanged events while InputMethodManager is merging.
-  bool merging_;
-
-  base::WeakPtrFactory<InputMethodSyncer> weak_factory_;
-};
-
-}  // namespace input_method
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_SYNCER_H_
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index a66fe09..5b68bb9 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -172,12 +172,9 @@
   }
 
   // Save the preferred languages in the user's preferences.
-  prefs->SetString(prefs::kLanguagePreferredLanguages,
-                   JoinString(language_codes, ','));
-
-  // Indicate that we need to merge the syncable input methods when we sync,
-  // since we have not applied the synced prefs before.
-  prefs->SetBoolean(prefs::kLanguageShouldMergeInputMethods, true);
+  StringPrefMember language_preferred_languages;
+  language_preferred_languages.Init(prefs::kLanguagePreferredLanguages, prefs);
+  language_preferred_languages.SetValue(JoinString(language_codes, ','));
 }
 
 #if defined(ENABLE_RLZ)
@@ -1488,8 +1485,4 @@
   callback.Run();
 }
 
-void UserSessionManager::RemoveProfileForTesting(Profile* profile) {
-  default_ime_states_.erase(profile);
-}
-
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.h b/chrome/browser/chromeos/login/session/user_session_manager.h
index b540c43..7ed0114 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.h
+++ b/chrome/browser/chromeos/login/session/user_session_manager.h
@@ -206,9 +206,6 @@
   // Update Easy unlock cryptohome keys for given user context.
   void UpdateEasyUnlockKeys(const UserContext& user_context);
 
-  // Removes a profile from the per-user input methods states map.
-  void RemoveProfileForTesting(Profile* profile);
-
  private:
   friend struct DefaultSingletonTraits<UserSessionManager>;
 
diff --git a/chrome/browser/chromeos/login/users/fake_user_manager.cc b/chrome/browser/chromeos/login/users/fake_user_manager.cc
index f5f118b4..03f5a3d 100644
--- a/chrome/browser/chromeos/login/users/fake_user_manager.cc
+++ b/chrome/browser/chromeos/login/users/fake_user_manager.cc
@@ -167,12 +167,6 @@
   active_user_id_ = email;
   ProfileHelper::Get()->ActiveUserHashChanged(
       ProfileHelper::GetUserIdHashByUserIdForTesting(email));
-  if (user_list_.size() && !active_user_id_.empty()) {
-    for (user_manager::UserList::const_iterator it = user_list_.begin();
-         it != user_list_.end(); ++it) {
-      (*it)->set_is_active((*it)->email() == active_user_id_);
-    }
-  }
 }
 
 void FakeUserManager::SaveUserDisplayName(
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index 6ab83e2f..365d53e8 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -22,9 +22,10 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
-#include "chrome/browser/chromeos/input_method/input_method_syncer.h"
+#include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
 #include "chrome/browser/chromeos/net/wake_on_wifi_manager.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/system/input_device_settings.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
@@ -35,7 +36,6 @@
 #include "components/feedback/tracing_manager.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/user_manager/user.h"
-#include "content/public/browser/browser_thread.h"
 #include "third_party/icu/source/i18n/unicode/timezone.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
 #include "ui/base/ime/chromeos/ime_keyboard.h"
@@ -216,6 +216,9 @@
       prefs::kLanguagePreviousInputMethod,
       "",
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+  // We don't sync the list of input methods and preferred languages since a
+  // user might use two or more devices with different hardware keyboards.
+  // crosbug.com/15181
   registry->RegisterStringPref(
       prefs::kLanguagePreferredLanguages,
       kFallbackInputMethodLocale,
@@ -319,8 +322,6 @@
       prefs::kTouchVirtualKeyboardEnabled,
       false,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-
-  input_method::InputMethodSyncer::RegisterProfilePrefs(registry);
 }
 
 void Preferences::InitUserPrefs(PrefServiceSyncable* prefs) {
@@ -366,9 +367,6 @@
   DCHECK(profile);
   DCHECK(user);
   PrefServiceSyncable* prefs = PrefServiceSyncable::FromProfile(profile);
-  // This causes OnIsSyncingChanged to be called when the value of
-  // PrefService::IsSyncing() changes.
-  prefs->AddObserver(this);
   user_ = user;
   user_is_primary_ =
       user_manager::UserManager::Get()->GetPrimaryUser() == user_;
@@ -376,6 +374,10 @@
 
   user_manager::UserManager::Get()->AddSessionStateObserver(this);
 
+  // This causes OnIsSyncingChanged to be called when the value of
+  // PrefService::IsSyncing() changes.
+  prefs->AddObserver(this);
+
   UserSessionManager* session_manager = UserSessionManager::GetInstance();
   DCHECK(session_manager);
   ime_state_ = session_manager->GetDefaultIMEState(profile);
@@ -383,9 +385,6 @@
 
   // Initialize preferences to currently saved state.
   ApplyPreferences(REASON_INITIALIZATION, "");
-  input_method_syncer_.reset(
-      new input_method::InputMethodSyncer(prefs, ime_state_));
-  input_method_syncer_->Initialize();
 
   // If a guest is logged in, initialize the prefs as if this is the first
   // login. For a regular user this is done in
@@ -405,10 +404,6 @@
     input_method_manager_->SetState(ime_state);
 
   InitUserPrefs(prefs);
-
-  input_method_syncer_.reset(
-      new input_method::InputMethodSyncer(prefs, ime_state_));
-  input_method_syncer_->Initialize();
 }
 
 void Preferences::SetInputMethodListForTesting() {
@@ -550,9 +545,7 @@
 #if !defined(USE_ATHENA)
     if (user_is_active) {
       const bool enabled = touch_hud_projection_enabled_.GetValue();
-      // There may not be a shell, e.g., in some unit tests.
-      if (ash::Shell::HasInstance())
-        ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled);
+      ash::Shell::GetInstance()->SetTouchHudProjectionEnabled(enabled);
     }
 #endif
   }
diff --git a/chrome/browser/chromeos/preferences.h b/chrome/browser/chromeos/preferences.h
index 88d861a..b0d8c9a 100644
--- a/chrome/browser/chromeos/preferences.h
+++ b/chrome/browser/chromeos/preferences.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_PREFERENCES_H_
 
 #include <string>
+#include <vector>
 
 #include "ash/shell_observer.h"
 #include "base/compiler_specific.h"
@@ -31,7 +32,6 @@
 
 namespace input_method {
 class InputMethodManager;
-class InputMethodSyncer;
 }
 
 // The Preferences class handles Chrome OS preferences. When the class
@@ -151,8 +151,6 @@
   // Input Methods state for this user.
   scoped_refptr<input_method::InputMethodManager::State> ime_state_;
 
-  scoped_ptr<input_method::InputMethodSyncer> input_method_syncer_;
-
   DISALLOW_COPY_AND_ASSIGN(Preferences);
 };
 
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc
index 8483e1e..194b303 100644
--- a/chrome/browser/chromeos/preferences_unittest.cc
+++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -4,82 +4,25 @@
 
 #include "chrome/browser/chromeos/preferences.h"
 
-#include "base/json/json_string_value_serializer.h"
 #include "base/prefs/pref_member.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/chromeos/input_method/input_method_configuration.h"
 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
-#include "chrome/browser/chromeos/login/session/user_session_manager.h"
 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
-#include "chrome/browser/chromeos/system/fake_input_device_settings.h"
-#include "chrome/common/chrome_constants.h"
+#include "chrome/browser/download/download_prefs.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
-#include "chrome/test/base/testing_profile.h"
-#include "chrome/test/base/testing_profile_manager.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/public/test/test_utils.h"
-#include "sync/api/attachments/attachment_id.h"
-#include "sync/api/fake_sync_change_processor.h"
-#include "sync/api/sync_change.h"
-#include "sync/api/sync_data.h"
-#include "sync/api/sync_error_factory.h"
-#include "sync/api/sync_error_factory_mock.h"
-#include "sync/api/syncable_service.h"
-#include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
-#include "sync/protocol/preference_specifics.pb.h"
-#include "sync/protocol/sync.pb.h"
+#include "components/pref_registry/pref_registry_syncable.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/ime/chromeos/extension_ime_util.h"
-#include "ui/base/ime/chromeos/input_method_whitelist.h"
-#include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h"
-#include "url/gurl.h"
 
 namespace chromeos {
 namespace {
 
-const char kIdentityIMEID[] =
-    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpIdentityIME";
-const char kToUpperIMEID[] =
-    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpToUpperIME";
-const char kAPIArgumentIMEID[] =
-    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpAPIArgumentIME";
-const char kUnknownIMEID[] =
-    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpUnknownIME";
-
-syncer::SyncData
-CreatePrefSyncData(const std::string& name, const base::Value& value) {
-  std::string serialized;
-  JSONStringValueSerializer json(&serialized);
-  json.Serialize(value);
-  sync_pb::EntitySpecifics specifics;
-  sync_pb::PreferenceSpecifics* pref = specifics.mutable_preference();
-  pref->set_name(name);
-  pref->set_value(serialized);
-  return syncer::SyncData::CreateRemoteData(
-      1,
-      specifics,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
-}
-
-}  // anonymous namespace
-
-namespace input_method {
-namespace {
-
-class MyMockInputMethodManager : public MockInputMethodManager {
+class MyMockInputMethodManager : public input_method::MockInputMethodManager {
  public:
   class State : public MockInputMethodManager::State {
    public:
     explicit State(MyMockInputMethodManager* manager)
-        : MockInputMethodManager::State(manager), manager_(manager) {
-      input_method_extensions_.reset(new InputMethodDescriptors);
-    }
+        : MockInputMethodManager::State(manager), manager_(manager) {};
 
     virtual void ChangeInputMethod(const std::string& input_method_id,
                                    bool show_message) override {
@@ -93,27 +36,11 @@
       manager_->current_->SetValue(input_method_id);
     }
 
-    virtual void
-    GetInputMethodExtensions(InputMethodDescriptors* result) override {
-      *result = *input_method_extensions_;
-    }
-
-    virtual void AddInputMethodExtension(
-        const std::string& id,
-        const InputMethodDescriptors& descriptors,
-        InputMethodEngineInterface* instance) override {
-      InputMethodDescriptor descriptor(
-          id, std::string(), std::string(), std::vector<std::string>(),
-          std::vector<std::string>(), false, GURL(), GURL());
-      input_method_extensions_->push_back(descriptor);
-    }
-
    protected:
     virtual ~State() {};
 
    private:
     MyMockInputMethodManager* const manager_;
-    scoped_ptr<InputMethodDescriptors> input_method_extensions_;
   };
 
   MyMockInputMethodManager(StringPrefMember* previous,
@@ -125,584 +52,49 @@
 
   virtual ~MyMockInputMethodManager() {}
 
-  virtual scoped_ptr<InputMethodDescriptors>
-  GetSupportedInputMethods() const override {
-    return whitelist_.GetSupportedInputMethods().Pass();
-  }
-
   std::string last_input_method_id_;
 
  private:
   StringPrefMember* previous_;
   StringPrefMember* current_;
-  InputMethodWhitelist whitelist_;
 };
 
 }  // anonymous namespace
-}  // namespace input_method
 
-class PreferencesTest : public testing::Test {
- public:
-  PreferencesTest() {}
-  virtual ~PreferencesTest() {}
+TEST(PreferencesTest, TestUpdatePrefOnBrowserScreenDetails) {
+  chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager();
+  chromeos::ScopedUserManagerEnabler user_manager_enabler(user_manager);
+  const char test_user_email[] = "test_user@example.com";
+  const user_manager::User* test_user = user_manager->AddUser(test_user_email);
+  user_manager->LoginUser(test_user_email);
 
-  virtual void SetUp() override {
-    profile_manager_.reset(
-        new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
-    ASSERT_TRUE(profile_manager_->SetUp());
+  TestingPrefServiceSyncable prefs;
+  Preferences::RegisterProfilePrefs(prefs.registry());
+  DownloadPrefs::RegisterProfilePrefs(prefs.registry());
+  // kSelectFileLastDirectory is registered for Profile. Here we register it for
+  // testing.
+  prefs.registry()->RegisterStringPref(
+      prefs::kSelectFileLastDirectory,
+      std::string(),
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 
-    chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager();
-    user_manager_enabler_.reset(
-        new chromeos::ScopedUserManagerEnabler(user_manager));
+  StringPrefMember previous;
+  previous.Init(prefs::kLanguagePreviousInputMethod, &prefs);
+  previous.SetValue("KeyboardA");
+  StringPrefMember current;
+  current.Init(prefs::kLanguageCurrentInputMethod, &prefs);
+  current.SetValue("KeyboardB");
 
-    const char test_user_email[] = "test_user@example.com";
-    test_user_ = user_manager->AddUser(test_user_email);
-    user_manager->LoginUser(test_user_email);
-    user_manager->SwitchActiveUser(test_user_email);
+  MyMockInputMethodManager mock_manager(&previous, &current);
+  Preferences testee(&mock_manager);
+  testee.InitUserPrefsForTesting(
+      &prefs, test_user, mock_manager.GetActiveIMEState());
+  testee.SetInputMethodListForTesting();
 
-    test_profile_ = profile_manager_->CreateTestingProfile(
-        chrome::kInitialProfile);
-    pref_service_ = test_profile_->GetTestingPrefService();
-
-    previous_input_method_.Init(
-        prefs::kLanguagePreviousInputMethod, pref_service_);
-    previous_input_method_.SetValue("KeyboardA");
-    current_input_method_.Init(
-        prefs::kLanguageCurrentInputMethod, pref_service_);
-    current_input_method_.SetValue("KeyboardB");
-
-    mock_manager_ = new input_method::MyMockInputMethodManager(
-        &previous_input_method_, &current_input_method_);
-    input_method::InitializeForTesting(mock_manager_);
-    system::InputDeviceSettings::SetSettingsForTesting(
-        new system::FakeInputDeviceSettings());
-
-    prefs_.reset(new Preferences(mock_manager_));
-  }
-
-  virtual void TearDown() override {
-    input_method::Shutdown();
-    // UserSessionManager doesn't listen to profile destruction, so make sure
-    // the default IME state isn't still cached in case test_profile_ is
-    // given the same address in the next test.
-    UserSessionManager::GetInstance()->RemoveProfileForTesting(test_profile_);
-  }
-
-  void InitPreferences() {
-    prefs_->InitUserPrefsForTesting(
-        pref_service_, test_user_, mock_manager_->GetActiveIMEState());
-    prefs_->SetInputMethodListForTesting();
-  }
-
-  scoped_ptr<TestingProfileManager> profile_manager_;
-  scoped_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
-  scoped_ptr<Preferences> prefs_;
-  StringPrefMember previous_input_method_;
-  StringPrefMember current_input_method_;
-
-  // Not owned.
-  const user_manager::User* test_user_;
-  TestingProfile* test_profile_;
-  TestingPrefServiceSyncable* pref_service_;
-  input_method::MyMockInputMethodManager* mock_manager_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PreferencesTest);
-};
-
-TEST_F(PreferencesTest, TestUpdatePrefOnBrowserScreenDetails) {
-  InitPreferences();
-
-  // Confirm the current and previous input methods are unchanged.
-  EXPECT_EQ("KeyboardA", previous_input_method_.GetValue());
-  EXPECT_EQ("KeyboardB", current_input_method_.GetValue());
-  EXPECT_EQ("KeyboardB", mock_manager_->last_input_method_id_);
-}
-
-class InputMethodPreferencesTest : public PreferencesTest {
- public:
-  InputMethodPreferencesTest() {}
-  virtual ~InputMethodPreferencesTest() {}
-
-  virtual void SetUp() override {
-    PreferencesTest::SetUp();
-
-    // Initialize pref members.
-    preferred_languages_.Init(prefs::kLanguagePreferredLanguages,
-                              pref_service_);
-    preferred_languages_syncable_.Init(
-        prefs::kLanguagePreferredLanguagesSyncable,
-        pref_service_);
-    preload_engines_.Init(prefs::kLanguagePreloadEngines, pref_service_);
-    preload_engines_syncable_.Init(prefs::kLanguagePreloadEnginesSyncable,
-                                   pref_service_);
-    enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes,
-                                 pref_service_);
-    enabled_extension_imes_syncable_.Init(
-        prefs::kLanguageEnabledExtensionImesSyncable, pref_service_);
-
-    // Initialize component and 3rd-party input method extensions.
-    InitComponentExtensionIMEManager();
-    input_method::InputMethodDescriptors descriptors;
-    mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
-        kIdentityIMEID,
-        descriptors,
-        NULL);
-    mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
-        kToUpperIMEID,
-        descriptors,
-        NULL);
-    mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
-        kAPIArgumentIMEID,
-        descriptors,
-        NULL);
-  }
-
-  void InitComponentExtensionIMEManager() {
-    // Set our custom IME list on the mock delegate.
-    input_method::MockComponentExtIMEManagerDelegate* mock_delegate =
-        new input_method::MockComponentExtIMEManagerDelegate();
-    mock_delegate->set_ime_list(CreateImeList());
-
-    // Pass the mock delegate to a new ComponentExtensionIMEManager.
-    scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(mock_delegate);
-    scoped_ptr<ComponentExtensionIMEManager> component_extension_ime_manager(
-        new ComponentExtensionIMEManager);
-    component_extension_ime_manager->Initialize(delegate.Pass());
-
-    // Add the ComponentExtensionIMEManager to the mock InputMethodManager.
-    mock_manager_->SetComponentExtensionIMEManager(
-        component_extension_ime_manager.Pass());
-  }
-
-  std::vector<ComponentExtensionIME> CreateImeList() {
-    std::vector<ComponentExtensionIME> ime_list;
-
-    ComponentExtensionIME ext;
-    ext.id = extension_ime_util::kMozcExtensionId;
-    ext.description = "ext_description";
-    ext.path = base::FilePath("ext_file_path");
-
-    ComponentExtensionEngine ext_engine1;
-    ext_engine1.engine_id = "nacl_mozc_us";
-    ext_engine1.display_name = "ext_engine_1_display_name";
-    ext_engine1.language_codes.push_back("ja");
-    ext_engine1.layouts.push_back("us");
-    ext.engines.push_back(ext_engine1);
-
-    ComponentExtensionEngine ext_engine2;
-    ext_engine2.engine_id = "nacl_mozc_jp";
-    ext_engine2.display_name = "ext_engine_2_display_name";
-    ext_engine2.language_codes.push_back("ja");
-    ext_engine2.layouts.push_back("jp");
-    ext.engines.push_back(ext_engine2);
-
-    ime_list.push_back(ext);
-    return ime_list;
-  }
-
-  // Helper function to set local language and input values.
-  void SetLocalValues(const std::string& preferred_languages,
-                      const std::string& preload_engines,
-                      const std::string& enabled_extension_imes) {
-    preferred_languages_.SetValue(preferred_languages);
-    preload_engines_.SetValue(preload_engines);
-    enabled_extension_imes_.SetValue(enabled_extension_imes);
-  }
-
-  // Helper function to set global language and input values.
-  void SetGlobalValues(const std::string& preferred_languages,
-                       const std::string& preload_engines,
-                       const std::string& enabled_extension_imes) {
-    preferred_languages_syncable_.SetValue(preferred_languages);
-    preload_engines_syncable_.SetValue(preload_engines);
-    enabled_extension_imes_syncable_.SetValue(enabled_extension_imes);
-  }
-
-  // Helper function to check local language and input values.
-  void ExpectLocalValues(const std::string& preferred_languages,
-                         const std::string& preload_engines,
-                         const std::string& enabled_extension_imes) {
-    EXPECT_EQ(preferred_languages, preferred_languages_.GetValue());
-    EXPECT_EQ(preload_engines, preload_engines_.GetValue());
-    EXPECT_EQ(enabled_extension_imes, enabled_extension_imes_.GetValue());
-  }
-
-  // Helper function to check global language and input values.
-  void ExpectGlobalValues(const std::string& preferred_languages,
-                          const std::string& preload_engines,
-                          const std::string& enabled_extension_imes) {
-    EXPECT_EQ(preferred_languages, preferred_languages_syncable_.GetValue());
-    EXPECT_EQ(preload_engines, preload_engines_syncable_.GetValue());
-    EXPECT_EQ(enabled_extension_imes,
-              enabled_extension_imes_syncable_.GetValue());
-  }
-
-  // Translates engine IDs in a CSV string to input method IDs.
-  std::string ToInputMethodIds(std::string value) {
-    std::vector<std::string> tokens;
-    base::SplitString(value, ',', &tokens);
-    std::transform(tokens.begin(), tokens.end(), tokens.begin(),
-                   &extension_ime_util::GetInputMethodIDByEngineID);
-    return JoinString(tokens, ',');
-  }
-
-  StringPrefMember preferred_languages_;
-  StringPrefMember preferred_languages_syncable_;
-  StringPrefMember preload_engines_;
-  StringPrefMember preload_engines_syncable_;
-  StringPrefMember enabled_extension_imes_;
-  StringPrefMember enabled_extension_imes_syncable_;
-  content::TestBrowserThreadBundle thread_bundle_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(InputMethodPreferencesTest);
-};
-
-// Tests that the server values are added to the values chosen at OOBE.
-TEST_F(InputMethodPreferencesTest, TestOobeAndSync) {
-  // Choose options at OOBE.
-  pref_service_->SetBoolean(
-      prefs::kLanguageShouldMergeInputMethods, true);
-  SetLocalValues("es",
-                 ToInputMethodIds("xkb:us:altgr-intl:eng"),
-                 std::string());
-  InitPreferences();
-
-  // Suppose we add an input method before syncing starts.
-  preload_engines_.SetValue(
-      ToInputMethodIds("xkb:us:altgr-intl:eng,xkb:us:intl:eng"));
-
-  // Create some values to come from the server.
-  syncer::SyncDataList sync_data_list;
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable, base::StringValue("ru,fi")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue("xkb:se::swe")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(kIdentityIMEID)));
-
-  // Sync for the first time.
-  syncer::SyncableService* sync =
-      pref_service_->GetSyncableService(
-          syncer::PREFERENCES);
-  sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
-                                 sync_data_list,
-                                 scoped_ptr<syncer::SyncChangeProcessor>(
-                                     new syncer::FakeSyncChangeProcessor),
-                                 scoped_ptr<syncer::SyncErrorFactory>(
-                                     new syncer::SyncErrorFactoryMock));
-  content::RunAllBlockingPoolTasksUntilIdle();
-
-  // Note that we expect the preload_engines to have been translated to input
-  // method IDs during the merge.
-  std::string expected_languages("es,ru,fi");
-  std::string expected_preload_engines(
-      "xkb:us:altgr-intl:eng,xkb:us:intl:eng,xkb:se::swe");
-  std::string expected_extensions(kIdentityIMEID);
-  {
-    SCOPED_TRACE("Server values should have merged into local values.");
-    ExpectLocalValues(
-        expected_languages,
-        ToInputMethodIds(expected_preload_engines),
-        expected_extensions);
-  }
-  {
-    SCOPED_TRACE("Server values should have been updated to local values.");
-    ExpectGlobalValues(
-        expected_languages, expected_preload_engines, expected_extensions);
-  }
-
-  // Update the global values from the server again.
-  syncer::SyncChangeList change_list;
-  change_list.push_back(syncer::SyncChange(
-      FROM_HERE,
-      syncer::SyncChange::ACTION_UPDATE,
-      CreatePrefSyncData(
-          prefs::kLanguagePreferredLanguagesSyncable,
-          base::StringValue("de"))));
-  change_list.push_back(syncer::SyncChange(
-      FROM_HERE,
-      syncer::SyncChange::ACTION_UPDATE,
-      CreatePrefSyncData(
-          prefs::kLanguagePreloadEnginesSyncable,
-          base::StringValue(ToInputMethodIds("xkb:de::ger")))));
-  change_list.push_back(syncer::SyncChange(
-      FROM_HERE,
-      syncer::SyncChange::ACTION_UPDATE,
-      CreatePrefSyncData(
-          prefs::kLanguageEnabledExtensionImesSyncable,
-          base::StringValue(kToUpperIMEID))));
-  sync->ProcessSyncChanges(FROM_HERE, change_list);
-  content::RunAllBlockingPoolTasksUntilIdle();
-
-  {
-    SCOPED_TRACE("Local preferences should have remained the same.");
-    ExpectLocalValues(
-        expected_languages,
-        ToInputMethodIds(expected_preload_engines),
-        expected_extensions);
-  }
-  // Change local preferences.
-  SetLocalValues("ja", ToInputMethodIds("xkb:jp::jpn"), "ime2");
-  {
-    SCOPED_TRACE("Global preferences should have been updated.");
-    ExpectGlobalValues("ja", "xkb:jp::jpn", "ime2");
-  }
-  content::RunAllBlockingPoolTasksUntilIdle();
-}
-
-// Tests that logging in after sync has completed changes nothing.
-TEST_F(InputMethodPreferencesTest, TestLogIn) {
-  // Set up existing preference values.
-  std::string languages("es");
-  std::string preload_engines(ToInputMethodIds("xkb:es::spa"));
-  std::string extensions(kIdentityIMEID);
-
-  SetLocalValues(languages, preload_engines, extensions);
-  SetGlobalValues(languages, preload_engines, extensions);
-  pref_service_->SetBoolean(
-      prefs::kLanguageShouldMergeInputMethods, false);
-  InitPreferences();
-
-  // Create some values to come from the server.
-  syncer::SyncDataList sync_data_list;
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguages, base::StringValue("ru,fi")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEngines,
-      base::StringValue(ToInputMethodIds("xkb:ru::rus"))));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImes, base::StringValue(kIdentityIMEID)));
-
-  // Sync.
-  syncer::SyncableService* sync =
-      pref_service_->GetSyncableService(
-          syncer::PREFERENCES);
-  sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
-                                 sync_data_list,
-                                 scoped_ptr<syncer::SyncChangeProcessor>(
-                                     new syncer::FakeSyncChangeProcessor),
-                                 scoped_ptr<syncer::SyncErrorFactory>(
-                                     new syncer::SyncErrorFactoryMock));
-  content::RunAllBlockingPoolTasksUntilIdle();
-  {
-    SCOPED_TRACE("Local preferences should have remained the same.");
-    ExpectLocalValues(languages, preload_engines, extensions);
-  }
-  // Change local preferences.
-  SetLocalValues("ja", ToInputMethodIds("xkb:jp::jpn"), kToUpperIMEID);
-  content::RunAllBlockingPoolTasksUntilIdle();
-  {
-    SCOPED_TRACE("Global preferences should have been updated.");
-    ExpectGlobalValues("ja", "xkb:jp::jpn", kToUpperIMEID);
-  }
-}
-
-// Tests that logging in with preferences from before a) XKB component
-// extensions and b) the IME syncing logic doesn't overwrite settings.
-TEST_F(InputMethodPreferencesTest, TestLogInLegacy) {
-  // Simulate existing local preferences from M-36.
-  SetLocalValues("es", "xkb:es::spa", kIdentityIMEID);
-  InitPreferences();
-
-  // Sync. Since this is an existing profile, the local values shouldn't change.
-  syncer::SyncDataList sync_data_list;
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable, base::StringValue("ru,fi")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue(ToInputMethodIds("xkb:ru::rus"))));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(kToUpperIMEID)));
-
-  syncer::SyncableService* sync =
-      pref_service_->GetSyncableService(
-          syncer::PREFERENCES);
-  sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
-                                 sync_data_list,
-                                 scoped_ptr<syncer::SyncChangeProcessor>(
-                                     new syncer::FakeSyncChangeProcessor),
-                                 scoped_ptr<syncer::SyncErrorFactory>(
-                                     new syncer::SyncErrorFactoryMock));
-  content::RunAllBlockingPoolTasksUntilIdle();
-  {
-    SCOPED_TRACE("Local preferences should have remained the same.");
-    ExpectLocalValues("es", "xkb:es::spa", kIdentityIMEID);
-  }
-  {
-    SCOPED_TRACE("Global preferences should have remained the same.");
-    ExpectGlobalValues("ru,fi", ToInputMethodIds("xkb:ru::rus"), kToUpperIMEID);
-  }
-  // Change local preferences.
-  SetLocalValues("ja", ToInputMethodIds("xkb:jp::jp"), kAPIArgumentIMEID);
-  {
-    SCOPED_TRACE("Global preferences should have been updated.");
-    ExpectGlobalValues("ja", "xkb:jp::jp", kAPIArgumentIMEID);
-  }
-}
-
-// Tests some edge cases: empty strings, lots of values, duplicates.
-TEST_F(InputMethodPreferencesTest, MergeStressTest) {
-  SetLocalValues("hr,lv,lt,es-419,he,el,da,ca,es,cs,bg",
-                 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
-                 std::string());
-  pref_service_->SetBoolean(
-      prefs::kLanguageShouldMergeInputMethods, true);
-  InitPreferences();
-
-  // Change input methods and languages before syncing starts.
-  std::string local_extensions =
-      kToUpperIMEID + std::string(",") +
-      kAPIArgumentIMEID + std::string(",") +
-      kIdentityIMEID;
-  SetLocalValues(
-      "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar",
-      ToInputMethodIds("xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr"),
-      local_extensions);
-
-  // Create some tricky values to come from the server.
-  syncer::SyncDataList sync_data_list;
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable,
-      base::StringValue("ar,fi,es,de,ar")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue(
-          "nacl_mozc_us,xkb:ru::rus,xkb:ru::rus,xkb:es::spa,xkb:es::spa")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(std::string())));
-
-  // Sync for the first time.
-  syncer::SyncableService* sync =
-      pref_service_->GetSyncableService(
-          syncer::PREFERENCES);
-  sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
-                                 sync_data_list,
-                                 scoped_ptr<syncer::SyncChangeProcessor>(
-                                     new syncer::FakeSyncChangeProcessor),
-                                 scoped_ptr<syncer::SyncErrorFactory>(
-                                     new syncer::SyncErrorFactoryMock));
-  content::RunAllBlockingPoolTasksUntilIdle();
-  {
-    SCOPED_TRACE("Server values should have merged into local values.");
-    ExpectLocalValues(
-        "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar,fi,de",
-        ToInputMethodIds("xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr,"
-                         "nacl_mozc_us,xkb:ru::rus"),
-        local_extensions);
-  }
-  {
-    SCOPED_TRACE("Server values should have incorporated local values.");
-    ExpectGlobalValues(
-        "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar,fi,de",
-        "xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr,nacl_mozc_us,xkb:ru::rus",
-        local_extensions);
-  }
-}
-
-// Tests non-existent IDs.
-TEST_F(InputMethodPreferencesTest, MergeInvalidValues) {
-  SetLocalValues("es",
-                 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
-                 kIdentityIMEID);
-  pref_service_->SetBoolean(
-      prefs::kLanguageShouldMergeInputMethods, true);
-  InitPreferences();
-
-  // Create some valid and some non-existent IDs from the server.
-  std::string preload_engines(
-      "xkb:ru::rus,xkb:xy::xyz,"
-      "_comp_ime_nothisisnotactuallyanextensionidxkb:es::spa," +
-      ToInputMethodIds("xkb:jp::jpn"));
-  syncer::SyncDataList sync_data_list;
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable,
-      base::StringValue("klingon,en-US")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue(preload_engines)));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(kUnknownIMEID)));
-
-  // Sync for the first time.
-  syncer::SyncableService* sync =
-      pref_service_->GetSyncableService(
-          syncer::PREFERENCES);
-  sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
-                                 sync_data_list,
-                                 scoped_ptr<syncer::SyncChangeProcessor>(
-                                     new syncer::FakeSyncChangeProcessor),
-                                 scoped_ptr<syncer::SyncErrorFactory>(
-                                     new syncer::SyncErrorFactoryMock));
-  content::RunAllBlockingPoolTasksUntilIdle();
-  {
-    SCOPED_TRACE("Only valid server values should have been merged in.");
-    ExpectLocalValues(
-        "es,en-US",
-        ToInputMethodIds("xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:jp::jpn"),
-        kIdentityIMEID);
-  }
-}
-
-// Tests that we merge input methods even if syncing has started before
-// initialization of Preferences.
-TEST_F(InputMethodPreferencesTest, MergeAfterSyncing) {
-  SetLocalValues("es",
-                 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
-                 kIdentityIMEID);
-  pref_service_->SetBoolean(
-      prefs::kLanguageShouldMergeInputMethods, true);
-
-  // Create some valid and some non-existent IDs from the server.
-  std::string preload_engines(
-      "xkb:ru::rus,xkb:xy::xyz," + ToInputMethodIds("xkb:jp::jpn"));
-  syncer::SyncDataList sync_data_list;
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable,
-      base::StringValue("en-US")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue(preload_engines)));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(kUnknownIMEID)));
-
-  // Sync for the first time.
-  syncer::SyncableService* sync =
-      pref_service_->GetSyncableService(
-          syncer::PREFERENCES);
-  sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
-                                 sync_data_list,
-                                 scoped_ptr<syncer::SyncChangeProcessor>(
-                                     new syncer::FakeSyncChangeProcessor),
-                                 scoped_ptr<syncer::SyncErrorFactory>(
-                                     new syncer::SyncErrorFactoryMock));
-  content::RunAllBlockingPoolTasksUntilIdle();
-  InitPreferences();
-  content::RunAllBlockingPoolTasksUntilIdle();
-
-  {
-    SCOPED_TRACE("Local values should have been merged on initialization.");
-    ExpectLocalValues(
-        "es,en-US",
-        ToInputMethodIds("xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:jp::jpn"),
-        kIdentityIMEID);
-  }
-  {
-    SCOPED_TRACE(
-        "Syncable values should have added local values on initialization.");
-    ExpectGlobalValues(
-        "es,en-US",
-        "xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:xy::xyz," +
-            ToInputMethodIds("xkb:jp::jpn"),
-        std::string(kIdentityIMEID) + "," + kUnknownIMEID);
-  }
+  // Confirm they're unchanged.
+  EXPECT_EQ("KeyboardA", previous.GetValue());
+  EXPECT_EQ("KeyboardB", current.GetValue());
+  EXPECT_EQ("KeyboardB", mock_manager.last_input_method_id_);
 }
 
 }  // namespace chromeos
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index bbde250..54d5846 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -389,8 +389,6 @@
         'browser/chromeos/input_method/input_method_manager_impl.h',
         'browser/chromeos/input_method/input_method_persistence.cc',
         'browser/chromeos/input_method/input_method_persistence.h',
-        'browser/chromeos/input_method/input_method_syncer.cc',
-        'browser/chromeos/input_method/input_method_syncer.h',
         'browser/chromeos/input_method/input_method_util.cc',
         'browser/chromeos/input_method/input_method_util.h',
         'browser/chromeos/input_method/mode_indicator_controller.cc',
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index b2b045b5..0cbf93d 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -539,25 +539,14 @@
 // (ex. "en-US,fr,ko").
 const char kLanguagePreferredLanguages[] =
     "settings.language.preferred_languages";
-const char kLanguagePreferredLanguagesSyncable[] =
-    "settings.language.preferred_languages_syncable";
 
 // A string pref (comma-separated list) set to the preloaded (active) input
 // method IDs (ex. "pinyin,mozc").
 const char kLanguagePreloadEngines[] = "settings.language.preload_engines";
-const char kLanguagePreloadEnginesSyncable[] =
-    "settings.language.preload_engines_syncable";
 
-// A string pref (comma-separated list) set to the extension IMEs to be enabled.
+// A List pref (comma-separated list) set to the extension IMEs to be enabled.
 const char kLanguageEnabledExtensionImes[] =
     "settings.language.enabled_extension_imes";
-const char kLanguageEnabledExtensionImesSyncable[] =
-    "settings.language.enabled_extension_imes_syncable";
-
-// A boolean pref to indicate whether we still need to add the globally synced
-// input methods. False after the initial post-OOBE sync.
-const char kLanguageShouldMergeInputMethods[] =
-    "settings.language.merge_input_methods";
 
 // Integer prefs which determine how we remap modifier keys (e.g. swap Alt and
 // Control.) Possible values for these prefs are 0-4. See ModifierKey enum in
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 26e83643..b71bcfa 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -194,12 +194,8 @@
 extern const char kLanguageHotkeyNextEngineInMenu[];
 extern const char kLanguageHotkeyPreviousEngine[];
 extern const char kLanguagePreferredLanguages[];
-extern const char kLanguagePreferredLanguagesSyncable[];
 extern const char kLanguagePreloadEngines[];
-extern const char kLanguagePreloadEnginesSyncable[];
 extern const char kLanguageEnabledExtensionImes[];
-extern const char kLanguageEnabledExtensionImesSyncable[];
-extern const char kLanguageShouldMergeInputMethods[];
 extern const char kLanguageRemapCapsLockKeyTo[];
 extern const char kLanguageRemapSearchKeyTo[];
 extern const char kLanguageRemapControlKeyTo[];