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.
4
5 #include "athena/home/public/home_card.h"
6
7 #include "athena/activity/public/activity_factory.h"
8 #include "athena/home/home_card_constants.h"
9 #include "athena/home/home_card_impl.h"
10 #include "athena/test/athena_test_base.h"
11 #include "athena/wm/public/window_manager.h"
12 #include "ui/aura/window.h"
13 #include "ui/events/test/event_generator.h"
14 #include "ui/gfx/display.h"
15 #include "ui/gfx/screen.h"
16 #include "ui/views/controls/textfield/textfield.h"
17 #include "ui/views/focus/focus_manager.h"
18 #include "ui/views/widget/widget.h"
19 #include "ui/wm/core/shadow_types.h"
20 #include "ui/wm/core/window_util.h"
21
22 namespace athena {
23
GetHomeCardWindow()24 aura::Window* GetHomeCardWindow() {
25 return static_cast<HomeCardImpl*>(HomeCard::Get())->
26 GetHomeCardWindowForTest();
27 }
28
29 // Returns true if the keyboard focus is on the search box.
IsSearchBoxFocused(aura::Window * home_card)30 bool IsSearchBoxFocused(aura::Window* home_card) {
31 return views::Widget::GetWidgetForNativeWindow(home_card)->
32 GetContentsView()->GetViewByID(kHomeCardSearchBoxId)->HasFocus();
33 }
34
35 typedef test::AthenaTestBase HomeCardTest;
36
TEST_F(HomeCardTest,BasicTransition)37 TEST_F(HomeCardTest, BasicTransition) {
38 ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
39 aura::Window* home_card = GetHomeCardWindow();
40 const int screen_height = root_window()->bounds().height();
41 const int work_area_height = gfx::Screen::GetScreenFor(root_window())->
42 GetDisplayNearestWindow(root_window()).work_area().height();
43 ASSERT_TRUE(home_card);
44
45 // In the minimized state, home card should be outside (below) the work area.
46 EXPECT_EQ(screen_height - kHomeCardMinimizedHeight,
47 home_card->GetTargetBounds().y());
48 EXPECT_EQ(work_area_height, home_card->GetTargetBounds().y());
49 EXPECT_EQ(wm::ShadowType::SHADOW_TYPE_NONE, wm::GetShadowType(home_card));
50
51 WindowManager::Get()->ToggleOverview();
52 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
53 EXPECT_EQ(screen_height - kHomeCardHeight, home_card->GetTargetBounds().y());
54 EXPECT_EQ(wm::ShadowType::SHADOW_TYPE_RECTANGULAR,
55 wm::GetShadowType(home_card));
56
57 WindowManager::Get()->ToggleOverview();
58 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
59 EXPECT_EQ(work_area_height, home_card->GetTargetBounds().y());
60 EXPECT_EQ(wm::ShadowType::SHADOW_TYPE_NONE, wm::GetShadowType(home_card));
61 }
62
TEST_F(HomeCardTest,VirtualKeyboardTransition)63 TEST_F(HomeCardTest, VirtualKeyboardTransition) {
64 // Minimized -> Hidden for virtual keyboard.
65 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
66 const gfx::Rect vk_bounds(0, 0, 100, 100);
67 HomeCard::Get()->UpdateVirtualKeyboardBounds(vk_bounds);
68 EXPECT_EQ(HomeCard::HIDDEN, HomeCard::Get()->GetState());
69 HomeCard::Get()->UpdateVirtualKeyboardBounds(gfx::Rect());
70 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
71
72 // bottom -> centered for virtual keyboard.
73 WindowManager::Get()->ToggleOverview();
74 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
75 HomeCard::Get()->UpdateVirtualKeyboardBounds(vk_bounds);
76 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
77
78 aura::Window* home_card = GetHomeCardWindow();
79 EXPECT_EQ(0, home_card->GetTargetBounds().y());
80 EXPECT_EQ(wm::ShadowType::SHADOW_TYPE_RECTANGULAR,
81 wm::GetShadowType(home_card));
82
83 HomeCard::Get()->UpdateVirtualKeyboardBounds(gfx::Rect());
84 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
85 }
86
TEST_F(HomeCardTest,ToggleOverviewWithVirtualKeyboard)87 TEST_F(HomeCardTest, ToggleOverviewWithVirtualKeyboard) {
88 // Minimized -> Hidden for virtual keyboard.
89 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
90 const gfx::Rect vk_bounds(0, 0, 100, 100);
91 HomeCard::Get()->UpdateVirtualKeyboardBounds(vk_bounds);
92 EXPECT_EQ(HomeCard::HIDDEN, HomeCard::Get()->GetState());
93
94 // Toogle overview revives the bottom home card. Home card also gets
95 /// activated which will close the virtual keyboard.
96 WindowManager::Get()->ToggleOverview();
97 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
98 aura::Window* home_card = GetHomeCardWindow();
99 EXPECT_TRUE(wm::IsActiveWindow(home_card));
100 }
101
102 // Verify if the home card is correctly minimized after app launch.
TEST_F(HomeCardTest,AppSelection)103 TEST_F(HomeCardTest, AppSelection) {
104 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
105
106 WindowManager::Get()->ToggleOverview();
107 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
108
109 athena::ActivityFactory::Get()->CreateWebActivity(
110 NULL, base::string16(), GURL("http://www.google.com/"));
111 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
112 }
113
TEST_F(HomeCardTest,Accelerators)114 TEST_F(HomeCardTest, Accelerators) {
115 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
116
117 ui::test::EventGenerator generator(root_window());
118 generator.PressKey(ui::VKEY_L, ui::EF_CONTROL_DOWN);
119 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
120
121 generator.PressKey(ui::VKEY_L, ui::EF_CONTROL_DOWN);
122 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
123
124 // Do nothing for BOTTOM.
125 WindowManager::Get()->ToggleOverview();
126 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
127 generator.PressKey(ui::VKEY_L, ui::EF_CONTROL_DOWN);
128 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
129
130 // Do nothing if the centered state is a temporary state.
131 HomeCard::Get()->UpdateVirtualKeyboardBounds(gfx::Rect(0, 0, 100, 100));
132 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
133 generator.PressKey(ui::VKEY_L, ui::EF_CONTROL_DOWN);
134 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
135 }
136
TEST_F(HomeCardTest,MouseClick)137 TEST_F(HomeCardTest, MouseClick) {
138 ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
139
140 // Mouse click at the bottom of the screen should invokes overview mode and
141 // changes the state to BOTTOM.
142 gfx::Rect screen_rect(root_window()->bounds());
143 ui::test::EventGenerator generator(
144 root_window(), gfx::Point(
145 screen_rect.x() + screen_rect.width() / 2, screen_rect.bottom() - 1));
146 generator.ClickLeftButton();
147
148 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
149 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
150
151 // Further clicks are simply ignored.
152 generator.ClickLeftButton();
153 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
154 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
155 }
156
TEST_F(HomeCardTest,Gestures)157 TEST_F(HomeCardTest, Gestures) {
158 ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
159 ui::test::EventGenerator generator(root_window());
160 gfx::Rect screen_rect(root_window()->bounds());
161
162 const int bottom = screen_rect.bottom();
163 const int x = screen_rect.x() + 1;
164
165 generator.GestureScrollSequence(gfx::Point(x, bottom - 1),
166 gfx::Point(x, bottom - 70),
167 base::TimeDelta::FromSeconds(1),
168 10);
169 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
170 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
171
172 // Too short moves. Nothing has changed.
173 generator.GestureScrollSequence(gfx::Point(x, bottom - 40),
174 gfx::Point(x, bottom - 80),
175 base::TimeDelta::FromSeconds(1),
176 10);
177 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
178 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
179
180 generator.GestureScrollSequence(gfx::Point(x, bottom - 40),
181 gfx::Point(x, bottom - 20),
182 base::TimeDelta::FromSeconds(1),
183 10);
184 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
185 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
186
187 // Swipe up to the centered state.
188 generator.GestureScrollSequence(gfx::Point(x, bottom - 40),
189 gfx::Point(x, bottom - 300),
190 base::TimeDelta::FromSeconds(1),
191 10);
192 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
193 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
194
195 // Swipe up from centered; nothing has to be changed.
196 generator.GestureScrollSequence(gfx::Point(x, bottom - 300),
197 gfx::Point(x, bottom - 350),
198 base::TimeDelta::FromSeconds(1),
199 10);
200 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
201 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
202
203 // Swipe down slightly; nothing has to be changed.
204 generator.GestureScrollSequence(gfx::Point(x, bottom - 300),
205 gfx::Point(x, bottom - 250),
206 base::TimeDelta::FromSeconds(1),
207 10);
208 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
209 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
210
211 // Swipe down to the bottom state.
212 generator.GestureScrollSequence(gfx::Point(x, 10),
213 gfx::Point(x, bottom - 90),
214 base::TimeDelta::FromSeconds(1),
215 10);
216 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
217 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
218
219 generator.GestureScrollSequence(gfx::Point(x, bottom - 40),
220 gfx::Point(x, bottom - 300),
221 base::TimeDelta::FromSeconds(1),
222 10);
223 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
224 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
225
226 // Swipe down to the minimized state.
227 generator.GestureScrollSequence(gfx::Point(x, 10),
228 gfx::Point(x, bottom - 1),
229 base::TimeDelta::FromSeconds(1),
230 10);
231 EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
232 EXPECT_FALSE(WindowManager::Get()->IsOverviewModeActive());
233 }
234
TEST_F(HomeCardTest,GesturesToFullDirectly)235 TEST_F(HomeCardTest, GesturesToFullDirectly) {
236 ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
237 ui::test::EventGenerator generator(root_window());
238 gfx::Rect screen_rect(root_window()->bounds());
239
240 const int bottom = screen_rect.bottom();
241 const int x = screen_rect.x() + 1;
242
243 generator.GestureScrollSequence(gfx::Point(x, bottom - 1),
244 gfx::Point(x, 20),
245 base::TimeDelta::FromSeconds(1),
246 10);
247 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
248 EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive());
249 }
250
TEST_F(HomeCardTest,KeyboardFocus)251 TEST_F(HomeCardTest, KeyboardFocus) {
252 ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
253 aura::Window* home_card = GetHomeCardWindow();
254 ASSERT_FALSE(IsSearchBoxFocused(home_card));
255
256 WindowManager::Get()->ToggleOverview();
257 ASSERT_FALSE(IsSearchBoxFocused(home_card));
258
259 ui::test::EventGenerator generator(root_window());
260 gfx::Rect screen_rect(root_window()->bounds());
261
262 const int bottom = screen_rect.bottom();
263 const int x = screen_rect.x() + 1;
264
265 generator.GestureScrollSequence(gfx::Point(x, bottom - 40),
266 gfx::Point(x, 10),
267 base::TimeDelta::FromSeconds(1),
268 10);
269 EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState());
270 EXPECT_TRUE(IsSearchBoxFocused(home_card));
271
272 generator.GestureScrollSequence(gfx::Point(x, 10),
273 gfx::Point(x, bottom - 100),
274 base::TimeDelta::FromSeconds(1),
275 10);
276 EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
277 EXPECT_FALSE(IsSearchBoxFocused(home_card));
278 }
279
280 } // namespace athena
281