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