Fix infinite recursion on hiding panel when created during fullscreen mode.
[chromium-blink-merge.git] / chrome / browser / chromeos / input_method / mode_indicator_browsertest.cc
blobb8bf3b4464cc3eb543a0c2c74d4751a0d5ec4127
1 // Copyright 2013 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 <algorithm>
7 #include "ash/shell.h"
8 #include "chrome/browser/chromeos/input_method/input_method_util.h"
9 #include "chrome/browser/chromeos/input_method/mode_indicator_controller.h"
10 #include "chrome/test/base/in_process_browser_test.h"
11 #include "chromeos/ime/component_extension_ime_manager.h"
12 #include "chromeos/ime/extension_ime_util.h"
13 #include "chromeos/ime/input_method_manager.h"
14 #include "chromeos/ime/input_method_whitelist.h"
15 #include "content/public/test/browser_test_utils.h"
16 #include "content/public/test/test_utils.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/base/ime/chromeos/ime_bridge.h"
19 #include "ui/base/ime/input_method_factory.h"
20 #include "ui/views/widget/widget.h"
21 #include "ui/views/widget/widget_observer.h"
23 namespace chromeos {
24 namespace input_method {
26 class ScopedModeIndicatorObserverForTesting :
27 public ModeIndicatorObserverInterface {
28 public:
29 ScopedModeIndicatorObserverForTesting()
30 : max_widget_list_size_(0) {
31 ModeIndicatorController::SetModeIndicatorObserverForTesting(this);
34 virtual ~ScopedModeIndicatorObserverForTesting() {
35 for (size_t i = 0; i < widget_list_.size(); ++i) {
36 widget_list_[i]->RemoveObserver(this);
38 ModeIndicatorController::SetModeIndicatorObserverForTesting(NULL);
41 gfx::Rect last_bounds() const {
42 return last_bounds_;
45 bool is_displayed() const {
46 return is_displayed_;
49 const std::vector<views::Widget*>& widget_list() const {
50 return widget_list_;
53 size_t widget_list_size() const {
54 return widget_list_.size();
57 size_t max_widget_list_size() const {
58 return max_widget_list_size_;
61 // ModeIndicatorObserverInterface override:
62 virtual void AddModeIndicatorWidget(views::Widget* widget) OVERRIDE {
63 widget_list_.push_back(widget);
64 max_widget_list_size_ =
65 std::max(max_widget_list_size_, widget_list_.size());
66 widget->AddObserver(this);
69 // views::WidgetObserver override:
70 virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE {
71 std::vector<views::Widget*>::iterator it =
72 std::find(widget_list_.begin(), widget_list_.end(), widget);
73 if (it != widget_list_.end())
74 widget_list_.erase(it);
77 // views::WidgetObserver override:
78 virtual void OnWidgetVisibilityChanged(views::Widget* widget,
79 bool visible) OVERRIDE {
80 last_bounds_ = widget->GetWindowBoundsInScreen();
81 is_displayed_ |= visible;
84 private:
85 bool is_displayed_;
86 gfx::Rect last_bounds_;
87 size_t max_widget_list_size_;
88 std::vector<views::Widget*> widget_list_;
91 class ModeIndicatorBrowserTest : public InProcessBrowserTest {
92 public:
93 ModeIndicatorBrowserTest()
94 : InProcessBrowserTest() {}
95 virtual ~ModeIndicatorBrowserTest() {}
97 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
98 ui::SetUpInputMethodFactoryForTesting();
101 void InitializeIMF() {
102 InputMethodManager::Get()
103 ->GetInputMethodUtil()
104 ->InitXkbInputMethodsForTesting();
105 // Make sure ComponentExtensionIMEManager is initialized.
106 // ComponentExtensionIMEManagerImpl::InitializeAsync posts
107 // ReadComponentExtensionsInfo to the FILE thread for the
108 // initialization. If it is never initialized for some reasons,
109 // the test is timed out and failed.
110 ComponentExtensionIMEManager* ceimm =
111 InputMethodManager::Get()->GetComponentExtensionIMEManager();
112 while (!ceimm->IsInitialized()) {
113 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
117 private:
118 DISALLOW_COPY_AND_ASSIGN(ModeIndicatorBrowserTest);
121 namespace {
122 // 43 is the designed size of the inner contents.
123 // This value corresponds with kMinSize defined in
124 // mode_indicator_delegate_view.cc.
125 const int kInnerSize = 43;
126 } // namespace
128 IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, Bounds) {
129 InitializeIMF();
131 InputMethodManager* imm = InputMethodManager::Get();
132 ASSERT_TRUE(imm);
134 std::vector<std::string> keyboard_layouts;
135 keyboard_layouts.push_back(
136 extension_ime_util::GetInputMethodIDByKeyboardLayout("xkb:fr::fra"));
138 // Add keyboard layouts to enable the mode indicator.
139 imm->EnableLoginLayouts("fr", keyboard_layouts);
140 ASSERT_LT(1UL, imm->GetNumActiveInputMethods());
142 chromeos::IMECandidateWindowHandlerInterface* candidate_window =
143 chromeos::IMEBridge::Get()->GetCandidateWindowHandler();
144 candidate_window->FocusStateChanged(true);
146 // Check if the size of the mode indicator is expected.
147 gfx::Rect cursor1_bounds(100, 100, 1, 20);
148 gfx::Rect mi1_bounds;
150 ScopedModeIndicatorObserverForTesting observer;
151 candidate_window->SetCursorBounds(cursor1_bounds, cursor1_bounds);
152 EXPECT_TRUE(imm->SwitchToNextInputMethod());
153 mi1_bounds = observer.last_bounds();
154 // The bounds should be bigger than the inner size.
155 EXPECT_LE(kInnerSize, mi1_bounds.width());
156 EXPECT_LE(kInnerSize, mi1_bounds.height());
157 EXPECT_TRUE(observer.is_displayed());
160 // Check if the location of the mode indicator is coresponded to
161 // the cursor bounds.
162 gfx::Rect cursor2_bounds(50, 200, 1, 20);
163 gfx::Rect mi2_bounds;
165 ScopedModeIndicatorObserverForTesting observer;
166 candidate_window->SetCursorBounds(cursor2_bounds, cursor2_bounds);
167 EXPECT_TRUE(imm->SwitchToNextInputMethod());
168 mi2_bounds = observer.last_bounds();
169 EXPECT_TRUE(observer.is_displayed());
172 EXPECT_EQ(cursor1_bounds.x() - cursor2_bounds.x(),
173 mi1_bounds.x() - mi2_bounds.x());
174 EXPECT_EQ(cursor1_bounds.y() - cursor2_bounds.y(),
175 mi1_bounds.y() - mi2_bounds.y());
176 EXPECT_EQ(mi1_bounds.width(), mi2_bounds.width());
177 EXPECT_EQ(mi1_bounds.height(), mi2_bounds.height());
179 const gfx::Rect screen_bounds =
180 ash::Shell::GetScreen()->GetDisplayMatching(cursor1_bounds).work_area();
182 // Check if the location of the mode indicator is concidered with
183 // the screen size.
184 const gfx::Rect cursor3_bounds(100, screen_bounds.bottom() - 25, 1, 20);
185 gfx::Rect mi3_bounds;
187 ScopedModeIndicatorObserverForTesting observer;
188 candidate_window->SetCursorBounds(cursor3_bounds, cursor3_bounds);
189 EXPECT_TRUE(imm->SwitchToNextInputMethod());
190 mi3_bounds = observer.last_bounds();
191 EXPECT_TRUE(observer.is_displayed());
192 EXPECT_LT(mi3_bounds.bottom(), screen_bounds.bottom());
196 IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, NumOfWidgets) {
197 InitializeIMF();
199 InputMethodManager* imm = InputMethodManager::Get();
200 ASSERT_TRUE(imm);
202 std::vector<std::string> keyboard_layouts;
203 keyboard_layouts.push_back(
204 extension_ime_util::GetInputMethodIDByKeyboardLayout("xkb:fr::fra"));
206 // Add keyboard layouts to enable the mode indicator.
207 imm->EnableLoginLayouts("fr", keyboard_layouts);
208 ASSERT_LT(1UL, imm->GetNumActiveInputMethods());
210 chromeos::IMECandidateWindowHandlerInterface* candidate_window =
211 chromeos::IMEBridge::Get()->GetCandidateWindowHandler();
212 candidate_window->FocusStateChanged(true);
215 ScopedModeIndicatorObserverForTesting observer;
217 EXPECT_TRUE(imm->SwitchToNextInputMethod());
218 EXPECT_EQ(1UL, observer.max_widget_list_size());
219 const views::Widget* widget1 = observer.widget_list()[0];
221 EXPECT_TRUE(imm->SwitchToNextInputMethod());
222 EXPECT_EQ(2UL, observer.max_widget_list_size());
224 // When a new mode indicator is displayed, the previous one should be
225 // closed.
226 content::RunAllPendingInMessageLoop();
227 EXPECT_EQ(1UL, observer.widget_list_size());
228 const views::Widget* widget2 = observer.widget_list()[0];
229 EXPECT_NE(widget1, widget2);
232 } // namespace input_method
233 } // namespace chromeos