- add sources.
[platform/framework/web/crosswalk.git] / src / ash / display / mouse_cursor_event_filter_unittest.cc
1 // Copyright (c) 2012 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 "ash/display/mouse_cursor_event_filter.h"
6
7 #include "ash/shell.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ash/test/cursor_manager_test_api.h"
10 #include "ash/display/display_layout_store.h"
11 #include "ash/display/display_manager.h"
12 #include "ui/aura/env.h"
13 #include "ui/aura/root_window.h"
14 #include "ui/gfx/display.h"
15 #include "ui/gfx/screen.h"
16
17 namespace ash {
18 namespace internal {
19 namespace {
20
21 gfx::Display GetPrimaryDisplay() {
22   return Shell::GetScreen()->GetDisplayNearestWindow(
23       Shell::GetAllRootWindows()[0]);
24 }
25
26 gfx::Display GetSecondaryDisplay() {
27   return Shell::GetScreen()->GetDisplayNearestWindow(
28       Shell::GetAllRootWindows()[1]);
29 }
30
31 }  // namespace
32
33 class MouseCursorEventFilterTest : public test::AshTestBase {
34  public:
35   MouseCursorEventFilterTest() {}
36   virtual ~MouseCursorEventFilterTest() {}
37
38  protected:
39   MouseCursorEventFilter* event_filter() {
40     return Shell::GetInstance()->mouse_cursor_filter();
41   }
42
43   bool WarpMouseCursorIfNecessary(aura::RootWindow* target_root,
44                                   gfx::Point point_in_screen) {
45     bool is_warped = event_filter()->WarpMouseCursorIfNecessary(
46         target_root, point_in_screen);
47     event_filter()->reset_was_mouse_warped_for_test();
48     return is_warped;
49   }
50
51   bool WarpMouseCursorIfNecessaryWithDragRoot(
52       aura::RootWindow* drag_source_root,
53       aura::RootWindow* target_root,
54       gfx::Point point_in_screen) {
55     gfx::Point location = drag_source_root->bounds().CenterPoint();
56     ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, location,
57                            location, 0);
58     ui::Event::DispatcherApi(&pressed).set_target(drag_source_root);
59     event_filter()->OnMouseEvent(&pressed);
60     bool is_warped = event_filter()->WarpMouseCursorIfNecessary(
61         target_root, point_in_screen);
62     event_filter()->reset_was_mouse_warped_for_test();
63
64     ui::MouseEvent released(ui::ET_MOUSE_RELEASED, location,
65                            location, 0);
66     ui::Event::DispatcherApi(&released).set_target(drag_source_root);
67     event_filter()->OnMouseEvent(&released);
68     return is_warped;
69   }
70
71  private:
72   MouseCursorEventFilter* event_filter_;
73
74   DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilterTest);
75 };
76
77 // Verifies if the mouse pointer correctly moves to another display when there
78 // are two displays.
79 TEST_F(MouseCursorEventFilterTest, WarpMouse) {
80   if (!SupportsMultipleDisplays())
81     return;
82
83   UpdateDisplay("500x500,500x500");
84
85   ASSERT_EQ(
86       DisplayLayout::RIGHT,
87       Shell::GetInstance()->display_manager()->layout_store()->
88           default_display_layout().position);
89
90   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
91   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(11, 11)));
92   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(11, 11)));
93
94   // Touch the right edge of the primary root window. Pointer should warp.
95   EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11)));
96   EXPECT_EQ("501,11",  // by 2px.
97             aura::Env::GetInstance()->last_mouse_location().ToString());
98
99   // Touch the left edge of the secondary root window. Pointer should warp.
100   EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(500, 11)));
101   EXPECT_EQ("498,11",  // by 2px.
102             aura::Env::GetInstance()->last_mouse_location().ToString());
103
104   // Touch the left edge of the primary root window.
105   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(0, 11)));
106   // Touch the top edge of the primary root window.
107   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(11, 0)));
108   // Touch the bottom edge of the primary root window.
109   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0],
110                                           gfx::Point(11, 499)));
111   // Touch the right edge of the secondary root window.
112   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1],
113                                           gfx::Point(999, 11)));
114   // Touch the top edge of the secondary root window.
115   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(11, 0)));
116   // Touch the bottom edge of the secondary root window.
117   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1],
118                                           gfx::Point(11, 499)));
119 }
120
121 // Verifies if the mouse pointer correctly moves to another display even when
122 // two displays are not the same size.
123 TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentSizeDisplays) {
124   if (!SupportsMultipleDisplays())
125     return;
126
127   UpdateDisplay("500x500,600x600");  // the second one is larger.
128
129   ASSERT_EQ(
130       DisplayLayout::RIGHT,
131       Shell::GetInstance()->display_manager()->
132           GetCurrentDisplayLayout().position);
133
134   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
135   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123));
136
137   // Touch the left edge of the secondary root window. Pointer should NOT warp
138   // because 1px left of (0, 500) is outside the primary root window.
139   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(0, 500)));
140   EXPECT_EQ("623,123",  // by 2px.
141             aura::Env::GetInstance()->last_mouse_location().ToString());
142
143   // Touch the left edge of the secondary root window. Pointer should warp
144   // because 1px left of (0, 499) is inside the primary root window.
145   EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[1],
146                                          gfx::Point(500, 499)));
147   EXPECT_EQ("498,499",  // by 2px.
148             aura::Env::GetInstance()->last_mouse_location().ToString());
149 }
150
151 // Verifies if the mouse pointer correctly moves between displays with
152 // different scale factors.
153 TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentScaleDisplays) {
154   if (!SupportsMultipleDisplays())
155     return;
156
157   UpdateDisplay("500x500,600x600*2");
158
159   ASSERT_EQ(
160       DisplayLayout::RIGHT,
161       Shell::GetInstance()->display_manager()->
162           GetCurrentDisplayLayout().position);
163
164   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
165   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(900, 123));
166
167   // This emulates the dragging to the 2nd display, which has
168   // higher scale factor, by having 2nd display's root as target
169   // but have the edge of 1st display.
170   EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot(
171       root_windows[1], root_windows[1], gfx::Point(498, 123)));
172   EXPECT_EQ("502,123",
173             aura::Env::GetInstance()->last_mouse_location().ToString());
174
175   // Touch the edge of 2nd display again and make sure it warps to
176   // 1st dislay.
177   EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot(
178       root_windows[1], root_windows[1], gfx::Point(500, 123)));
179   EXPECT_EQ("496,123",
180             aura::Env::GetInstance()->last_mouse_location().ToString());
181
182   // Draging back from 1x to 2x.
183   EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot(
184       root_windows[1], root_windows[0], gfx::Point(500, 123)));
185   EXPECT_EQ("496,123",
186             aura::Env::GetInstance()->last_mouse_location().ToString());
187
188   UpdateDisplay("500x500*2,600x600");
189   // Draging back from 1x to 2x.
190   EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot(
191       root_windows[0], root_windows[1], gfx::Point(250, 123)));
192   EXPECT_EQ("246,123",
193             aura::Env::GetInstance()->last_mouse_location().ToString());
194 }
195
196 TEST_F(MouseCursorEventFilterTest, DoNotWarpTwice) {
197   if (!SupportsMultipleDisplays())
198     return;
199
200   UpdateDisplay("500x500,600x600");
201
202   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
203   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123));
204
205   // Touch the right edge of the primary root window. Pointer should warp.
206   EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessary(root_windows[0],
207                                                          gfx::Point(499, 11)));
208   EXPECT_EQ("501,11",  // by 2px.
209             aura::Env::GetInstance()->last_mouse_location().ToString());
210
211   // Touch the left edge of the secondary root window immediately. This should
212   // be ignored.
213   EXPECT_FALSE(event_filter()->WarpMouseCursorIfNecessary(root_windows[1],
214                                                           gfx::Point(500, 11)));
215
216   // Touch the left edge of the secondary root window again, pointer should
217   // warp for this time.
218   EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessary(root_windows[1],
219                                                          gfx::Point(500, 11)));
220   EXPECT_EQ("498,11",  // by 2px.
221             aura::Env::GetInstance()->last_mouse_location().ToString());
222 }
223
224 // Verifies if MouseCursorEventFilter::set_mouse_warp_mode() works as expected.
225 TEST_F(MouseCursorEventFilterTest, SetMouseWarpModeFlag) {
226   if (!SupportsMultipleDisplays())
227     return;
228
229   UpdateDisplay("500x500,500x500");
230
231   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
232   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(1, 1));
233
234   event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_NONE);
235   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0],
236                                           gfx::Point(499, 11)));
237   EXPECT_EQ("1,1",
238             aura::Env::GetInstance()->last_mouse_location().ToString());
239
240   event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_ALWAYS);
241   EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11)));
242   EXPECT_EQ("501,11",
243             aura::Env::GetInstance()->last_mouse_location().ToString());
244 }
245
246 // Verifies if MouseCursorEventFilter's bounds calculation works correctly.
247 TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnRight) {
248   if (!SupportsMultipleDisplays())
249     return;
250
251   UpdateDisplay("360x360,700x700");
252   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
253
254   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
255   DisplayLayout layout(DisplayLayout::RIGHT, 0);
256   display_manager->SetLayoutForCurrentDisplays(layout);
257   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
258   EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString());
259   EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
260   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
261   EXPECT_EQ("360,16 1x344", event_filter()->src_indicator_bounds_.ToString());
262   EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
263
264   // Move 2nd display downwards a bit.
265   layout.offset = 5;
266   display_manager->SetLayoutForCurrentDisplays(layout);
267   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
268   // This is same as before because the 2nd display's y is above
269   // the indicator's x.
270   EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString());
271   EXPECT_EQ("360,5 1x355", event_filter()->dst_indicator_bounds_.ToString());
272   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
273   EXPECT_EQ("360,21 1x339", event_filter()->src_indicator_bounds_.ToString());
274   EXPECT_EQ("359,5 1x355", event_filter()->dst_indicator_bounds_.ToString());
275
276   // Move it down further so that the shared edge is shorter than
277   // minimum hole size (160).
278   layout.offset = 200;
279   display_manager->SetLayoutForCurrentDisplays(layout);
280   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
281   EXPECT_EQ("359,200 1x160", event_filter()->src_indicator_bounds_.ToString());
282   EXPECT_EQ("360,200 1x160", event_filter()->dst_indicator_bounds_.ToString());
283   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
284   EXPECT_EQ("360,200 1x160", event_filter()->src_indicator_bounds_.ToString());
285   EXPECT_EQ("359,200 1x160", event_filter()->dst_indicator_bounds_.ToString());
286
287   // Now move 2nd display upwards
288   layout.offset = -5;
289   display_manager->SetLayoutForCurrentDisplays(layout);
290   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
291   EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString());
292   EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
293   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
294   // 16 px are reserved on 2nd display from top, so y must be
295   // (16 - 5) = 11
296   EXPECT_EQ("360,11 1x349", event_filter()->src_indicator_bounds_.ToString());
297   EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
298
299   event_filter()->HideSharedEdgeIndicator();
300 }
301
302 TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnLeft) {
303   if (!SupportsMultipleDisplays())
304     return;
305
306   UpdateDisplay("360x360,700x700");
307   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
308
309   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
310   DisplayLayout layout(DisplayLayout::LEFT, 0);
311   display_manager->SetLayoutForCurrentDisplays(layout);
312   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
313   EXPECT_EQ("0,16 1x344", event_filter()->src_indicator_bounds_.ToString());
314   EXPECT_EQ("-1,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
315   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
316   EXPECT_EQ("-1,16 1x344", event_filter()->src_indicator_bounds_.ToString());
317   EXPECT_EQ("0,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
318
319   layout.offset = 250;
320   display_manager->SetLayoutForCurrentDisplays(layout);
321   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
322   EXPECT_EQ("0,250 1x110", event_filter()->src_indicator_bounds_.ToString());
323   EXPECT_EQ("-1,250 1x110", event_filter()->dst_indicator_bounds_.ToString());
324   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
325   EXPECT_EQ("-1,250 1x110", event_filter()->src_indicator_bounds_.ToString());
326   EXPECT_EQ("0,250 1x110", event_filter()->dst_indicator_bounds_.ToString());
327   event_filter()->HideSharedEdgeIndicator();
328 }
329
330 TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnTopBottom) {
331   if (!SupportsMultipleDisplays())
332     return;
333
334   UpdateDisplay("360x360,700x700");
335   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
336
337   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
338   DisplayLayout layout(DisplayLayout::TOP, 0);
339   display_manager->SetLayoutForCurrentDisplays(layout);
340   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
341   EXPECT_EQ("0,0 360x1", event_filter()->src_indicator_bounds_.ToString());
342   EXPECT_EQ("0,-1 360x1", event_filter()->dst_indicator_bounds_.ToString());
343   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
344   EXPECT_EQ("0,-1 360x1", event_filter()->src_indicator_bounds_.ToString());
345   EXPECT_EQ("0,0 360x1", event_filter()->dst_indicator_bounds_.ToString());
346
347   layout.offset = 250;
348   display_manager->SetLayoutForCurrentDisplays(layout);
349   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
350   EXPECT_EQ("250,0 110x1", event_filter()->src_indicator_bounds_.ToString());
351   EXPECT_EQ("250,-1 110x1", event_filter()->dst_indicator_bounds_.ToString());
352   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
353   EXPECT_EQ("250,-1 110x1", event_filter()->src_indicator_bounds_.ToString());
354   EXPECT_EQ("250,0 110x1", event_filter()->dst_indicator_bounds_.ToString());
355
356   layout.position = DisplayLayout::BOTTOM;
357   layout.offset = 0;
358   display_manager->SetLayoutForCurrentDisplays(layout);
359   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
360   EXPECT_EQ("0,359 360x1", event_filter()->src_indicator_bounds_.ToString());
361   EXPECT_EQ("0,360 360x1", event_filter()->dst_indicator_bounds_.ToString());
362   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
363   EXPECT_EQ("0,360 360x1", event_filter()->src_indicator_bounds_.ToString());
364   EXPECT_EQ("0,359 360x1", event_filter()->dst_indicator_bounds_.ToString());
365
366   event_filter()->HideSharedEdgeIndicator();
367 }
368
369 // Verifies cursor's device scale factor is updated when a cursor has moved
370 // across root windows with different device scale factors
371 // (http://crbug.com/154183).
372 TEST_F(MouseCursorEventFilterTest, CursorDeviceScaleFactor) {
373   if (!SupportsMultipleDisplays())
374     return;
375
376   UpdateDisplay("400x400,800x800*2");
377   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
378   display_manager->SetLayoutForCurrentDisplays(
379       DisplayLayout(DisplayLayout::RIGHT, 0));
380   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
381   ASSERT_EQ(2U, root_windows.size());
382   test::CursorManagerTestApi cursor_test_api(
383       Shell::GetInstance()->cursor_manager());
384
385   EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor());
386   WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(399, 200));
387   EXPECT_EQ(2.0f, cursor_test_api.GetDisplay().device_scale_factor());
388   WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(400, 200));
389   EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor());
390 }
391
392 }  // namespace internal
393 }  // namespace ash