- add sources.
[platform/framework/web/crosswalk.git] / src / ash / display / root_window_transformers_unittest.cc
1 // Copyright 2013 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/root_window_transformers.h"
6
7 #include "ash/display/display_info.h"
8 #include "ash/display/display_manager.h"
9 #include "ash/launcher/launcher.h"
10 #include "ash/magnifier/magnification_controller.h"
11 #include "ash/screen_ash.h"
12 #include "ash/shelf/shelf_widget.h"
13 #include "ash/shell.h"
14 #include "ash/test/ash_test_base.h"
15 #include "ash/test/cursor_manager_test_api.h"
16 #include "ash/test/mirror_window_test_api.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "ui/aura/env.h"
19 #include "ui/aura/root_window.h"
20 #include "ui/aura/root_window_transformer.h"
21 #include "ui/aura/test/event_generator.h"
22 #include "ui/aura/window_tracker.h"
23 #include "ui/events/event_handler.h"
24 #include "ui/gfx/display.h"
25 #include "ui/gfx/rect_conversions.h"
26 #include "ui/gfx/screen.h"
27 #include "ui/views/widget/widget.h"
28
29 namespace ash {
30 namespace internal {
31
32 namespace {
33
34 const char kDesktopBackgroundView[] = "DesktopBackgroundView";
35
36 class TestEventHandler : public ui::EventHandler {
37  public:
38   TestEventHandler() : target_root_(NULL),
39                        touch_radius_x_(0.0),
40                        touch_radius_y_(0.0),
41                        scroll_x_offset_(0.0),
42                        scroll_y_offset_(0.0),
43                        scroll_x_offset_ordinal_(0.0),
44                        scroll_y_offset_ordinal_(0.0) {}
45   virtual ~TestEventHandler() {}
46
47   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
48     if (event->flags() & ui::EF_IS_SYNTHESIZED)
49       return;
50     aura::Window* target = static_cast<aura::Window*>(event->target());
51     mouse_location_ = event->root_location();
52     target_root_ = target->GetRootWindow();
53     event->StopPropagation();
54   }
55
56   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
57     aura::Window* target = static_cast<aura::Window*>(event->target());
58     // Only record when the target is the background which covers
59     // entire root window.
60     if (target->name() != kDesktopBackgroundView)
61       return;
62     touch_radius_x_ = event->radius_x();
63     touch_radius_y_ = event->radius_y();
64     event->StopPropagation();
65   }
66
67   virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
68     aura::Window* target = static_cast<aura::Window*>(event->target());
69     // Only record when the target is the background which covers
70     // entire root window.
71     if (target->name() != kDesktopBackgroundView)
72       return;
73
74     if (event->type() == ui::ET_SCROLL) {
75       scroll_x_offset_ = event->x_offset();
76       scroll_y_offset_ = event->y_offset();
77       scroll_x_offset_ordinal_ = event->x_offset_ordinal();
78       scroll_y_offset_ordinal_ = event->y_offset_ordinal();
79     }
80     event->StopPropagation();
81   }
82
83   std::string GetLocationAndReset() {
84     std::string result = mouse_location_.ToString();
85     mouse_location_.SetPoint(0, 0);
86     target_root_ = NULL;
87     return result;
88   }
89
90   float touch_radius_x() const { return touch_radius_x_; }
91   float touch_radius_y() const { return touch_radius_y_; }
92   float scroll_x_offset() const { return scroll_x_offset_; }
93   float scroll_y_offset() const { return scroll_y_offset_; }
94   float scroll_x_offset_ordinal() const { return scroll_x_offset_ordinal_; }
95   float scroll_y_offset_ordinal() const { return scroll_y_offset_ordinal_; }
96
97  private:
98   gfx::Point mouse_location_;
99   aura::Window* target_root_;
100
101   float touch_radius_x_;
102   float touch_radius_y_;
103   float scroll_x_offset_;
104   float scroll_y_offset_;
105   float scroll_x_offset_ordinal_;
106   float scroll_y_offset_ordinal_;
107
108   DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
109 };
110
111 gfx::Display::Rotation GetStoredRotation(int64 id) {
112   return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).rotation();
113 }
114
115 float GetStoredUIScale(int64 id) {
116   return Shell::GetInstance()->display_manager()->GetDisplayInfo(id).ui_scale();
117 }
118
119 }  // namespace
120
121 typedef test::AshTestBase RootWindowTransformersTest;
122
123 #if defined(OS_WIN)
124 // TODO(scottmg): RootWindow doesn't get resized on Windows
125 // Ash. http://crbug.com/247916.
126 #define MAYBE_RotateAndMagnify DISABLED_RotateAndMagniy
127 #define MAYBE_TouchScaleAndMagnify DISABLED_TouchScaleAndMagnify
128 #define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords
129 #else
130 #define MAYBE_RotateAndMagnify RotateAndMagniy
131 #define MAYBE_TouchScaleAndMagnify TouchScaleAndMagnify
132 #define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords
133 #endif
134
135 TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) {
136   MagnificationController* magnifier =
137       Shell::GetInstance()->magnification_controller();
138   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
139
140   TestEventHandler event_handler;
141   Shell::GetInstance()->AddPreTargetHandler(&event_handler);
142
143   UpdateDisplay("120x200,300x400*2");
144   gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
145   int64 display2_id = ScreenAsh::GetSecondaryDisplay().id();
146
147   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
148   aura::test::EventGenerator generator1(root_windows[0]);
149   aura::test::EventGenerator generator2(root_windows[1]);
150
151   magnifier->SetEnabled(true);
152   EXPECT_EQ(2.0f, magnifier->GetScale());
153   EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
154   EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
155   EXPECT_EQ("120,0 150x200",
156             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
157   generator1.MoveMouseToInHost(40, 80);
158   EXPECT_EQ("50,90", event_handler.GetLocationAndReset());
159   EXPECT_EQ("50,90",
160             aura::Env::GetInstance()->last_mouse_location().ToString());
161   EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display1.id()));
162   EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
163   magnifier->SetEnabled(false);
164
165   display_manager->SetDisplayRotation(display1.id(),
166                                       gfx::Display::ROTATE_90);
167   // Move the cursor to the center of the first root window.
168   generator1.MoveMouseToInHost(59, 100);
169
170   magnifier->SetEnabled(true);
171   EXPECT_EQ(2.0f, magnifier->GetScale());
172   EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
173   EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
174   EXPECT_EQ("200,0 150x200",
175             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
176   generator1.MoveMouseToInHost(39, 120);
177   EXPECT_EQ("110,70", event_handler.GetLocationAndReset());
178   EXPECT_EQ("110,70",
179             aura::Env::GetInstance()->last_mouse_location().ToString());
180   EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
181   EXPECT_EQ(gfx::Display::ROTATE_0, GetStoredRotation(display2_id));
182   magnifier->SetEnabled(false);
183
184   DisplayLayout display_layout(DisplayLayout::BOTTOM, 50);
185   display_manager->SetLayoutForCurrentDisplays(display_layout);
186   EXPECT_EQ("50,120 150x200",
187             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
188
189   display_manager->SetDisplayRotation(display2_id,
190                                       gfx::Display::ROTATE_270);
191   // Move the cursor to the center of the second root window.
192   generator2.MoveMouseToInHost(151, 199);
193
194   magnifier->SetEnabled(true);
195   EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
196   EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
197   EXPECT_EQ("50,120 200x150",
198             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
199   generator2.MoveMouseToInHost(172, 219);
200   EXPECT_EQ("95,80", event_handler.GetLocationAndReset());
201   EXPECT_EQ("145,200",
202             aura::Env::GetInstance()->last_mouse_location().ToString());
203   EXPECT_EQ(gfx::Display::ROTATE_90, GetStoredRotation(display1.id()));
204   EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
205   magnifier->SetEnabled(false);
206
207   display_manager->SetDisplayRotation(display1.id(),
208                                       gfx::Display::ROTATE_180);
209   // Move the cursor to the center of the first root window.
210   generator1.MoveMouseToInHost(59, 99);
211
212   magnifier->SetEnabled(true);
213   EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
214   EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
215   // Dislay must share at least 100, so the x's offset becomes 20.
216   EXPECT_EQ("20,200 200x150",
217             ScreenAsh::GetSecondaryDisplay().bounds().ToString());
218   generator1.MoveMouseToInHost(39, 59);
219   EXPECT_EQ("70,120", event_handler.GetLocationAndReset());
220   EXPECT_EQ(gfx::Display::ROTATE_180, GetStoredRotation(display1.id()));
221   EXPECT_EQ(gfx::Display::ROTATE_270, GetStoredRotation(display2_id));
222   magnifier->SetEnabled(false);
223
224   Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
225 }
226
227 TEST_F(RootWindowTransformersTest, ScaleAndMagnify) {
228   if (!SupportsMultipleDisplays())
229     return;
230
231   TestEventHandler event_handler;
232   Shell::GetInstance()->AddPreTargetHandler(&event_handler);
233
234   UpdateDisplay("600x400*2@1.5,500x300");
235
236   gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
237   gfx::Display::SetInternalDisplayId(display1.id());
238   gfx::Display display2 = ScreenAsh::GetSecondaryDisplay();
239   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
240   MagnificationController* magnifier =
241       Shell::GetInstance()->magnification_controller();
242
243   magnifier->SetEnabled(true);
244   EXPECT_EQ(2.0f, magnifier->GetScale());
245   EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
246   EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
247   EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
248   EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
249   EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
250
251   aura::test::EventGenerator generator(root_windows[0]);
252   generator.MoveMouseToInHost(500, 200);
253   EXPECT_EQ("299,150", event_handler.GetLocationAndReset());
254   magnifier->SetEnabled(false);
255
256   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
257   display_manager->SetDisplayUIScale(display1.id(), 1.25);
258   display1 = Shell::GetScreen()->GetPrimaryDisplay();
259   display2 = ScreenAsh::GetSecondaryDisplay();
260   magnifier->SetEnabled(true);
261   EXPECT_EQ(2.0f, magnifier->GetScale());
262   EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
263   EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
264   EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
265   EXPECT_EQ(1.25f, GetStoredUIScale(display1.id()));
266   EXPECT_EQ(1.0f, GetStoredUIScale(display2.id()));
267   magnifier->SetEnabled(false);
268
269   Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
270 }
271
272 TEST_F(RootWindowTransformersTest, MAYBE_TouchScaleAndMagnify) {
273   TestEventHandler event_handler;
274   Shell::GetInstance()->AddPreTargetHandler(&event_handler);
275
276   UpdateDisplay("200x200*2");
277   gfx::Display display = Shell::GetScreen()->GetPrimaryDisplay();
278   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
279   aura::RootWindow* root_window = root_windows[0];
280   aura::test::EventGenerator generator(root_window);
281   MagnificationController* magnifier =
282       Shell::GetInstance()->magnification_controller();
283
284   magnifier->SetEnabled(true);
285   EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
286   magnifier->SetScale(2.5f, false);
287   EXPECT_FLOAT_EQ(2.5f, magnifier->GetScale());
288   generator.PressMoveAndReleaseTouchTo(50, 50);
289   // Default test touches have radius_x/y = 1.0, with device scale
290   // factor = 2, the scaled radius_x/y should be 0.5.
291   EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_x());
292   EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_y());
293
294   generator.ScrollSequence(gfx::Point(0,0),
295                            base::TimeDelta::FromMilliseconds(100),
296                            10.0, 1.0, 5, 1);
297
298   // ordinal_offset is invariant to the device scale factor.
299   EXPECT_FLOAT_EQ(event_handler.scroll_x_offset(),
300                   event_handler.scroll_x_offset_ordinal());
301   EXPECT_FLOAT_EQ(event_handler.scroll_y_offset(),
302                   event_handler.scroll_y_offset_ordinal());
303   magnifier->SetEnabled(false);
304
305   Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
306 }
307
308 TEST_F(RootWindowTransformersTest, MAYBE_ConvertHostToRootCoords) {
309   TestEventHandler event_handler;
310   Shell::GetInstance()->AddPreTargetHandler(&event_handler);
311   MagnificationController* magnifier =
312       Shell::GetInstance()->magnification_controller();
313
314   // Test 1
315   UpdateDisplay("600x400*2/r@1.5");
316
317   gfx::Display display1 = Shell::GetScreen()->GetPrimaryDisplay();
318   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
319   EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
320   EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
321   EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
322
323   aura::test::EventGenerator generator(root_windows[0]);
324   generator.MoveMouseToInHost(300, 200);
325   magnifier->SetEnabled(true);
326   EXPECT_EQ("150,224", event_handler.GetLocationAndReset());
327   EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
328
329   generator.MoveMouseToInHost(300, 200);
330   EXPECT_EQ("150,224", event_handler.GetLocationAndReset());
331   generator.MoveMouseToInHost(200, 300);
332   EXPECT_EQ("187,261", event_handler.GetLocationAndReset());
333   generator.MoveMouseToInHost(100, 400);
334   EXPECT_EQ("237,299", event_handler.GetLocationAndReset());
335   generator.MoveMouseToInHost(0, 0);
336   EXPECT_EQ("137,348", event_handler.GetLocationAndReset());
337
338   magnifier->SetEnabled(false);
339   EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
340
341   // Test 2
342   UpdateDisplay("600x400*2/u@1.5");
343   display1 = Shell::GetScreen()->GetPrimaryDisplay();
344   root_windows = Shell::GetAllRootWindows();
345   EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
346   EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
347   EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
348
349   generator.MoveMouseToInHost(300, 200);
350   magnifier->SetEnabled(true);
351   EXPECT_EQ("224,149", event_handler.GetLocationAndReset());
352   EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
353
354   generator.MoveMouseToInHost(300, 200);
355   EXPECT_EQ("224,148", event_handler.GetLocationAndReset());
356   generator.MoveMouseToInHost(200, 300);
357   EXPECT_EQ("261,111", event_handler.GetLocationAndReset());
358   generator.MoveMouseToInHost(100, 400);
359   EXPECT_EQ("299,60", event_handler.GetLocationAndReset());
360   generator.MoveMouseToInHost(0, 0);
361   EXPECT_EQ("348,159", event_handler.GetLocationAndReset());
362
363   magnifier->SetEnabled(false);
364   EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
365
366   // Test 3
367   UpdateDisplay("600x400*2/l@1.5");
368   display1 = Shell::GetScreen()->GetPrimaryDisplay();
369   root_windows = Shell::GetAllRootWindows();
370   EXPECT_EQ("0,0 300x450", display1.bounds().ToString());
371   EXPECT_EQ("0,0 300x450", root_windows[0]->bounds().ToString());
372   EXPECT_EQ(1.5f, GetStoredUIScale(display1.id()));
373
374   generator.MoveMouseToInHost(300, 200);
375   magnifier->SetEnabled(true);
376   EXPECT_EQ("149,225", event_handler.GetLocationAndReset());
377   EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
378
379   generator.MoveMouseToInHost(300, 200);
380   EXPECT_EQ("148,224", event_handler.GetLocationAndReset());
381   generator.MoveMouseToInHost(200, 300);
382   EXPECT_EQ("111,187", event_handler.GetLocationAndReset());
383   generator.MoveMouseToInHost(100, 400);
384   EXPECT_EQ("60,149", event_handler.GetLocationAndReset());
385   generator.MoveMouseToInHost(0, 0);
386   EXPECT_EQ("159,99", event_handler.GetLocationAndReset());
387
388   magnifier->SetEnabled(false);
389   EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
390
391   Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
392 }
393
394 TEST_F(RootWindowTransformersTest, LetterBoxPillarBox) {
395   if (!SupportsMultipleDisplays())
396     return;
397   test::MirrorWindowTestApi test_api;
398   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
399   display_manager->SetSecondDisplayMode(DisplayManager::MIRRORING);
400   UpdateDisplay("400x200,500x500");
401   scoped_ptr<aura::RootWindowTransformer> transformer(
402       test_api.CreateCurrentRootWindowTransformer());
403   // Y margin must be margin is (500 - 500/400 * 200) / 2 = 125.
404   EXPECT_EQ("0,125,0,125", transformer->GetHostInsets().ToString());
405
406   UpdateDisplay("200x400,500x500");
407   // The aspect ratio is flipped, so X margin is now 125.
408   transformer = test_api.CreateCurrentRootWindowTransformer();
409   EXPECT_EQ("125,0,125,0", transformer->GetHostInsets().ToString());
410 }
411
412 }  // namespace test
413 }  // namespace ash