// Copyright (c) 2012 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_manager_impl.h"

#include <algorithm>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "chrome/browser/chromeos/input_method/mock_candidate_window_controller.h"
#include "chromeos/ime/extension_ime_util.h"
#include "chromeos/ime/fake_input_method_delegate.h"
#include "chromeos/ime/mock_component_extension_ime_manager_delegate.h"
#include "chromeos/ime/mock_xkeyboard.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/ime/chromeos/mock_ime_engine_handler.h"
#include "ui/events/keycodes/keyboard_codes.h"

namespace chromeos {

namespace input_method {
namespace {

const char nacl_mozc_us_id[] =
    "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_us";
const char nacl_mozc_jp_id[] =
    "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_jp";

// Returns true if |descriptors| contain |target|.
bool Contain(const InputMethodDescriptors& descriptors,
             const InputMethodDescriptor& target) {
  for (size_t i = 0; i < descriptors.size(); ++i) {
    if (descriptors[i].id() == target.id())
      return true;
  }
  return false;
}

class InputMethodManagerImplTest :  public testing::Test {
 public:
  InputMethodManagerImplTest()
      : delegate_(NULL),
        candidate_window_controller_(NULL),
        xkeyboard_(NULL) {
  }
  virtual ~InputMethodManagerImplTest() {}

  virtual void SetUp() OVERRIDE {
    delegate_ = new FakeInputMethodDelegate();
    manager_.reset(new InputMethodManagerImpl(
        scoped_ptr<InputMethodDelegate>(delegate_)));
    candidate_window_controller_ = new MockCandidateWindowController;
    manager_->SetCandidateWindowControllerForTesting(
        candidate_window_controller_);
    xkeyboard_ = new MockXKeyboard;
    manager_->SetXKeyboardForTesting(xkeyboard_);
    mock_engine_handler_.reset(new MockIMEEngineHandler());
    IBusBridge::Initialize();
    IBusBridge::Get()->SetEngineHandler(mock_engine_handler_.get());

    ime_list_.clear();

    ComponentExtensionIME ext1;
    ext1.id = "fpfbhcjppmaeaijcidgiibchfbnhbelj";
    ext1.description = "ext1_description";
    ext1.path = base::FilePath("ext1_file_path");

    ComponentExtensionEngine ext1_engine1;
    ext1_engine1.engine_id = "nacl_mozc_us";
    ext1_engine1.display_name = "ext1_engine_1_display_name";
    ext1_engine1.language_codes.push_back("ja");
    ext1_engine1.layouts.push_back("us");
    ext1.engines.push_back(ext1_engine1);

    ComponentExtensionEngine ext1_engine2;
    ext1_engine2.engine_id = "nacl_mozc_jp";
    ext1_engine2.display_name = "ext1_engine_1_display_name";
    ext1_engine2.language_codes.push_back("ja");
    ext1_engine2.layouts.push_back("jp");
    ext1.engines.push_back(ext1_engine2);

    ime_list_.push_back(ext1);

    ComponentExtensionIME ext2;
    ext2.id = "nmblnjkfdkabgdofidlkienfnnbjhnab";
    ext2.description = "ext2_description";
    ext2.path = base::FilePath("ext2_file_path");

    ComponentExtensionEngine ext2_engine1;
    ext2_engine1.engine_id = "ext2_engine1_engine_id";
    ext2_engine1.display_name = "ext2_engine_1_display_name";
    ext2_engine1.language_codes.push_back("en");
    ext2_engine1.layouts.push_back("us");
    ext2.engines.push_back(ext2_engine1);

    ComponentExtensionEngine ext2_engine2;
    ext2_engine2.engine_id = "ext2_engine2_engine_id";
    ext2_engine2.display_name = "ext2_engine_2_display_name";
    ext2_engine2.language_codes.push_back("en");
    ext2_engine2.layouts.push_back("us(dvorak)");
    ext2.engines.push_back(ext2_engine2);

    ime_list_.push_back(ext2);
  }

  virtual void TearDown() OVERRIDE {
    delegate_ = NULL;
    candidate_window_controller_ = NULL;
    xkeyboard_ = NULL;
    manager_.reset();
    IBusBridge::Get()->SetEngineHandler(NULL);
    IBusBridge::Shutdown();
  }

 protected:
  // Helper function to initialize component extension stuff for testing.
  void InitComponentExtension() {
    mock_delegate_ = new MockComponentExtIMEManagerDelegate();
    mock_delegate_->set_ime_list(ime_list_);
    scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(mock_delegate_);
    manager_->InitializeComponentExtensionForTesting(delegate.Pass());
  }

  scoped_ptr<InputMethodManagerImpl> manager_;
  FakeInputMethodDelegate* delegate_;
  MockCandidateWindowController* candidate_window_controller_;
  scoped_ptr<MockIMEEngineHandler> mock_engine_handler_;
  MockXKeyboard* xkeyboard_;
  base::MessageLoop message_loop_;
  MockComponentExtIMEManagerDelegate* mock_delegate_;
  std::vector<ComponentExtensionIME> ime_list_;

 private:
  DISALLOW_COPY_AND_ASSIGN(InputMethodManagerImplTest);
};

class TestObserver : public InputMethodManager::Observer {
 public:
  TestObserver()
      : input_method_changed_count_(0),
        input_method_property_changed_count_(0),
        last_show_message_(false) {
  }
  virtual ~TestObserver() {}

  virtual void InputMethodChanged(InputMethodManager* manager,
                                  bool show_message) OVERRIDE {
    ++input_method_changed_count_;
    last_show_message_ = show_message;
  }
  virtual void InputMethodPropertyChanged(
      InputMethodManager* manager) OVERRIDE {
    ++input_method_property_changed_count_;
  }

  int input_method_changed_count_;
  int input_method_property_changed_count_;
  bool last_show_message_;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

class TestCandidateWindowObserver
    : public InputMethodManager::CandidateWindowObserver {
 public:
  TestCandidateWindowObserver()
      : candidate_window_opened_count_(0),
        candidate_window_closed_count_(0) {
  }
  virtual ~TestCandidateWindowObserver() {}

  virtual void CandidateWindowOpened(InputMethodManager* manager) OVERRIDE {
    ++candidate_window_opened_count_;
  }
  virtual void CandidateWindowClosed(InputMethodManager* manager) OVERRIDE {
    ++candidate_window_closed_count_;
  }

  int candidate_window_opened_count_;
  int candidate_window_closed_count_;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestCandidateWindowObserver);
};

}  // namespace

TEST_F(InputMethodManagerImplTest, TestGetXKeyboard) {
  EXPECT_TRUE(manager_->GetXKeyboard());
  EXPECT_EQ(xkeyboard_, manager_->GetXKeyboard());
}

TEST_F(InputMethodManagerImplTest, TestCandidateWindowObserver) {
  TestCandidateWindowObserver observer;
  candidate_window_controller_->NotifyCandidateWindowOpened();  // nop
  candidate_window_controller_->NotifyCandidateWindowClosed();  // nop
  manager_->AddCandidateWindowObserver(&observer);
  candidate_window_controller_->NotifyCandidateWindowOpened();
  EXPECT_EQ(1, observer.candidate_window_opened_count_);
  candidate_window_controller_->NotifyCandidateWindowClosed();
  EXPECT_EQ(1, observer.candidate_window_closed_count_);
  candidate_window_controller_->NotifyCandidateWindowOpened();
  EXPECT_EQ(2, observer.candidate_window_opened_count_);
  candidate_window_controller_->NotifyCandidateWindowClosed();
  EXPECT_EQ(2, observer.candidate_window_closed_count_);
  manager_->RemoveCandidateWindowObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestObserver) {
  // For http://crbug.com/19655#c11 - (3). browser_state_monitor_unittest.cc is
  // also for the scenario.
  TestObserver observer;
  InitComponentExtension();
  manager_->AddObserver(&observer);
  EXPECT_EQ(0, observer.input_method_changed_count_);
  manager_->EnableLayouts("en-US", "xkb:us::eng");
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(1, observer.input_method_property_changed_count_);
  manager_->ChangeInputMethod("xkb:us:dvorak:eng");
  EXPECT_FALSE(observer.last_show_message_);
  EXPECT_EQ(2, observer.input_method_changed_count_);
  EXPECT_EQ(2, observer.input_method_property_changed_count_);
  manager_->ChangeInputMethod("xkb:us:dvorak:eng");
  EXPECT_FALSE(observer.last_show_message_);

  // The observer is always notified even when the same input method ID is
  // passed to ChangeInputMethod() more than twice.
  // TODO(komatsu): Revisit if this is neccessary.
  EXPECT_EQ(3, observer.input_method_changed_count_);

  // If the same input method ID is passed, PropertyChanged() is not
  // notified.
  EXPECT_EQ(2, observer.input_method_property_changed_count_);

  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestGetSupportedInputMethods) {
  InitComponentExtension();
  scoped_ptr<InputMethodDescriptors> methods(
      manager_->GetSupportedInputMethods());
  ASSERT_TRUE(methods.get());
  // Try to find random 4-5 layuts and IMEs to make sure the returned list is
  // correct.
  const InputMethodDescriptor* id_to_find =
      manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId(
          nacl_mozc_us_id);
  id_to_find = manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId(
      "xkb:us::eng");
  EXPECT_TRUE(Contain(*methods.get(), *id_to_find));
  id_to_find = manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId(
      "xkb:us:dvorak:eng");
  EXPECT_TRUE(Contain(*methods.get(), *id_to_find));
  id_to_find = manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId(
      "xkb:fr::fra");
  EXPECT_TRUE(Contain(*methods.get(), *id_to_find));
}

TEST_F(InputMethodManagerImplTest, TestEnableLayouts) {
  // Currently 5 keyboard layouts are supported for en-US, and 1 for ja. See
  // ibus_input_method.txt.
  InitComponentExtension();
  manager_->EnableLayouts("en-US", "");
  EXPECT_EQ(5U, manager_->GetNumActiveInputMethods());
  for (size_t i = 0; i < manager_->GetActiveInputMethodIds().size(); ++i)
    LOG(ERROR) << manager_->GetActiveInputMethodIds().at(i);

  // For http://crbug.com/19655#c11 - (5)
  // The hardware keyboard layout "xkb:us::eng" is always active, hence 2U.
  manager_->EnableLayouts("ja", "");  // Japanese
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
}

TEST_F(InputMethodManagerImplTest, TestEnableLayoutsNonUsHardwareKeyboard) {
  // The physical layout is French.
  delegate_->set_hardware_keyboard_layout("xkb:fr::fra");
  manager_->EnableLayouts("en-US", "");
  EXPECT_EQ(6U, manager_->GetNumActiveInputMethods());  // 5 + French
  // The physical layout is Japanese.
  delegate_->set_hardware_keyboard_layout("xkb:jp::jpn");
  manager_->EnableLayouts("ja", "");
  // "xkb:us::eng" is not needed, hence 1.
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
}

TEST_F(InputMethodManagerImplTest, TestActiveInputMethods) {
  manager_->EnableLayouts("ja", "");  // Japanese
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  scoped_ptr<InputMethodDescriptors> methods(
      manager_->GetActiveInputMethods());
  ASSERT_TRUE(methods.get());
  EXPECT_EQ(2U, methods->size());
  const InputMethodDescriptor* id_to_find =
      manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId(
          "xkb:us::eng");
  EXPECT_TRUE(Contain(*methods.get(), *id_to_find));
  id_to_find = manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId(
      "xkb:jp::jpn");
  EXPECT_TRUE(Contain(*methods.get(), *id_to_find));
}

TEST_F(InputMethodManagerImplTest, TestEnableTwoLayouts) {
  // For http://crbug.com/19655#c11 - (8), step 6.
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us:dvorak:eng");
  ids.push_back("xkb:us:colemak:eng");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  // Since all the IDs added avobe are keyboard layouts, Start() should not be
  // called.
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  // Disable Dvorak.
  ids.erase(ids.begin());
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(2, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0],  // colemak
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_);
  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestEnableThreeLayouts) {
  // For http://crbug.com/19655#c11 - (9).
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us::eng");
  ids.push_back("xkb:us:dvorak:eng");
  ids.push_back("xkb:us:colemak:eng");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(3U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  // Switch to Dvorak.
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(2, observer.input_method_changed_count_);
  EXPECT_EQ(ids[1], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  // Disable Dvorak.
  ids.erase(ids.begin() + 1);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(3, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0],  // US Qwerty
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme) {
  // For http://crbug.com/19655#c11 - (10).
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us:dvorak:eng");
  ids.push_back(nacl_mozc_us_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  // Switch to Mozc
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(2, observer.input_method_changed_count_);
  EXPECT_EQ(ids[1], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  // Disable Mozc.
  ids.erase(ids.begin() + 1);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
}

TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme2) {
  // For http://crbug.com/19655#c11 - (11).
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us:dvorak:eng");
  ids.push_back(nacl_mozc_us_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);

  // Disable Dvorak.
  ids.erase(ids.begin());
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(ids[0],  // Mozc
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestEnableImes) {
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabext2_engine1_engine_id");
  ids.push_back("mozc-dv");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestEnableUnknownIds) {
  TestObserver observer;
  manager_->AddObserver(&observer);
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:tl::tlh");  // Klingon, which is not supported.
  ids.push_back("unknown-super-cool-ime");
  EXPECT_FALSE(manager_->EnableInputMethods(ids));

  // TODO(yusukes): Should we fall back to the hardware keyboard layout in this
  // case?
  EXPECT_EQ(0, observer.input_method_changed_count_);

  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestEnableLayoutsThenLock) {
  // For http://crbug.com/19655#c11 - (14).
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us::eng");
  ids.push_back("xkb:us:dvorak:eng");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);

  // Switch to Dvorak.
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(2, observer.input_method_changed_count_);
  EXPECT_EQ(ids[1], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);

  // Lock screen
  manager_->SetState(InputMethodManager::STATE_LOCK_SCREEN);
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(ids[1],  // still Dvorak
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  // Switch back to Qwerty.
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);

  // Unlock screen. The original state, Dvorak, is restored.
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(ids[1], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);

  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, SwithchInputMethodTest) {
  // For http://crbug.com/19655#c11 - (15).
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us:dvorak:eng");
  ids.push_back("_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabext2_engine2_engine_id");
  ids.push_back("_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabext2_engine1_engine_id");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(3U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);

  // Switch to Mozc.
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(2, observer.input_method_changed_count_);
  EXPECT_EQ(ids[1], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);

  // Lock screen
  manager_->SetState(InputMethodManager::STATE_LOCK_SCREEN);
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());  // Qwerty+Dvorak.
  EXPECT_EQ("xkb:us:dvorak:eng",
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ("xkb:us::eng",  // The hardware keyboard layout.
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);

  // Unlock screen. The original state, pinyin-dv, is restored.
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  EXPECT_EQ(3U, manager_->GetNumActiveInputMethods());  // Dvorak and 2 IMEs.
  EXPECT_EQ(ids[1], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);

  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestXkbSetting) {
  // For http://crbug.com/19655#c11 - (8), step 7-11.
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us:dvorak:eng");
  ids.push_back("xkb:us:colemak:eng");
  ids.push_back(nacl_mozc_jp_id);
  ids.push_back(nacl_mozc_us_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(4U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(1, xkeyboard_->set_current_keyboard_layout_by_name_count_);
  // See input_methods.txt for an expected XKB layout name.
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(2, xkeyboard_->set_current_keyboard_layout_by_name_count_);
  EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(3, xkeyboard_->set_current_keyboard_layout_by_name_count_);
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(4, xkeyboard_->set_current_keyboard_layout_by_name_count_);
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(5, xkeyboard_->set_current_keyboard_layout_by_name_count_);
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  // Disable Dvorak.
  ids.erase(ids.begin());
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(3U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(6, xkeyboard_->set_current_keyboard_layout_by_name_count_);
  EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_);
}

TEST_F(InputMethodManagerImplTest, TestActivateInputMethodProperty) {
  const std::string kKey = "key";
  InputMethodPropertyList property_list;
  property_list.push_back(InputMethodProperty(kKey, "label", false, false));
  manager_->SetCurrentInputMethodProperties(property_list);

  manager_->ActivateInputMethodProperty(kKey);
  EXPECT_EQ(kKey, mock_engine_handler_->last_activated_property());

  // Key2 is not registered, so activated property should not be changed.
  manager_->ActivateInputMethodProperty("key2");
  EXPECT_EQ(kKey, mock_engine_handler_->last_activated_property());
}

TEST_F(InputMethodManagerImplTest, TestGetCurrentInputMethodProperties) {
  InitComponentExtension();
  EXPECT_TRUE(manager_->GetCurrentInputMethodProperties().empty());

  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us::eng");
  ids.push_back(nacl_mozc_us_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_TRUE(manager_->GetCurrentInputMethodProperties().empty());
  manager_->ChangeInputMethod(nacl_mozc_us_id);

  InputMethodPropertyList current_property_list;
  current_property_list.push_back(InputMethodProperty("key",
                                                      "label",
                                                      false,
                                                      false));
  manager_->SetCurrentInputMethodProperties(current_property_list);

  ASSERT_EQ(1U, manager_->GetCurrentInputMethodProperties().size());
  EXPECT_EQ("key", manager_->GetCurrentInputMethodProperties().at(0).key);

  manager_->ChangeInputMethod("xkb:us::eng");
  EXPECT_TRUE(manager_->GetCurrentInputMethodProperties().empty());
}

TEST_F(InputMethodManagerImplTest, TestGetCurrentInputMethodPropertiesTwoImes) {
  InitComponentExtension();
  EXPECT_TRUE(manager_->GetCurrentInputMethodProperties().empty());

  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back(nacl_mozc_us_id);  // Japanese
  ids.push_back("_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabext2_engine1_engine_id");  // T-Chinese
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_TRUE(manager_->GetCurrentInputMethodProperties().empty());

  InputMethodPropertyList current_property_list;
  current_property_list.push_back(InputMethodProperty("key-mozc",
                                                      "label",
                                                      false,
                                                      false));
  manager_->SetCurrentInputMethodProperties(current_property_list);

  ASSERT_EQ(1U, manager_->GetCurrentInputMethodProperties().size());
  EXPECT_EQ("key-mozc", manager_->GetCurrentInputMethodProperties().at(0).key);

  manager_->ChangeInputMethod("_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabext2_engine1_engine_id");
  // Since the IME is changed, the property for mozc Japanese should be hidden.
  EXPECT_TRUE(manager_->GetCurrentInputMethodProperties().empty());

  // Asynchronous property update signal from mozc-chewing.
  current_property_list.clear();
  current_property_list.push_back(InputMethodProperty("key-chewing",
                                                      "label",
                                                      false,
                                                      false));
  manager_->SetCurrentInputMethodProperties(current_property_list);
  ASSERT_EQ(1U, manager_->GetCurrentInputMethodProperties().size());
  EXPECT_EQ("key-chewing",
            manager_->GetCurrentInputMethodProperties().at(0).key);
}

TEST_F(InputMethodManagerImplTest, TestNextInputMethod) {
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  // For http://crbug.com/19655#c11 - (1)
  manager_->EnableLayouts("en-US", "xkb:us::eng");
  EXPECT_EQ(5U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:intl:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(intl)", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:altgr-intl:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(altgr-intl)", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:dvorak:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:colemak:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_);
  manager_->SwitchToNextInputMethod();
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);

  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestPreviousInputMethod) {
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();

  ui::Accelerator keydown_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
  keydown_accelerator.set_type(ui::ET_KEY_PRESSED);
  ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
  keyup_accelerator.set_type(ui::ET_KEY_RELEASED);

  manager_->EnableLayouts("en-US", "xkb:us::eng");
  EXPECT_EQ(5U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToNextInputMethod());
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:intl:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(intl)", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator));
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator));
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator));
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator));
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:intl:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(intl)", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator));
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator));
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToNextInputMethod());
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:intl:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(intl)", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToNextInputMethod());
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:altgr-intl:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(altgr-intl)", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator));
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator));
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:intl:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(intl)", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator));
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator));
  EXPECT_TRUE(observer.last_show_message_);
  EXPECT_EQ("xkb:us:altgr-intl:eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(altgr-intl)", xkeyboard_->last_layout_);

  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest,
       TestSwitchToPreviousInputMethodForOneActiveInputMethod) {
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();

  ui::Accelerator keydown_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
  keydown_accelerator.set_type(ui::ET_KEY_PRESSED);
  ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
  keyup_accelerator.set_type(ui::ET_KEY_RELEASED);

  std::vector<std::string> ids;
  ids.push_back("xkb:us:dvorak:eng");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());

  // Ctrl+Space accelerator should not be consumed if there is only one active
  // input method.
  EXPECT_FALSE(manager_->SwitchToPreviousInputMethod(keydown_accelerator));
  EXPECT_FALSE(manager_->SwitchToPreviousInputMethod(keyup_accelerator));

  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithUsLayouts) {
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->EnableLayouts("en-US", "xkb:us::eng");
  EXPECT_EQ(5U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);

  // Henkan, Muhenkan, ZenkakuHankaku should be ignored when no Japanese IMEs
  // and keyboards are enabled.
  EXPECT_FALSE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_CONVERT, ui::EF_NONE)));
  EXPECT_FALSE(observer.last_show_message_);
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_FALSE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_NONCONVERT, ui::EF_NONE)));
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_FALSE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE)));
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_FALSE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE)));
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);

  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpLayout) {
  // Enable "xkb:jp::jpn" and press Muhenkan/ZenkakuHankaku.
  InitComponentExtension();

  ui::Accelerator keydown_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
  keydown_accelerator.set_type(ui::ET_KEY_PRESSED);
  ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
  keyup_accelerator.set_type(ui::ET_KEY_RELEASED);

  manager_->EnableLayouts("ja", "xkb:us::eng");
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_NONCONVERT, ui::EF_NONE)));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator));
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator));
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE)));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator));
  EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator));
  EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE)));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
}

TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpIme) {
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:jp::jpn");
  ids.push_back(nacl_mozc_jp_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE)));
  EXPECT_EQ(nacl_mozc_jp_id, manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE)));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_CONVERT, ui::EF_NONE)));
  EXPECT_EQ(nacl_mozc_jp_id, manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_CONVERT, ui::EF_NONE)));
  EXPECT_EQ(nacl_mozc_jp_id, manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_NONCONVERT, ui::EF_NONE)));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_NONCONVERT, ui::EF_NONE)));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);

  // Add Dvorak.
  ids.push_back("xkb:us:dvorak:eng");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE)));
  EXPECT_EQ(nacl_mozc_jp_id, manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
  EXPECT_TRUE(manager_->SwitchInputMethod(
      ui::Accelerator(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE)));
  EXPECT_EQ("xkb:jp::jpn", manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("jp", xkeyboard_->last_layout_);
}

TEST_F(InputMethodManagerImplTest, TestAddRemoveExtensionInputMethods) {
  TestObserver observer;
  manager_->AddObserver(&observer);
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us:dvorak:eng");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0],
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);

  // Add two Extension IMEs.
  std::vector<std::string> layouts;
  layouts.push_back("us");
  std::vector<std::string> languages;
  languages.push_back("en-US");
  manager_->AddInputMethodExtension(
      extension_ime_util::GetInputMethodID("deadbeef", "engine_id"),
      "deadbeef input method",
      layouts,
      languages,
      GURL(),
      GURL(),
      NULL);

  // Extension IMEs are not enabled by default.
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());

  std::vector<std::string> extension_ime_ids;
  extension_ime_ids.push_back(
      extension_ime_util::GetInputMethodID("deadbeef", "engine_id"));
  manager_->SetEnabledExtensionImes(&extension_ime_ids);
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());

  {
    scoped_ptr<InputMethodDescriptors> methods(
        manager_->GetActiveInputMethods());
    ASSERT_EQ(2U, methods->size());
    EXPECT_EQ(extension_ime_util::GetInputMethodID("deadbeef", "engine_id"),
              // Ext IMEs should be at the end of the list.
              methods->at(1).id());
  }
  manager_->AddInputMethodExtension(
      extension_ime_util::GetInputMethodID("cafebabe", "engine_id"),
      "cafebabe input method",
      layouts,
      languages,
      GURL(),
      GURL(),
      NULL);
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());

  extension_ime_ids.push_back(
      extension_ime_util::GetInputMethodID("cafebabe", "engine_id"));
  manager_->SetEnabledExtensionImes(&extension_ime_ids);
  EXPECT_EQ(3U, manager_->GetNumActiveInputMethods());
  {
    scoped_ptr<InputMethodDescriptors> methods(
        manager_->GetActiveInputMethods());
    ASSERT_EQ(3U, methods->size());
    EXPECT_EQ(extension_ime_util::GetInputMethodID("deadbeef", "engine_id"),
              // Ext IMEs should be at the end of the list.
              methods->at(1).id());
  }

  // Remove them.
  manager_->RemoveInputMethodExtension(
      extension_ime_util::GetInputMethodID("deadbeef", "engine_id"));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  manager_->RemoveInputMethodExtension(
      extension_ime_util::GetInputMethodID("cafebabe", "engine_id"));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
}

TEST_F(InputMethodManagerImplTest, TestAddExtensionInputThenLockScreen) {
  TestObserver observer;
  InitComponentExtension();
  manager_->AddObserver(&observer);
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back("xkb:us::eng");
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(1, observer.input_method_changed_count_);
  EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);

  // Add an Extension IME.
  std::vector<std::string> layouts;
  layouts.push_back("us(dvorak)");
  std::vector<std::string> languages;
  languages.push_back("en-US");
  manager_->AddInputMethodExtension(
      extension_ime_util::GetInputMethodID("deadbeef", "engine_id"),
      "deadbeef input method",
      layouts,
      languages,
      GURL(),
      GURL(),
      NULL);
  // Extension IME is not enabled by default.
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(1, observer.input_method_changed_count_);

  std::vector<std::string> extension_ime_ids;
  extension_ime_ids.push_back(
      extension_ime_util::GetInputMethodID("deadbeef", "engine_id"));
  manager_->SetEnabledExtensionImes(&extension_ime_ids);
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());

  // Switch to the IME.
  manager_->SwitchToNextInputMethod();
  EXPECT_EQ(3, observer.input_method_changed_count_);
  EXPECT_EQ(extension_ime_util::GetInputMethodID("deadbeef", "engine_id"),
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);

  // Lock the screen. This is for crosbug.com/27049.
  manager_->SetState(InputMethodManager::STATE_LOCK_SCREEN);
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());  // Qwerty. No Ext. IME
  EXPECT_EQ("xkb:us::eng",
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us", xkeyboard_->last_layout_);

  // Unlock the screen.
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(extension_ime_util::GetInputMethodID("deadbeef", "engine_id"),
            manager_->GetCurrentInputMethod().id());
  EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_);
  {
    // This is for crosbug.com/27052.
    scoped_ptr<InputMethodDescriptors> methods(
        manager_->GetActiveInputMethods());
    ASSERT_EQ(2U, methods->size());
    EXPECT_EQ(extension_ime_util::GetInputMethodID("deadbeef", "engine_id"),
              // Ext. IMEs should be at the end of the list.
              methods->at(1).id());
  }
  manager_->RemoveObserver(&observer);
}

TEST_F(InputMethodManagerImplTest,
       ChangeInputMethodBeforeComponentExtensionInitialization_OneIME) {
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back(nacl_mozc_us_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  manager_->ChangeInputMethod(nacl_mozc_us_id);

  InitComponentExtension();
  EXPECT_EQ(nacl_mozc_us_id, manager_->GetCurrentInputMethod().id());
}

TEST_F(InputMethodManagerImplTest,
       ChangeInputMethodBeforeComponentExtensionInitialization_TwoIME) {
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  std::vector<std::string> ids;
  ids.push_back(nacl_mozc_us_id);
  ids.push_back(nacl_mozc_jp_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  manager_->ChangeInputMethod(nacl_mozc_us_id);
  manager_->ChangeInputMethod(nacl_mozc_jp_id);

  InitComponentExtension();
  EXPECT_EQ(nacl_mozc_jp_id, manager_->GetCurrentInputMethod().id());
}

TEST_F(InputMethodManagerImplTest,
       ChangeInputMethodBeforeComponentExtensionInitialization_CompOneIME) {
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  const std::string ext_id = extension_ime_util::GetComponentInputMethodID(
      ime_list_[0].id,
      ime_list_[0].engines[0].engine_id);
  std::vector<std::string> ids;
  ids.push_back(ext_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  manager_->ChangeInputMethod(ext_id);

  InitComponentExtension();
  EXPECT_EQ(ext_id, manager_->GetCurrentInputMethod().id());
}

TEST_F(InputMethodManagerImplTest,
       ChangeInputMethodBeforeComponentExtensionInitialization_CompTwoIME) {
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  const std::string ext_id1 = extension_ime_util::GetComponentInputMethodID(
      ime_list_[0].id,
      ime_list_[0].engines[0].engine_id);
  const std::string ext_id2 = extension_ime_util::GetComponentInputMethodID(
      ime_list_[1].id,
      ime_list_[1].engines[0].engine_id);
  std::vector<std::string> ids;
  ids.push_back(ext_id1);
  ids.push_back(ext_id2);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  manager_->ChangeInputMethod(ext_id1);
  manager_->ChangeInputMethod(ext_id2);

  InitComponentExtension();
  EXPECT_EQ(ext_id2, manager_->GetCurrentInputMethod().id());
}

TEST_F(InputMethodManagerImplTest,
       ChangeInputMethod_ComponenteExtensionOneIME) {
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  const std::string ext_id = extension_ime_util::GetComponentInputMethodID(
      ime_list_[0].id,
      ime_list_[0].engines[0].engine_id);
  std::vector<std::string> ids;
  ids.push_back(ext_id);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(1U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(ext_id, manager_->GetCurrentInputMethod().id());
}

TEST_F(InputMethodManagerImplTest,
       ChangeInputMethod_ComponenteExtensionTwoIME) {
  InitComponentExtension();
  manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN);
  const std::string ext_id1 = extension_ime_util::GetComponentInputMethodID(
      ime_list_[0].id,
      ime_list_[0].engines[0].engine_id);
  const std::string ext_id2 = extension_ime_util::GetComponentInputMethodID(
      ime_list_[1].id,
      ime_list_[1].engines[0].engine_id);
  std::vector<std::string> ids;
  ids.push_back(ext_id1);
  ids.push_back(ext_id2);
  EXPECT_TRUE(manager_->EnableInputMethods(ids));
  EXPECT_EQ(2U, manager_->GetNumActiveInputMethods());
  EXPECT_EQ(ext_id1, manager_->GetCurrentInputMethod().id());
  manager_->ChangeInputMethod(ext_id2);
  EXPECT_EQ(ext_id2, manager_->GetCurrentInputMethod().id());
}

}  // namespace input_method
}  // namespace chromeos
