1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/extension_apitest.h"
6
7#include "base/command_line.h"
8#include "base/strings/stringprintf.h"
9#include "chrome/browser/chrome_notification_types.h"
10#include "chrome/browser/chromeos/extensions/input_method_event_router.h"
11#include "chrome/browser/extensions/api/test/test_api.h"
12#include "chrome/common/chrome_switches.h"
13#include "chromeos/ime/input_method_manager.h"
14#include "content/public/browser/notification_observer.h"
15#include "content/public/browser/notification_registrar.h"
16#include "content/public/browser/notification_service.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19namespace {
20
21const char kLoginScreenUILanguage[] = "ru";
22const char kInitialInputMethodOnLoginScreen[] = "xkb:us::eng";
23const char kNewInputMethod[] = "ru::rus";
24const char kSetInputMethodMessage[] = "setInputMethod";
25const char kSetInputMethodDone[] = "done";
26
27// Class that listens for the JS message then changes input method and replies
28// back.
29class SetInputMethodListener : public content::NotificationObserver {
30 public:
31  // Creates listener, which should reply exactly |count_| times.
32  explicit SetInputMethodListener(int count) : count_(count) {
33    registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE,
34                   content::NotificationService::AllSources());
35    chromeos::input_method::InputMethodManager::Get()->
36        EnableLayouts(kLoginScreenUILanguage, kInitialInputMethodOnLoginScreen);
37  }
38
39  virtual ~SetInputMethodListener() {
40    EXPECT_EQ(0, count_);
41  }
42
43  // Implements the content::NotificationObserver interface.
44  virtual void Observe(int type,
45                       const content::NotificationSource& source,
46                       const content::NotificationDetails& details) OVERRIDE {
47    const std::string& content = *content::Details<std::string>(details).ptr();
48    const std::string expected_message =
49        base::StringPrintf("%s:%s", kSetInputMethodMessage, kNewInputMethod);
50    if (content == expected_message) {
51      chromeos::input_method::InputMethodManager::Get()->
52          ChangeInputMethod(base::StringPrintf("xkb:%s", kNewInputMethod));
53
54      extensions::TestSendMessageFunction* function =
55          content::Source<extensions::TestSendMessageFunction>(
56              source).ptr();
57      EXPECT_GT(count_--, 0);
58      function->Reply(kSetInputMethodDone);
59    }
60  }
61
62 private:
63  content::NotificationRegistrar registrar_;
64
65  int count_;
66};
67
68class ExtensionInputMethodApiTest : public ExtensionApiTest {
69  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
70    ExtensionApiTest::SetUpCommandLine(command_line);
71    command_line->AppendSwitchASCII(
72        switches::kWhitelistedExtensionID, "ilanclmaeigfpnmdlgelmhkpkegdioip");
73  }
74};
75
76}  // namespace
77
78IN_PROC_BROWSER_TEST_F(ExtensionInputMethodApiTest, Basic) {
79  // Two test, two calls. See JS code for more info.
80  SetInputMethodListener listener(2);
81
82  ASSERT_TRUE(RunExtensionTest("input_method")) << message_;
83}
84