Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / input_method / mode_indicator_browsertest.cc
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.
4
5 #include <algorithm>
6
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"
22
23 namespace chromeos {
24 namespace input_method {
25
26 class ScopedModeIndicatorObserverForTesting :
27       public ModeIndicatorObserverInterface {
28  public:
29   ScopedModeIndicatorObserverForTesting()
30       : max_widget_list_size_(0) {
31     ModeIndicatorController::SetModeIndicatorObserverForTesting(this);
32   }
33
34   virtual ~ScopedModeIndicatorObserverForTesting() {
35     for (size_t i = 0; i < widget_list_.size(); ++i) {
36       widget_list_[i]->RemoveObserver(this);
37     }
38     ModeIndicatorController::SetModeIndicatorObserverForTesting(NULL);
39   }
40
41   gfx::Rect last_bounds() const {
42     return last_bounds_;
43   }
44
45   bool is_displayed() const {
46     return is_displayed_;
47   }
48
49   const std::vector<views::Widget*>& widget_list() const {
50     return widget_list_;
51   }
52
53   size_t widget_list_size() const {
54     return widget_list_.size();
55   }
56
57   size_t max_widget_list_size() const {
58     return max_widget_list_size_;
59   }
60
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);
67   }
68
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);
75   }
76
77   // views::WidgetObserver override:
78   virtual void OnWidgetVisibilityChanged(views::Widget* widget,
79                                          bool visible) override {
80     last_bounds_ = widget->GetWindowBoundsInScreen();
81     is_displayed_ |= visible;
82   }
83
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_;
89 };
90
91 class ModeIndicatorBrowserTest : public InProcessBrowserTest {
92  public:
93   ModeIndicatorBrowserTest()
94       : InProcessBrowserTest() {}
95   virtual ~ModeIndicatorBrowserTest() {}
96
97   virtual void SetUpInProcessBrowserTestFixture() override {
98     ui::SetUpInputMethodFactoryForTesting();
99   }
100
101   void InitializeIMF() {
102     InputMethodManager::Get()
103         ->GetInputMethodUtil()
104         ->InitXkbInputMethodsForTesting();
105   }
106
107  private:
108   DISALLOW_COPY_AND_ASSIGN(ModeIndicatorBrowserTest);
109 };
110
111 namespace {
112 // 43 is the designed size of the inner contents.
113 // This value corresponds with kMinSize defined in
114 // mode_indicator_delegate_view.cc.
115 const int kInnerSize = 43;
116 }  // namespace
117
118 IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, Bounds) {
119   InitializeIMF();
120
121   InputMethodManager* imm = InputMethodManager::Get();
122   ASSERT_TRUE(imm);
123
124   std::vector<std::string> keyboard_layouts;
125   keyboard_layouts.push_back(
126       extension_ime_util::GetInputMethodIDByEngineID("xkb:fr::fra"));
127
128   // Add keyboard layouts to enable the mode indicator.
129   imm->GetActiveIMEState()->EnableLoginLayouts("fr", keyboard_layouts);
130   ASSERT_LT(1UL, imm->GetActiveIMEState()->GetNumActiveInputMethods());
131
132   chromeos::IMECandidateWindowHandlerInterface* candidate_window =
133       chromeos::IMEBridge::Get()->GetCandidateWindowHandler();
134   candidate_window->FocusStateChanged(true);
135
136   // Check if the size of the mode indicator is expected.
137   gfx::Rect cursor1_bounds(100, 100, 1, 20);
138   gfx::Rect mi1_bounds;
139   {
140     ScopedModeIndicatorObserverForTesting observer;
141     candidate_window->SetCursorBounds(cursor1_bounds, cursor1_bounds);
142     EXPECT_TRUE(imm->GetActiveIMEState()->SwitchToNextInputMethod());
143     mi1_bounds = observer.last_bounds();
144     // The bounds should be bigger than the inner size.
145     EXPECT_LE(kInnerSize, mi1_bounds.width());
146     EXPECT_LE(kInnerSize, mi1_bounds.height());
147     EXPECT_TRUE(observer.is_displayed());
148   }
149
150   // Check if the location of the mode indicator is coresponded to
151   // the cursor bounds.
152   gfx::Rect cursor2_bounds(50, 200, 1, 20);
153   gfx::Rect mi2_bounds;
154   {
155     ScopedModeIndicatorObserverForTesting observer;
156     candidate_window->SetCursorBounds(cursor2_bounds, cursor2_bounds);
157     EXPECT_TRUE(imm->GetActiveIMEState()->SwitchToNextInputMethod());
158     mi2_bounds = observer.last_bounds();
159     EXPECT_TRUE(observer.is_displayed());
160   }
161
162   EXPECT_EQ(cursor1_bounds.x() - cursor2_bounds.x(),
163             mi1_bounds.x() - mi2_bounds.x());
164   EXPECT_EQ(cursor1_bounds.y() - cursor2_bounds.y(),
165             mi1_bounds.y() - mi2_bounds.y());
166   EXPECT_EQ(mi1_bounds.width(),  mi2_bounds.width());
167   EXPECT_EQ(mi1_bounds.height(), mi2_bounds.height());
168
169   const gfx::Rect screen_bounds =
170       ash::Shell::GetScreen()->GetDisplayMatching(cursor1_bounds).work_area();
171
172   // Check if the location of the mode indicator is concidered with
173   // the screen size.
174   const gfx::Rect cursor3_bounds(100, screen_bounds.bottom() - 25, 1, 20);
175   gfx::Rect mi3_bounds;
176   {
177     ScopedModeIndicatorObserverForTesting observer;
178     candidate_window->SetCursorBounds(cursor3_bounds, cursor3_bounds);
179     EXPECT_TRUE(imm->GetActiveIMEState()->SwitchToNextInputMethod());
180     mi3_bounds = observer.last_bounds();
181     EXPECT_TRUE(observer.is_displayed());
182     EXPECT_LT(mi3_bounds.bottom(), screen_bounds.bottom());
183   }
184 }
185
186 IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, NumOfWidgets) {
187   InitializeIMF();
188
189   InputMethodManager* imm = InputMethodManager::Get();
190   ASSERT_TRUE(imm);
191
192   std::vector<std::string> keyboard_layouts;
193   keyboard_layouts.push_back(
194       extension_ime_util::GetInputMethodIDByEngineID("xkb:fr::fra"));
195
196   // Add keyboard layouts to enable the mode indicator.
197   imm->GetActiveIMEState()->EnableLoginLayouts("fr", keyboard_layouts);
198   ASSERT_LT(1UL, imm->GetActiveIMEState()->GetNumActiveInputMethods());
199
200   chromeos::IMECandidateWindowHandlerInterface* candidate_window =
201       chromeos::IMEBridge::Get()->GetCandidateWindowHandler();
202   candidate_window->FocusStateChanged(true);
203
204   {
205     ScopedModeIndicatorObserverForTesting observer;
206
207     EXPECT_TRUE(imm->GetActiveIMEState()->SwitchToNextInputMethod());
208     EXPECT_EQ(1UL, observer.max_widget_list_size());
209     const views::Widget* widget1 = observer.widget_list()[0];
210
211     EXPECT_TRUE(imm->GetActiveIMEState()->SwitchToNextInputMethod());
212     EXPECT_EQ(2UL, observer.max_widget_list_size());
213
214     // When a new mode indicator is displayed, the previous one should be
215     // closed.
216     content::RunAllPendingInMessageLoop();
217     EXPECT_EQ(1UL, observer.widget_list_size());
218     const views::Widget* widget2 = observer.widget_list()[0];
219     EXPECT_NE(widget1, widget2);
220   }
221 }
222 }  // namespace input_method
223 }  // namespace chromeos