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/screen/public/screen_manager.h" 6 7#include <algorithm> 8#include <string> 9 10#include "athena/test/athena_test_base.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/events/test/event_generator.h" 15#include "ui/wm/core/window_util.h" 16 17typedef athena::test::AthenaTestBase ScreenManagerTest; 18 19namespace athena { 20namespace { 21 22const int kTestZOrderPriority = 10; 23 24aura::Window* Create(const std::string& name, int z_order_priority) { 25 ScreenManager::ContainerParams params(name, z_order_priority); 26 return ScreenManager::Get()->CreateContainer(params); 27} 28 29aura::Window* CreateWindow(aura::Window* container, 30 aura::WindowDelegate* delegate, 31 const gfx::Rect& bounds) { 32 aura::Window* window = new aura::Window(delegate); 33 window->SetType(ui::wm::WINDOW_TYPE_NORMAL); 34 window->Init(aura::WINDOW_LAYER_TEXTURED); 35 container->AddChild(window); 36 window->Show(); 37 window->SetBounds(bounds); 38 return window; 39} 40 41void CheckZOrder(aura::Window* w1, aura::Window* w2) { 42 aura::Window* parent = w1->parent(); 43 const aura::Window::Windows& children = parent->children(); 44 aura::Window::Windows::const_iterator begin_iter = children.begin(); 45 aura::Window::Windows::const_iterator end_iter = children.end(); 46 47 aura::Window::Windows::const_iterator w1_iter = 48 std::find(begin_iter, end_iter, w1); 49 aura::Window::Windows::const_iterator w2_iter = 50 std::find(begin_iter, end_iter, w2); 51 EXPECT_NE(end_iter, w1_iter); 52 EXPECT_NE(end_iter, w2_iter); 53 EXPECT_TRUE(w1_iter < w2_iter); 54} 55 56} // namespace 57 58TEST_F(ScreenManagerTest, CreateContainer) { 59 size_t num_containers = root_window()->children().size(); 60 61 aura::Window* container = Create("test", kTestZOrderPriority); 62 EXPECT_EQ("test", container->name()); 63 64 const aura::Window::Windows& containers = root_window()->children(); 65 EXPECT_EQ(num_containers + 1, containers.size()); 66 EXPECT_NE(containers.end(), 67 std::find(containers.begin(), containers.end(), container)); 68} 69 70TEST_F(ScreenManagerTest, Zorder) { 71 aura::Window* window_10 = Create("test10", 10); 72 aura::Window* window_11 = Create("test11", 11); 73 aura::Window* window_12 = Create("test12", 12); 74 75 { 76 SCOPED_TRACE("Init"); 77 CheckZOrder(window_10, window_11); 78 CheckZOrder(window_11, window_12); 79 } 80 { 81 SCOPED_TRACE("Delete"); 82 delete window_11; 83 CheckZOrder(window_10, window_12); 84 } 85 { 86 SCOPED_TRACE("Insert"); 87 window_11 = Create("test11", 11); 88 CheckZOrder(window_10, window_11); 89 CheckZOrder(window_11, window_12); 90 } 91} 92 93TEST_F(ScreenManagerTest, NonActivatableContainer) { 94 ScreenManager::ContainerParams non_activatable( 95 "non_activatable", kTestZOrderPriority); 96 non_activatable.can_activate_children = false; 97 aura::Window* no_activatable_container = 98 ScreenManager::Get()->CreateContainer(non_activatable); 99 100 ScreenManager::ContainerParams activatable( 101 "activatable", kTestZOrderPriority + 1); 102 activatable.can_activate_children = true; 103 aura::Window* activatable_container = 104 ScreenManager::Get()->CreateContainer(activatable); 105 106 scoped_ptr<aura::Window> window( 107 CreateWindow(no_activatable_container, NULL, gfx::Rect(0, 0, 100, 100))); 108 EXPECT_FALSE(wm::CanActivateWindow(window.get())); 109 110 activatable_container->AddChild(window.get()); 111 EXPECT_TRUE(wm::CanActivateWindow(window.get())); 112} 113 114TEST_F(ScreenManagerTest, GrabInputContainer) { 115 ScreenManager::ContainerParams normal_params( 116 "normal", kTestZOrderPriority); 117 normal_params.can_activate_children = true; 118 aura::Window* normal_container = 119 ScreenManager::Get()->CreateContainer(normal_params); 120 121 aura::test::EventCountDelegate normal_delegate; 122 scoped_ptr<aura::Window> normal_window(CreateWindow( 123 normal_container, &normal_delegate, gfx::Rect(0, 0, 100, 100))); 124 125 EXPECT_TRUE(wm::CanActivateWindow(normal_window.get())); 126 wm::ActivateWindow(normal_window.get()); 127 ui::test::EventGenerator event_generator(root_window()); 128 event_generator.MoveMouseTo(0, 0); 129 event_generator.ClickLeftButton(); 130 EXPECT_EQ("1 1", normal_delegate.GetMouseButtonCountsAndReset()); 131 event_generator.PressKey(ui::VKEY_A, ui::EF_NONE); 132 event_generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE); 133 EXPECT_EQ("1 1", normal_delegate.GetKeyCountsAndReset()); 134 135 ScreenManager::ContainerParams grab_params( 136 "grabbing", kTestZOrderPriority + 1); 137 grab_params.can_activate_children = true; 138 grab_params.grab_inputs = true; 139 aura::Window* grab_container = 140 ScreenManager::Get()->CreateContainer(grab_params); 141 142 EXPECT_FALSE(wm::CanActivateWindow(normal_window.get())); 143 144 aura::test::EventCountDelegate grab_delegate; 145 scoped_ptr<aura::Window> grab_window(CreateWindow( 146 grab_container, &grab_delegate, gfx::Rect(10, 10, 100, 100))); 147 EXPECT_TRUE(wm::CanActivateWindow(grab_window.get())); 148 149 wm::ActivateWindow(grab_window.get()); 150 151 // (0, 0) is still on normal_window, but the event should not go there 152 // because grabbing_container prevents it. 153 event_generator.MoveMouseTo(0, 0); 154 event_generator.ClickLeftButton(); 155 EXPECT_EQ("0 0", normal_delegate.GetMouseButtonCountsAndReset()); 156 EXPECT_EQ("0 0", grab_delegate.GetMouseButtonCountsAndReset()); 157 158 event_generator.MoveMouseTo(20, 20); 159 event_generator.ClickLeftButton(); 160 EXPECT_EQ("1 1", grab_delegate.GetMouseButtonCountsAndReset()); 161 162 event_generator.PressKey(ui::VKEY_A, ui::EF_NONE); 163 event_generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE); 164 EXPECT_EQ("0 0", normal_delegate.GetKeyCountsAndReset()); 165 EXPECT_EQ("1 1", grab_delegate.GetKeyCountsAndReset()); 166} 167 168TEST_F(ScreenManagerTest, GrabShouldNotBlockVirtualKeyboard) { 169 ScreenManager::ContainerParams grab_params("grabbing", kTestZOrderPriority); 170 grab_params.can_activate_children = true; 171 grab_params.grab_inputs = true; 172 aura::Window* grab_container = 173 ScreenManager::Get()->CreateContainer(grab_params); 174 175 aura::test::EventCountDelegate grab_delegate; 176 scoped_ptr<aura::Window> grab_window( 177 CreateWindow(grab_container, &grab_delegate, gfx::Rect(0, 0, 100, 100))); 178 EXPECT_TRUE(wm::CanActivateWindow(grab_window.get())); 179 180 // Create a normal container appearing over the |grab_container|. This is 181 // essentially the case of virtual keyboard. 182 ScreenManager::ContainerParams vk_params( 183 "virtual keyboard", kTestZOrderPriority + 1); 184 vk_params.can_activate_children = true; 185 aura::Window* vk_container = ScreenManager::Get()->CreateContainer(vk_params); 186 187 aura::test::EventCountDelegate vk_delegate; 188 scoped_ptr<aura::Window> vk_window( 189 CreateWindow(vk_container, &vk_delegate, gfx::Rect(0, 20, 100, 80))); 190 EXPECT_TRUE(wm::CanActivateWindow(vk_window.get())); 191 192 ui::test::EventGenerator event_generator(root_window()); 193 event_generator.MoveMouseTo(10, 25); 194 event_generator.ClickLeftButton(); 195 EXPECT_EQ("0 0", grab_delegate.GetMouseButtonCountsAndReset()); 196 EXPECT_EQ("1 1", vk_delegate.GetMouseButtonCountsAndReset()); 197} 198 199TEST_F(ScreenManagerTest, GrabAndMouseCapture) { 200 ScreenManager::ContainerParams normal_params( 201 "normal", kTestZOrderPriority); 202 normal_params.can_activate_children = true; 203 aura::Window* normal_container = 204 ScreenManager::Get()->CreateContainer(normal_params); 205 206 aura::test::EventCountDelegate normal_delegate; 207 scoped_ptr<aura::Window> normal_window(CreateWindow( 208 normal_container, &normal_delegate, gfx::Rect(0, 0, 100, 100))); 209 210 ui::test::EventGenerator event_generator(root_window()); 211 event_generator.MoveMouseTo(0, 0); 212 event_generator.PressLeftButton(); 213 214 // Creating grabbing container while mouse pressing. 215 ScreenManager::ContainerParams grab_params( 216 "grabbing", kTestZOrderPriority + 1); 217 grab_params.can_activate_children = true; 218 grab_params.grab_inputs = true; 219 aura::Window* grab_container = 220 ScreenManager::Get()->CreateContainer(grab_params); 221 222 aura::test::EventCountDelegate grab_delegate; 223 scoped_ptr<aura::Window> grab_window(CreateWindow( 224 grab_container, &grab_delegate, gfx::Rect(10, 10, 100, 100))); 225 226 // Release event should be sent to |normal_window| because it captures the 227 // mouse event. 228 event_generator.ReleaseLeftButton(); 229 EXPECT_EQ("1 1", normal_delegate.GetMouseButtonCountsAndReset()); 230 EXPECT_EQ("0 0", grab_delegate.GetMouseButtonCountsAndReset()); 231 232 // After release, further mouse events should not be sent to |normal_window| 233 // because grab_container grabs the input. 234 event_generator.ClickLeftButton(); 235 EXPECT_EQ("0 0", normal_delegate.GetMouseButtonCountsAndReset()); 236 EXPECT_EQ("0 0", grab_delegate.GetMouseButtonCountsAndReset()); 237} 238 239} // namespace athena 240