• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 typedef athena::test::AthenaTestBase ScreenManagerTest;
18 
19 namespace athena {
20 namespace {
21 
22 const int kTestZOrderPriority = 10;
23 
Create(const std::string & name,int z_order_priority)24 aura::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 
CreateWindow(aura::Window * container,aura::WindowDelegate * delegate,const gfx::Rect & bounds)29 aura::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 
CheckZOrder(aura::Window * w1,aura::Window * w2)41 void 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 
TEST_F(ScreenManagerTest,CreateContainer)58 TEST_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 
TEST_F(ScreenManagerTest,Zorder)70 TEST_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 
TEST_F(ScreenManagerTest,NonActivatableContainer)93 TEST_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 
TEST_F(ScreenManagerTest,GrabInputContainer)114 TEST_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 
TEST_F(ScreenManagerTest,GrabShouldNotBlockVirtualKeyboard)168 TEST_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 
TEST_F(ScreenManagerTest,GrabAndMouseCapture)199 TEST_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