OLD | NEW |
| (Empty) |
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 <algorithm> | |
6 #include <string> | |
7 | |
8 #include "athena/screen/screen_manager_impl.h" | |
9 #include "athena/test/base/athena_test_base.h" | |
10 #include "athena/test/base/test_windows.h" | |
11 #include "athena/util/container_priorities.h" | |
12 #include "ui/aura/test/test_window_delegate.h" | |
13 #include "ui/aura/window.h" | |
14 #include "ui/aura/window_targeter.h" | |
15 #include "ui/events/test/event_generator.h" | |
16 #include "ui/wm/core/window_util.h" | |
17 | |
18 using ScreenManagerTest = athena::test::AthenaTestBase; | |
19 using AthenaFocusRuleTest = athena::test::AthenaTestBase; | |
20 | |
21 namespace athena { | |
22 namespace { | |
23 | |
24 const int kTestZOrderPriority = 10; | |
25 | |
26 aura::Window* Create(const std::string& name, int z_order_priority) { | |
27 ScreenManager::ContainerParams params(name, z_order_priority); | |
28 return ScreenManager::Get()->CreateContainer(params); | |
29 } | |
30 | |
31 aura::Window* CreateWindow(aura::Window* container, | |
32 aura::WindowDelegate* delegate, | |
33 const gfx::Rect& bounds) { | |
34 aura::Window* window = new aura::Window(delegate); | |
35 window->SetType(ui::wm::WINDOW_TYPE_NORMAL); | |
36 window->Init(aura::WINDOW_LAYER_TEXTURED); | |
37 container->AddChild(window); | |
38 window->Show(); | |
39 window->SetBounds(bounds); | |
40 return window; | |
41 } | |
42 | |
43 void CheckZOrder(aura::Window* w1, aura::Window* w2) { | |
44 aura::Window* parent = w1->parent(); | |
45 const aura::Window::Windows& children = parent->children(); | |
46 aura::Window::Windows::const_iterator begin_iter = children.begin(); | |
47 aura::Window::Windows::const_iterator end_iter = children.end(); | |
48 | |
49 aura::Window::Windows::const_iterator w1_iter = | |
50 std::find(begin_iter, end_iter, w1); | |
51 aura::Window::Windows::const_iterator w2_iter = | |
52 std::find(begin_iter, end_iter, w2); | |
53 EXPECT_NE(end_iter, w1_iter); | |
54 EXPECT_NE(end_iter, w2_iter); | |
55 EXPECT_TRUE(w1_iter < w2_iter); | |
56 } | |
57 | |
58 } // namespace | |
59 | |
60 TEST_F(ScreenManagerTest, CreateContainer) { | |
61 size_t num_containers = root_window()->children().size(); | |
62 | |
63 aura::Window* container = Create("test", kTestZOrderPriority); | |
64 EXPECT_EQ("test", container->name()); | |
65 | |
66 const aura::Window::Windows& containers = root_window()->children(); | |
67 EXPECT_EQ(num_containers + 1, containers.size()); | |
68 EXPECT_NE(containers.end(), | |
69 std::find(containers.begin(), containers.end(), container)); | |
70 } | |
71 | |
72 TEST_F(ScreenManagerTest, Zorder) { | |
73 aura::Window* window_10 = Create("test10", 10); | |
74 aura::Window* window_11 = Create("test11", 11); | |
75 aura::Window* window_12 = Create("test12", 12); | |
76 | |
77 { | |
78 SCOPED_TRACE("Init"); | |
79 CheckZOrder(window_10, window_11); | |
80 CheckZOrder(window_11, window_12); | |
81 } | |
82 { | |
83 SCOPED_TRACE("Delete"); | |
84 delete window_11; | |
85 CheckZOrder(window_10, window_12); | |
86 } | |
87 { | |
88 SCOPED_TRACE("Insert"); | |
89 window_11 = Create("test11", 11); | |
90 CheckZOrder(window_10, window_11); | |
91 CheckZOrder(window_11, window_12); | |
92 } | |
93 } | |
94 | |
95 TEST_F(ScreenManagerTest, NonActivatableContainer) { | |
96 ScreenManager::ContainerParams non_activatable( | |
97 "non_activatable", kTestZOrderPriority); | |
98 non_activatable.can_activate_children = false; | |
99 aura::Window* no_activatable_container = | |
100 ScreenManager::Get()->CreateContainer(non_activatable); | |
101 | |
102 ScreenManager::ContainerParams activatable( | |
103 "activatable", kTestZOrderPriority + 1); | |
104 activatable.can_activate_children = true; | |
105 aura::Window* activatable_container = | |
106 ScreenManager::Get()->CreateContainer(activatable); | |
107 | |
108 scoped_ptr<aura::Window> window(CreateWindow( | |
109 no_activatable_container, nullptr, gfx::Rect(0, 0, 100, 100))); | |
110 EXPECT_FALSE(wm::CanActivateWindow(window.get())); | |
111 | |
112 activatable_container->AddChild(window.get()); | |
113 EXPECT_TRUE(wm::CanActivateWindow(window.get())); | |
114 } | |
115 | |
116 TEST_F(ScreenManagerTest, BlockInputsShouldNotBlockVirtualKeyboard) { | |
117 ScreenManager::ContainerParams block_params("blocking", kTestZOrderPriority); | |
118 block_params.can_activate_children = true; | |
119 block_params.block_events = true; | |
120 aura::Window* block_container = | |
121 ScreenManager::Get()->CreateContainer(block_params); | |
122 | |
123 aura::test::EventCountDelegate block_delegate; | |
124 scoped_ptr<aura::Window> block_window(CreateWindow( | |
125 block_container, &block_delegate, gfx::Rect(0, 0, 100, 100))); | |
126 EXPECT_TRUE(wm::CanActivateWindow(block_window.get())); | |
127 | |
128 // Create a normal container appearing over the |block_container|. This is | |
129 // essentially the case of virtual keyboard. | |
130 ScreenManager::ContainerParams vk_params("virtual keyboard", | |
131 kTestZOrderPriority + 1); | |
132 vk_params.can_activate_children = true; | |
133 aura::Window* vk_container = ScreenManager::Get()->CreateContainer(vk_params); | |
134 | |
135 aura::test::EventCountDelegate vk_delegate; | |
136 scoped_ptr<aura::Window> vk_window( | |
137 CreateWindow(vk_container, &vk_delegate, gfx::Rect(0, 20, 100, 80))); | |
138 EXPECT_TRUE(wm::CanActivateWindow(vk_window.get())); | |
139 | |
140 ui::test::EventGenerator event_generator(root_window()); | |
141 event_generator.MoveMouseTo(10, 25); | |
142 event_generator.ClickLeftButton(); | |
143 EXPECT_EQ("0 0", block_delegate.GetMouseButtonCountsAndReset()); | |
144 EXPECT_EQ("1 1", vk_delegate.GetMouseButtonCountsAndReset()); | |
145 } | |
146 | |
147 TEST_F(ScreenManagerTest, DefaultContainer) { | |
148 ScreenManagerImpl* impl = | |
149 static_cast<ScreenManagerImpl*>(ScreenManager::Get()); | |
150 aura::Window* original_default = impl->FindContainerByPriority(CP_DEFAULT); | |
151 aura::Window* parent = original_default->parent(); | |
152 // Temporarily remove the original default container from tree. | |
153 parent->RemoveChild(original_default); | |
154 | |
155 ScreenManager::ContainerParams params("new_default", CP_END + 1); | |
156 params.default_parent = true; | |
157 params.modal_container_priority = CP_END + 2; | |
158 aura::Window* new_default = ScreenManager::Get()->CreateContainer(params); | |
159 aura::Window* w = test::CreateNormalWindow(nullptr, nullptr).release(); | |
160 EXPECT_EQ(new_default, w->parent()); | |
161 delete new_default; | |
162 | |
163 // Add the original back to shutdown properly. | |
164 parent->AddChild(original_default); | |
165 } | |
166 | |
167 TEST_F(AthenaFocusRuleTest, FocusTravarsalFromSameContainer) { | |
168 ScreenManager::ContainerParams params("contaier", kTestZOrderPriority); | |
169 params.can_activate_children = true; | |
170 scoped_ptr<aura::Window> | |
171 container(ScreenManager::Get()->CreateContainer(params)); | |
172 | |
173 scoped_ptr<aura::Window> w1(CreateWindow( | |
174 container.get(), nullptr, gfx::Rect(0, 0, 100, 100))); | |
175 wm::ActivateWindow(w1.get()); | |
176 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); | |
177 | |
178 scoped_ptr<aura::Window> w2(CreateWindow( | |
179 container.get(), nullptr, gfx::Rect(0, 0, 100, 100))); | |
180 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); | |
181 | |
182 container->RemoveChild(w1.get()); | |
183 EXPECT_TRUE(wm::IsActiveWindow(w2.get())); | |
184 } | |
185 | |
186 TEST_F(AthenaFocusRuleTest, FocusTravarsalFromOtherContainer) { | |
187 ScreenManager::ContainerParams params2("contaier2", kTestZOrderPriority + 1); | |
188 params2.can_activate_children = true; | |
189 scoped_ptr<aura::Window> | |
190 container2(ScreenManager::Get()->CreateContainer(params2)); | |
191 scoped_ptr<aura::Window> w2(CreateWindow( | |
192 container2.get(), nullptr, gfx::Rect(0, 0, 100, 100))); | |
193 wm::ActivateWindow(w2.get()); | |
194 EXPECT_TRUE(wm::IsActiveWindow(w2.get())); | |
195 | |
196 ScreenManager::ContainerParams params1("contaier1", kTestZOrderPriority); | |
197 params1.can_activate_children = true; | |
198 scoped_ptr<aura::Window> | |
199 container1(ScreenManager::Get()->CreateContainer(params1)); | |
200 ScreenManager::ContainerParams params3("contaier3", kTestZOrderPriority + 2); | |
201 params3.can_activate_children = true; | |
202 scoped_ptr<aura::Window> | |
203 container3(ScreenManager::Get()->CreateContainer(params3)); | |
204 scoped_ptr<aura::Window> w1(CreateWindow( | |
205 container1.get(), nullptr, gfx::Rect(0, 0, 100, 100))); | |
206 scoped_ptr<aura::Window> w3(CreateWindow( | |
207 container3.get(), nullptr, gfx::Rect(0, 0, 100, 100))); | |
208 | |
209 EXPECT_TRUE(wm::IsActiveWindow(w2.get())); | |
210 | |
211 container2->RemoveChild(w2.get()); | |
212 // Focus moves to a window in the front contaier. | |
213 EXPECT_TRUE(wm::IsActiveWindow(w3.get())); | |
214 | |
215 container3->RemoveChild(w3.get()); | |
216 // Focus moves to a window in the back contaier. | |
217 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); | |
218 } | |
219 | |
220 TEST_F(AthenaFocusRuleTest, FocusTravarsalFromEventBlockedContainer) { | |
221 ScreenManager::ContainerParams params1("contaier1", kTestZOrderPriority + 1); | |
222 params1.can_activate_children = true; | |
223 scoped_ptr<aura::Window> | |
224 container1(ScreenManager::Get()->CreateContainer(params1)); | |
225 | |
226 ScreenManager::ContainerParams params2("contaier2", kTestZOrderPriority + 2); | |
227 params2.can_activate_children = true; | |
228 params2.block_events = true; | |
229 scoped_ptr<aura::Window> | |
230 container2(ScreenManager::Get()->CreateContainer(params2)); | |
231 | |
232 scoped_ptr<aura::Window> w1(CreateWindow( | |
233 container1.get(), nullptr, gfx::Rect(0, 0, 100, 100))); | |
234 scoped_ptr<aura::Window> w2(CreateWindow( | |
235 container2.get(), nullptr, gfx::Rect(0, 0, 100, 100))); | |
236 | |
237 wm::ActivateWindow(w2.get()); | |
238 EXPECT_TRUE(wm::IsActiveWindow(w2.get())); | |
239 | |
240 // Confirm that w1 can't get the focus. | |
241 wm::ActivateWindow(w1.get()); | |
242 EXPECT_FALSE(wm::IsActiveWindow(w1.get())); | |
243 EXPECT_TRUE(wm::IsActiveWindow(w2.get())); | |
244 | |
245 container2->Hide(); | |
246 w2.reset(); | |
247 container2.reset(); | |
248 | |
249 EXPECT_TRUE(wm::IsActiveWindow(w1.get())); | |
250 } | |
251 | |
252 TEST_F(AthenaFocusRuleTest, FocusTravarsalFromModalWindow) { | |
253 ScreenManagerImpl* screen_manager = | |
254 static_cast<ScreenManagerImpl*>(ScreenManager::Get()); | |
255 | |
256 ScreenManager::ContainerParams params1("contaier1", kTestZOrderPriority + 1); | |
257 params1.can_activate_children = true; | |
258 scoped_ptr<aura::Window> | |
259 container1(ScreenManager::Get()->CreateContainer(params1)); | |
260 | |
261 scoped_ptr<aura::Window> normal(CreateWindow( | |
262 container1.get(), nullptr, gfx::Rect(0, 0, 100, 100))); | |
263 wm::ActivateWindow(normal.get()); | |
264 EXPECT_TRUE(wm::IsActiveWindow(normal.get())); | |
265 | |
266 aura::test::EventCountDelegate delegate; | |
267 scoped_ptr<aura::Window> modal(test::CreateTransientWindow( | |
268 &delegate, nullptr, ui::MODAL_TYPE_SYSTEM, false)); | |
269 | |
270 aura::Window* modal_container = | |
271 screen_manager->FindContainerByPriority(CP_SYSTEM_MODAL); | |
272 EXPECT_TRUE(modal_container); | |
273 | |
274 modal->Show(); | |
275 wm::ActivateWindow(modal.get()); | |
276 EXPECT_TRUE(wm::IsActiveWindow(modal.get())); | |
277 EXPECT_FALSE(wm::IsActiveWindow(normal.get())); | |
278 | |
279 // Closes the modal window and confirms the normal window gets the focus. | |
280 modal.reset(); | |
281 EXPECT_TRUE(wm::IsActiveWindow(normal.get())); | |
282 } | |
283 | |
284 namespace { | |
285 | |
286 class ScreenManagerTargeterTest | |
287 : public athena::test::AthenaTestBase, | |
288 public testing::WithParamInterface<bool> { | |
289 public: | |
290 ScreenManagerTargeterTest() | |
291 : targeter_(GetParam() ? nullptr : new aura::WindowTargeter) {} | |
292 ~ScreenManagerTargeterTest() override {} | |
293 | |
294 protected: | |
295 scoped_ptr<ui::EventTargeter> targeter_; | |
296 | |
297 private: | |
298 DISALLOW_COPY_AND_ASSIGN(ScreenManagerTargeterTest); | |
299 }; | |
300 | |
301 } // namespace | |
302 | |
303 TEST_P(ScreenManagerTargeterTest, BlockContainer) { | |
304 ScreenManager::ContainerParams normal_params( | |
305 "normal", kTestZOrderPriority); | |
306 normal_params.can_activate_children = true; | |
307 aura::Window* normal_container = | |
308 ScreenManager::Get()->CreateContainer(normal_params); | |
309 normal_container->SetEventTargeter(targeter_.Pass()); | |
310 | |
311 aura::test::EventCountDelegate normal_delegate; | |
312 scoped_ptr<aura::Window> normal_window(CreateWindow( | |
313 normal_container, &normal_delegate, gfx::Rect(0, 0, 100, 100))); | |
314 | |
315 EXPECT_TRUE(wm::CanActivateWindow(normal_window.get())); | |
316 wm::ActivateWindow(normal_window.get()); | |
317 ui::test::EventGenerator event_generator(root_window()); | |
318 event_generator.MoveMouseTo(0, 0); | |
319 event_generator.ClickLeftButton(); | |
320 EXPECT_EQ("1 1", normal_delegate.GetMouseButtonCountsAndReset()); | |
321 event_generator.PressKey(ui::VKEY_A, ui::EF_NONE); | |
322 event_generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE); | |
323 EXPECT_EQ("1 1", normal_delegate.GetKeyCountsAndReset()); | |
324 | |
325 ScreenManager::ContainerParams block_params("blocking", | |
326 kTestZOrderPriority + 1); | |
327 block_params.can_activate_children = true; | |
328 block_params.block_events = true; | |
329 aura::Window* block_container = | |
330 ScreenManager::Get()->CreateContainer(block_params); | |
331 | |
332 EXPECT_FALSE(wm::CanActivateWindow(normal_window.get())); | |
333 | |
334 aura::test::EventCountDelegate block_delegate; | |
335 scoped_ptr<aura::Window> block_window(CreateWindow( | |
336 block_container, &block_delegate, gfx::Rect(10, 10, 100, 100))); | |
337 EXPECT_TRUE(wm::CanActivateWindow(block_window.get())); | |
338 | |
339 wm::ActivateWindow(block_window.get()); | |
340 | |
341 // (0, 0) is still on normal_window, but the event should not go there | |
342 // because blockbing_container prevents it. | |
343 event_generator.MoveMouseTo(0, 0); | |
344 event_generator.ClickLeftButton(); | |
345 EXPECT_EQ("0 0", normal_delegate.GetMouseButtonCountsAndReset()); | |
346 EXPECT_EQ("0 0", block_delegate.GetMouseButtonCountsAndReset()); | |
347 event_generator.MoveMouseWheel(0, 10); | |
348 // EXPECT_EQ(0, normal_event_counter.num_scroll_events()); | |
349 | |
350 event_generator.MoveMouseTo(20, 20); | |
351 event_generator.ClickLeftButton(); | |
352 EXPECT_EQ("1 1", block_delegate.GetMouseButtonCountsAndReset()); | |
353 | |
354 event_generator.PressKey(ui::VKEY_A, ui::EF_NONE); | |
355 event_generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE); | |
356 EXPECT_EQ("0 0", normal_delegate.GetKeyCountsAndReset()); | |
357 EXPECT_EQ("1 1", block_delegate.GetKeyCountsAndReset()); | |
358 } | |
359 | |
360 TEST_P(ScreenManagerTargeterTest, BlockAndMouseCapture) { | |
361 ScreenManager::ContainerParams normal_params( | |
362 "normal", kTestZOrderPriority); | |
363 normal_params.can_activate_children = true; | |
364 aura::Window* normal_container = | |
365 ScreenManager::Get()->CreateContainer(normal_params); | |
366 normal_container->SetEventTargeter(targeter_.Pass()); | |
367 | |
368 aura::test::EventCountDelegate normal_delegate; | |
369 scoped_ptr<aura::Window> normal_window(CreateWindow( | |
370 normal_container, &normal_delegate, gfx::Rect(0, 0, 100, 100))); | |
371 | |
372 ui::test::EventGenerator event_generator(root_window()); | |
373 event_generator.MoveMouseTo(0, 0); | |
374 event_generator.PressLeftButton(); | |
375 | |
376 // Creating blocking container while mouse pressing. | |
377 ScreenManager::ContainerParams block_params("blocking", | |
378 kTestZOrderPriority + 1); | |
379 block_params.can_activate_children = true; | |
380 block_params.block_events = true; | |
381 aura::Window* block_container = | |
382 ScreenManager::Get()->CreateContainer(block_params); | |
383 | |
384 aura::test::EventCountDelegate block_delegate; | |
385 scoped_ptr<aura::Window> block_window(CreateWindow( | |
386 block_container, &block_delegate, gfx::Rect(10, 10, 100, 100))); | |
387 | |
388 // Release event should be sent to |normal_window| because it captures the | |
389 // mouse event. | |
390 event_generator.ReleaseLeftButton(); | |
391 EXPECT_EQ("1 1", normal_delegate.GetMouseButtonCountsAndReset()); | |
392 EXPECT_EQ("0 0", block_delegate.GetMouseButtonCountsAndReset()); | |
393 | |
394 // After release, further mouse events should not be sent to |normal_window| | |
395 // because block_container blocks the input. | |
396 event_generator.ClickLeftButton(); | |
397 EXPECT_EQ("0 0", normal_delegate.GetMouseButtonCountsAndReset()); | |
398 EXPECT_EQ("0 0", block_delegate.GetMouseButtonCountsAndReset()); | |
399 } | |
400 | |
401 INSTANTIATE_TEST_CASE_P(WithOrWithoutTargeter, | |
402 ScreenManagerTargeterTest, | |
403 testing::Values(false, true)); | |
404 | |
405 } // namespace athena | |
OLD | NEW |