1 // Copyright (c) 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/ash_root_window_transformer.h"
7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_info.h"
9 #include "ash/display/display_manager.h"
10 #include "ash/launcher/launcher.h"
11 #include "ash/magnifier/magnification_controller.h"
12 #include "ash/screen_ash.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 "base/synchronization/waitable_event.h"
18 #include "ui/aura/env.h"
19 #include "ui/aura/root_window.h"
20 #include "ui/aura/test/event_generator.h"
21 #include "ui/aura/window_tracker.h"
22 #include "ui/base/events/event_handler.h"
23 #include "ui/gfx/display.h"
24 #include "ui/gfx/rect_conversions.h"
25 #include "ui/gfx/screen.h"
26 #include "ui/views/widget/widget.h"
33 const char kDesktopBackgroundView
[] = "DesktopBackgroundView";
35 class TestEventHandler
: public ui::EventHandler
{
37 TestEventHandler() : target_root_(NULL
),
40 scroll_x_offset_(0.0),
41 scroll_y_offset_(0.0),
42 scroll_x_offset_ordinal_(0.0),
43 scroll_y_offset_ordinal_(0.0) {}
44 virtual ~TestEventHandler() {}
46 virtual void OnMouseEvent(ui::MouseEvent
* event
) OVERRIDE
{
47 if (event
->flags() & ui::EF_IS_SYNTHESIZED
)
49 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
50 mouse_location_
= event
->root_location();
51 target_root_
= target
->GetRootWindow();
52 event
->StopPropagation();
55 virtual void OnTouchEvent(ui::TouchEvent
* event
) OVERRIDE
{
56 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
57 // Only record when the target is the background which covers
58 // entire root window.
59 if (target
->name() != kDesktopBackgroundView
)
61 touch_radius_x_
= event
->radius_x();
62 touch_radius_y_
= event
->radius_y();
63 event
->StopPropagation();
66 virtual void OnScrollEvent(ui::ScrollEvent
* event
) OVERRIDE
{
67 aura::Window
* target
= static_cast<aura::Window
*>(event
->target());
68 // Only record when the target is the background which covers
69 // entire root window.
70 if (target
->name() != kDesktopBackgroundView
)
73 if (event
->type() == ui::ET_SCROLL
) {
74 scroll_x_offset_
= event
->x_offset();
75 scroll_y_offset_
= event
->y_offset();
76 scroll_x_offset_ordinal_
= event
->x_offset_ordinal();
77 scroll_y_offset_ordinal_
= event
->y_offset_ordinal();
79 event
->StopPropagation();
82 std::string
GetLocationAndReset() {
83 std::string result
= mouse_location_
.ToString();
84 mouse_location_
.SetPoint(0, 0);
89 float touch_radius_x() const { return touch_radius_x_
; }
90 float touch_radius_y() const { return touch_radius_y_
; }
91 float scroll_x_offset() const { return scroll_x_offset_
; }
92 float scroll_y_offset() const { return scroll_y_offset_
; }
93 float scroll_x_offset_ordinal() const { return scroll_x_offset_ordinal_
; }
94 float scroll_y_offset_ordinal() const { return scroll_y_offset_ordinal_
; }
97 gfx::Point mouse_location_
;
98 aura::RootWindow
* target_root_
;
100 float touch_radius_x_
;
101 float touch_radius_y_
;
102 float scroll_x_offset_
;
103 float scroll_y_offset_
;
104 float scroll_x_offset_ordinal_
;
105 float scroll_y_offset_ordinal_
;
107 DISALLOW_COPY_AND_ASSIGN(TestEventHandler
);
110 gfx::Display::Rotation
GetStoredRotation(int64 id
) {
111 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id
).rotation();
114 float GetStoredUIScale(int64 id
) {
115 return Shell::GetInstance()->display_manager()->GetDisplayInfo(id
).ui_scale();
120 typedef test::AshTestBase AshRootWindowTransformerTest
;
123 // On Win8 bots, the host window can't be resized and
124 // SetTransform updates the window using the orignal host window
126 #define MAYBE_RotateAndMagnify DISABLED_RotateAndMagniy
127 #define MAYBE_ScaleAndMagnify DISABLED_ScaleAndMagnify
128 #define MAYBE_TouchScaleAndMagnify DISABLED_TouchScaleAndMagnify
129 #define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords
131 #define MAYBE_RotateAndMagnify RotateAndMagniy
132 #define MAYBE_ScaleAndMagnify ScaleAndMagnify
133 #define MAYBE_TouchScaleAndMagnify TouchScaleAndMagnify
134 #define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords
137 TEST_F(AshRootWindowTransformerTest
, MAYBE_RotateAndMagnify
) {
138 DisplayController
* display_controller
=
139 Shell::GetInstance()->display_controller();
140 MagnificationController
* magnifier
=
141 Shell::GetInstance()->magnification_controller();
142 internal::DisplayManager
* display_manager
=
143 Shell::GetInstance()->display_manager();
145 TestEventHandler event_handler
;
146 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
148 UpdateDisplay("120x200,300x400*2");
149 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
150 int64 display2_id
= ScreenAsh::GetSecondaryDisplay().id();
152 Shell::RootWindowList root_windows
= Shell::GetAllRootWindows();
153 aura::test::EventGenerator
generator1(root_windows
[0]);
154 aura::test::EventGenerator
generator2(root_windows
[1]);
156 magnifier
->SetEnabled(true);
157 EXPECT_EQ(2.0f
, magnifier
->GetScale());
158 EXPECT_EQ("120x200", root_windows
[0]->bounds().size().ToString());
159 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
160 EXPECT_EQ("120,0 150x200",
161 ScreenAsh::GetSecondaryDisplay().bounds().ToString());
162 generator1
.MoveMouseToInHost(40, 80);
163 EXPECT_EQ("50,90", event_handler
.GetLocationAndReset());
165 aura::Env::GetInstance()->last_mouse_location().ToString());
166 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display1
.id()));
167 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display2_id
));
168 magnifier
->SetEnabled(false);
170 display_manager
->SetDisplayRotation(display1
.id(),
171 gfx::Display::ROTATE_90
);
172 // Move the cursor to the center of the first root window.
173 generator1
.MoveMouseToInHost(59, 100);
175 magnifier
->SetEnabled(true);
176 EXPECT_EQ(2.0f
, magnifier
->GetScale());
177 EXPECT_EQ("200x120", root_windows
[0]->bounds().size().ToString());
178 EXPECT_EQ("150x200", root_windows
[1]->bounds().size().ToString());
179 EXPECT_EQ("200,0 150x200",
180 ScreenAsh::GetSecondaryDisplay().bounds().ToString());
181 generator1
.MoveMouseToInHost(39, 120);
182 EXPECT_EQ("110,70", event_handler
.GetLocationAndReset());
184 aura::Env::GetInstance()->last_mouse_location().ToString());
185 EXPECT_EQ(gfx::Display::ROTATE_90
, GetStoredRotation(display1
.id()));
186 EXPECT_EQ(gfx::Display::ROTATE_0
, GetStoredRotation(display2_id
));
187 magnifier
->SetEnabled(false);
189 DisplayLayout
display_layout(DisplayLayout::BOTTOM
, 50);
190 display_controller
->SetLayoutForCurrentDisplays(display_layout
);
191 EXPECT_EQ("50,120 150x200",
192 ScreenAsh::GetSecondaryDisplay().bounds().ToString());
194 display_manager
->SetDisplayRotation(display2_id
,
195 gfx::Display::ROTATE_270
);
196 // Move the cursor to the center of the second root window.
197 generator2
.MoveMouseToInHost(151, 199);
199 magnifier
->SetEnabled(true);
200 EXPECT_EQ("200x120", root_windows
[0]->bounds().size().ToString());
201 EXPECT_EQ("200x150", root_windows
[1]->bounds().size().ToString());
202 EXPECT_EQ("50,120 200x150",
203 ScreenAsh::GetSecondaryDisplay().bounds().ToString());
204 generator2
.MoveMouseToInHost(172, 219);
205 EXPECT_EQ("95,80", event_handler
.GetLocationAndReset());
207 aura::Env::GetInstance()->last_mouse_location().ToString());
208 EXPECT_EQ(gfx::Display::ROTATE_90
, GetStoredRotation(display1
.id()));
209 EXPECT_EQ(gfx::Display::ROTATE_270
, GetStoredRotation(display2_id
));
210 magnifier
->SetEnabled(false);
212 display_manager
->SetDisplayRotation(display1
.id(),
213 gfx::Display::ROTATE_180
);
214 // Move the cursor to the center of the first root window.
215 generator1
.MoveMouseToInHost(59, 99);
217 magnifier
->SetEnabled(true);
218 EXPECT_EQ("120x200", root_windows
[0]->bounds().size().ToString());
219 EXPECT_EQ("200x150", root_windows
[1]->bounds().size().ToString());
220 // Dislay must share at least 100, so the x's offset becomes 20.
221 EXPECT_EQ("20,200 200x150",
222 ScreenAsh::GetSecondaryDisplay().bounds().ToString());
223 generator1
.MoveMouseToInHost(39, 59);
224 EXPECT_EQ("70,120", event_handler
.GetLocationAndReset());
225 EXPECT_EQ(gfx::Display::ROTATE_180
, GetStoredRotation(display1
.id()));
226 EXPECT_EQ(gfx::Display::ROTATE_270
, GetStoredRotation(display2_id
));
227 magnifier
->SetEnabled(false);
229 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
232 TEST_F(AshRootWindowTransformerTest
, MAYBE_ScaleAndMagnify
) {
233 TestEventHandler event_handler
;
234 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
236 UpdateDisplay("600x400*2@1.5,500x300");
238 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
239 gfx::Display::SetInternalDisplayId(display1
.id());
240 gfx::Display display2
= ScreenAsh::GetSecondaryDisplay();
241 Shell::RootWindowList root_windows
= Shell::GetAllRootWindows();
242 MagnificationController
* magnifier
=
243 Shell::GetInstance()->magnification_controller();
245 magnifier
->SetEnabled(true);
246 EXPECT_EQ(2.0f
, magnifier
->GetScale());
247 EXPECT_EQ("0,0 450x300", display1
.bounds().ToString());
248 EXPECT_EQ("0,0 450x300", root_windows
[0]->bounds().ToString());
249 EXPECT_EQ("450,0 500x300", display2
.bounds().ToString());
250 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
251 EXPECT_EQ(1.0f
, GetStoredUIScale(display2
.id()));
253 aura::test::EventGenerator
generator(root_windows
[0]);
254 generator
.MoveMouseToInHost(500, 200);
255 EXPECT_EQ("299,150", event_handler
.GetLocationAndReset());
256 magnifier
->SetEnabled(false);
258 internal::DisplayManager
* display_manager
=
259 Shell::GetInstance()->display_manager();
260 display_manager
->SetDisplayUIScale(display1
.id(), 1.25);
261 display1
= Shell::GetScreen()->GetPrimaryDisplay();
262 display2
= ScreenAsh::GetSecondaryDisplay();
263 magnifier
->SetEnabled(true);
264 EXPECT_EQ(2.0f
, magnifier
->GetScale());
265 EXPECT_EQ("0,0 375x250", display1
.bounds().ToString());
266 EXPECT_EQ("0,0 375x250", root_windows
[0]->bounds().ToString());
267 EXPECT_EQ("375,0 500x300", display2
.bounds().ToString());
268 EXPECT_EQ(1.25f
, GetStoredUIScale(display1
.id()));
269 EXPECT_EQ(1.0f
, GetStoredUIScale(display2
.id()));
270 magnifier
->SetEnabled(false);
272 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
275 TEST_F(AshRootWindowTransformerTest
, MAYBE_TouchScaleAndMagnify
) {
276 TestEventHandler event_handler
;
277 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
279 UpdateDisplay("200x200*2");
280 gfx::Display display
= Shell::GetScreen()->GetPrimaryDisplay();
281 Shell::RootWindowList root_windows
= Shell::GetAllRootWindows();
282 aura::RootWindow
* root_window
= root_windows
[0];
283 aura::test::EventGenerator
generator(root_window
);
284 MagnificationController
* magnifier
=
285 Shell::GetInstance()->magnification_controller();
287 magnifier
->SetEnabled(true);
288 EXPECT_FLOAT_EQ(2.0f
, magnifier
->GetScale());
289 magnifier
->SetScale(2.5f
, false);
290 EXPECT_FLOAT_EQ(2.5f
, magnifier
->GetScale());
291 generator
.PressMoveAndReleaseTouchTo(50, 50);
292 // Default test touches have radius_x/y = 1.0, with device scale
293 // factor = 2, the scaled radius_x/y should be 0.5.
294 EXPECT_FLOAT_EQ(0.2, event_handler
.touch_radius_x());
295 EXPECT_FLOAT_EQ(0.2, event_handler
.touch_radius_y());
297 generator
.ScrollSequence(gfx::Point(0,0),
298 base::TimeDelta::FromMilliseconds(100),
301 // With device scale factor = 2, ordinal_offset * 2 = offset.
302 EXPECT_FLOAT_EQ(event_handler
.scroll_x_offset(),
303 event_handler
.scroll_x_offset_ordinal() * 2 * 2.5f
);
304 EXPECT_FLOAT_EQ(event_handler
.scroll_y_offset(),
305 event_handler
.scroll_y_offset_ordinal() * 2 * 2.5f
);
306 magnifier
->SetEnabled(false);
308 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);
311 TEST_F(AshRootWindowTransformerTest
, MAYBE_ConvertHostToRootCoords
) {
312 TestEventHandler event_handler
;
313 Shell::GetInstance()->AddPreTargetHandler(&event_handler
);
314 MagnificationController
* magnifier
=
315 Shell::GetInstance()->magnification_controller();
318 UpdateDisplay("600x400*2/r@1.5");
320 gfx::Display display1
= Shell::GetScreen()->GetPrimaryDisplay();
321 Shell::RootWindowList root_windows
= Shell::GetAllRootWindows();
322 EXPECT_EQ("0,0 300x450", display1
.bounds().ToString());
323 EXPECT_EQ("0,0 300x450", root_windows
[0]->bounds().ToString());
324 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
326 aura::test::EventGenerator
generator(root_windows
[0]);
327 generator
.MoveMouseToInHost(300, 200);
328 magnifier
->SetEnabled(true);
329 EXPECT_EQ("150,224", event_handler
.GetLocationAndReset());
330 EXPECT_FLOAT_EQ(2.0f
, magnifier
->GetScale());
332 generator
.MoveMouseToInHost(300, 200);
333 EXPECT_EQ("150,224", event_handler
.GetLocationAndReset());
334 generator
.MoveMouseToInHost(200, 300);
335 EXPECT_EQ("187,261", event_handler
.GetLocationAndReset());
336 generator
.MoveMouseToInHost(100, 400);
337 EXPECT_EQ("237,299", event_handler
.GetLocationAndReset());
338 generator
.MoveMouseToInHost(0, 0);
339 EXPECT_EQ("137,348", event_handler
.GetLocationAndReset());
341 magnifier
->SetEnabled(false);
342 EXPECT_FLOAT_EQ(1.0f
, magnifier
->GetScale());
345 UpdateDisplay("600x400*2/u@1.5");
346 display1
= Shell::GetScreen()->GetPrimaryDisplay();
347 root_windows
= Shell::GetAllRootWindows();
348 EXPECT_EQ("0,0 450x300", display1
.bounds().ToString());
349 EXPECT_EQ("0,0 450x300", root_windows
[0]->bounds().ToString());
350 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
352 generator
.MoveMouseToInHost(300, 200);
353 magnifier
->SetEnabled(true);
354 EXPECT_EQ("224,149", event_handler
.GetLocationAndReset());
355 EXPECT_FLOAT_EQ(2.0f
, magnifier
->GetScale());
357 generator
.MoveMouseToInHost(300, 200);
358 EXPECT_EQ("224,148", event_handler
.GetLocationAndReset());
359 generator
.MoveMouseToInHost(200, 300);
360 EXPECT_EQ("261,111", event_handler
.GetLocationAndReset());
361 generator
.MoveMouseToInHost(100, 400);
362 EXPECT_EQ("299,60", event_handler
.GetLocationAndReset());
363 generator
.MoveMouseToInHost(0, 0);
364 EXPECT_EQ("348,159", event_handler
.GetLocationAndReset());
366 magnifier
->SetEnabled(false);
367 EXPECT_FLOAT_EQ(1.0f
, magnifier
->GetScale());
370 UpdateDisplay("600x400*2/l@1.5");
371 display1
= Shell::GetScreen()->GetPrimaryDisplay();
372 root_windows
= Shell::GetAllRootWindows();
373 EXPECT_EQ("0,0 300x450", display1
.bounds().ToString());
374 EXPECT_EQ("0,0 300x450", root_windows
[0]->bounds().ToString());
375 EXPECT_EQ(1.5f
, GetStoredUIScale(display1
.id()));
377 generator
.MoveMouseToInHost(300, 200);
378 magnifier
->SetEnabled(true);
379 EXPECT_EQ("149,225", event_handler
.GetLocationAndReset());
380 EXPECT_FLOAT_EQ(2.0f
, magnifier
->GetScale());
382 generator
.MoveMouseToInHost(300, 200);
383 EXPECT_EQ("148,224", event_handler
.GetLocationAndReset());
384 generator
.MoveMouseToInHost(200, 300);
385 EXPECT_EQ("111,187", event_handler
.GetLocationAndReset());
386 generator
.MoveMouseToInHost(100, 400);
387 EXPECT_EQ("60,149", event_handler
.GetLocationAndReset());
388 generator
.MoveMouseToInHost(0, 0);
389 EXPECT_EQ("159,99", event_handler
.GetLocationAndReset());
391 magnifier
->SetEnabled(false);
392 EXPECT_FLOAT_EQ(1.0f
, magnifier
->GetScale());
394 Shell::GetInstance()->RemovePreTargetHandler(&event_handler
);