| 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 |