1 // Copyright 2014 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.
5 #include "base/logging.h"
6 #include "base/metrics/histogram.h"
7 #include "base/metrics/histogram_samples.h"
8 #include "base/metrics/statistics_recorder.h"
9 #include "base/test/histogram_tester.h"
10 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
11 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
12 #include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
13 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
14 #include "chromeos/ime/extension_ime_util.h"
15 #include "chromeos/ime/mock_component_extension_ime_manager_delegate.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
21 namespace input_method
{
24 const char kTestExtensionId
[] = "mppnpdlheglhdfmldimlhpnegondlapf";
25 const char kTestExtensionId2
[] = "dmpipdbjkoajgdeppkffbjhngfckdloi";
26 const char kTestImeComponentId
[] = "test_engine_id";
36 void InitInputMethod() {
37 ComponentExtensionIMEManager
* comp_ime_manager
=
38 new ComponentExtensionIMEManager
;
39 MockComponentExtIMEManagerDelegate
* delegate
=
40 new MockComponentExtIMEManagerDelegate
;
42 ComponentExtensionIME ext1
;
43 ext1
.id
= kTestExtensionId
;
45 ComponentExtensionEngine ext1_engine1
;
46 ext1_engine1
.engine_id
= kTestImeComponentId
;
47 ext1_engine1
.language_codes
.push_back("en-US");
48 ext1_engine1
.layouts
.push_back("us");
49 ext1
.engines
.push_back(ext1_engine1
);
51 std::vector
<ComponentExtensionIME
> ime_list
;
52 ime_list
.push_back(ext1
);
53 delegate
->set_ime_list(ime_list
);
54 comp_ime_manager
->Initialize(
55 scoped_ptr
<ComponentExtensionIMEManagerDelegate
>(delegate
).Pass());
57 MockInputMethodManager
* manager
= new MockInputMethodManager
;
58 manager
->SetComponentExtensionIMEManager(
59 scoped_ptr
<ComponentExtensionIMEManager
>(comp_ime_manager
).Pass());
60 InitializeForTesting(manager
);
63 class TestObserver
: public InputMethodEngineInterface::Observer
{
65 TestObserver() : calls_bitmap_(NONE
) {}
66 virtual ~TestObserver() {}
68 virtual void OnActivate(const std::string
& engine_id
) override
{
69 calls_bitmap_
|= ACTIVATE
;
71 virtual void OnDeactivated(const std::string
& engine_id
) override
{
72 calls_bitmap_
|= DEACTIVATED
;
75 const InputMethodEngineInterface::InputContext
& context
) override
{
76 calls_bitmap_
|= ONFOCUS
;
78 virtual void OnBlur(int context_id
) override
{
79 calls_bitmap_
|= ONBLUR
;
81 virtual void OnKeyEvent(
82 const std::string
& engine_id
,
83 const InputMethodEngineInterface::KeyboardEvent
& event
,
84 input_method::KeyEventHandle
* key_data
) override
{}
85 virtual void OnInputContextUpdate(
86 const InputMethodEngineInterface::InputContext
& context
) override
{}
87 virtual void OnCandidateClicked(
88 const std::string
& engine_id
,
90 InputMethodEngineInterface::MouseButtonEvent button
) override
{}
91 virtual void OnMenuItemActivated(
92 const std::string
& engine_id
,
93 const std::string
& menu_id
) override
{}
94 virtual void OnSurroundingTextChanged(
95 const std::string
& engine_id
,
96 const std::string
& text
,
98 int anchor_pos
) override
{}
99 virtual void OnReset(const std::string
& engine_id
) override
{}
101 unsigned char GetCallsBitmapAndReset() {
102 unsigned char ret
= calls_bitmap_
;
103 calls_bitmap_
= NONE
;
108 unsigned char calls_bitmap_
;
110 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
113 class InputMethodEngineTest
: public testing::Test
{
115 InputMethodEngineTest() : observer_(NULL
), input_view_("inputview.html") {
116 languages_
.push_back("en-US");
117 layouts_
.push_back("us");
119 IMEBridge::Initialize();
120 mock_ime_input_context_handler_
.reset(new MockIMEInputContextHandler());
121 IMEBridge::Get()->SetInputContextHandler(
122 mock_ime_input_context_handler_
.get());
124 virtual ~InputMethodEngineTest() {
125 IMEBridge::Get()->SetInputContextHandler(NULL
);
131 void CreateEngine(bool whitelisted
) {
132 engine_
.reset(new InputMethodEngine());
133 observer_
= new TestObserver();
134 scoped_ptr
<InputMethodEngineInterface::Observer
> observer_ptr(observer_
);
135 engine_
->Initialize(observer_ptr
.Pass(),
136 whitelisted
? kTestExtensionId
: kTestExtensionId2
);
139 void FocusIn(ui::TextInputType input_type
) {
140 IMEEngineHandlerInterface::InputContext
input_context(
141 input_type
, ui::TEXT_INPUT_MODE_DEFAULT
);
142 engine_
->FocusIn(input_context
);
143 IMEBridge::Get()->SetCurrentTextInputType(input_type
);
146 scoped_ptr
<InputMethodEngine
> engine_
;
148 TestObserver
* observer_
;
149 std::vector
<std::string
> languages_
;
150 std::vector
<std::string
> layouts_
;
154 scoped_ptr
<MockIMEInputContextHandler
> mock_ime_input_context_handler_
;
157 DISALLOW_COPY_AND_ASSIGN(InputMethodEngineTest
);
162 TEST_F(InputMethodEngineTest
, TestSwitching
) {
164 // Enable/disable with focus.
165 FocusIn(ui::TEXT_INPUT_TYPE_URL
);
166 EXPECT_EQ(NONE
, observer_
->GetCallsBitmapAndReset());
167 engine_
->Enable(kTestImeComponentId
);
168 EXPECT_EQ(ACTIVATE
| ONFOCUS
, observer_
->GetCallsBitmapAndReset());
170 EXPECT_EQ(DEACTIVATED
, observer_
->GetCallsBitmapAndReset());
171 // Enable/disable without focus.
173 EXPECT_EQ(NONE
, observer_
->GetCallsBitmapAndReset());
174 engine_
->Enable(kTestImeComponentId
);
175 EXPECT_EQ(ACTIVATE
| ONFOCUS
, observer_
->GetCallsBitmapAndReset());
177 EXPECT_EQ(DEACTIVATED
, observer_
->GetCallsBitmapAndReset());
178 // Focus change when enabled.
179 engine_
->Enable(kTestImeComponentId
);
180 EXPECT_EQ(ACTIVATE
| ONFOCUS
, observer_
->GetCallsBitmapAndReset());
182 EXPECT_EQ(ONBLUR
, observer_
->GetCallsBitmapAndReset());
183 // Focus change when disabled.
185 EXPECT_EQ(DEACTIVATED
, observer_
->GetCallsBitmapAndReset());
186 FocusIn(ui::TEXT_INPUT_TYPE_TEXT
);
187 EXPECT_EQ(NONE
, observer_
->GetCallsBitmapAndReset());
189 EXPECT_EQ(NONE
, observer_
->GetCallsBitmapAndReset());
192 TEST_F(InputMethodEngineTest
, TestSwitching_Password_3rd_Party
) {
194 // Enable/disable with focus.
195 FocusIn(ui::TEXT_INPUT_TYPE_PASSWORD
);
196 EXPECT_EQ(NONE
, observer_
->GetCallsBitmapAndReset());
197 engine_
->Enable(kTestImeComponentId
);
198 EXPECT_EQ(ACTIVATE
| ONFOCUS
, observer_
->GetCallsBitmapAndReset());
200 EXPECT_EQ(DEACTIVATED
, observer_
->GetCallsBitmapAndReset());
201 // Focus change when enabled.
202 engine_
->Enable(kTestImeComponentId
);
203 EXPECT_EQ(ACTIVATE
| ONFOCUS
, observer_
->GetCallsBitmapAndReset());
205 EXPECT_EQ(ONBLUR
, observer_
->GetCallsBitmapAndReset());
206 FocusIn(ui::TEXT_INPUT_TYPE_PASSWORD
);
207 EXPECT_EQ(ONFOCUS
, observer_
->GetCallsBitmapAndReset());
209 EXPECT_EQ(DEACTIVATED
, observer_
->GetCallsBitmapAndReset());
212 TEST_F(InputMethodEngineTest
, TestSwitching_Password_Whitelisted
) {
214 // Enable/disable with focus.
215 FocusIn(ui::TEXT_INPUT_TYPE_PASSWORD
);
216 EXPECT_EQ(NONE
, observer_
->GetCallsBitmapAndReset());
217 engine_
->Enable(kTestImeComponentId
);
218 EXPECT_EQ(ACTIVATE
| ONFOCUS
, observer_
->GetCallsBitmapAndReset());
220 EXPECT_EQ(DEACTIVATED
, observer_
->GetCallsBitmapAndReset());
221 // Focus change when enabled.
222 engine_
->Enable(kTestImeComponentId
);
223 EXPECT_EQ(ACTIVATE
| ONFOCUS
, observer_
->GetCallsBitmapAndReset());
225 EXPECT_EQ(ONBLUR
, observer_
->GetCallsBitmapAndReset());
226 FocusIn(ui::TEXT_INPUT_TYPE_PASSWORD
);
227 EXPECT_EQ(ONFOCUS
, observer_
->GetCallsBitmapAndReset());
229 EXPECT_EQ(DEACTIVATED
, observer_
->GetCallsBitmapAndReset());
232 TEST_F(InputMethodEngineTest
, TestHistograms
) {
234 FocusIn(ui::TEXT_INPUT_TYPE_TEXT
);
235 engine_
->Enable(kTestImeComponentId
);
236 std::vector
<InputMethodEngineInterface::SegmentInfo
> segments
;
237 engine_
->SetComposition(
238 engine_
->GetCotextIdForTesting(), "test", 0, 0, 0, segments
, NULL
);
240 base::HistogramTester histograms
;
241 engine_
->CommitText(1, "input", &error
);
242 engine_
->CommitText(1,
243 "\xE5\x85\xA5\xE5\x8A\x9B", // 2 UTF-8 characters
245 engine_
->CommitText(1, "input\xE5\x85\xA5\xE5\x8A\x9B", &error
);
246 histograms
.ExpectTotalCount("InputMethod.CommitLength", 3);
247 histograms
.ExpectBucketCount("InputMethod.CommitLength", 5, 1);
248 histograms
.ExpectBucketCount("InputMethod.CommitLength", 2, 1);
249 histograms
.ExpectBucketCount("InputMethod.CommitLength", 7, 1);
252 } // namespace input_method
253 } // namespace chromeos