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 <memory>
8
9 #include "ash/display/display_util.h"
10 #include "ash/display/mirror_window_test_api.h"
11 #include "ash/host/root_window_transformer.h"
12 #include "ash/magnifier/magnification_controller.h"
13 #include "ash/screen_util.h"
14 #include "ash/shelf/shelf_widget.h"
15 #include "ash/shell.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/wm/cursor_manager_test_api.h"
18 #include "base/command_line.h"
19 #include "base/synchronization/waitable_event.h"
20 #include "ui/aura/env.h"
21 #include "ui/aura/window_event_dispatcher.h"
22 #include "ui/aura/window_tracker.h"
23 #include "ui/aura/window_tree_host.h"
24 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
25 #include "ui/compositor/scoped_layer_animation_settings.h"
26 #include "ui/display/display.h"
27 #include "ui/display/display_layout.h"
28 #include "ui/display/display_switches.h"
29 #include "ui/display/manager/display_manager.h"
30 #include "ui/display/manager/managed_display_info.h"
31 #include "ui/display/screen.h"
32 #include "ui/display/test/display_manager_test_api.h"
33 #include "ui/events/event_handler.h"
34 #include "ui/events/test/event_generator.h"
35 #include "ui/gfx/geometry/rect_conversions.h"
36 #include "ui/gfx/geometry/rect_f.h"
37 #include "ui/views/widget/widget.h"
38
39 namespace ash {
40 namespace {
41
42 const char kWallpaperView[] = "WallpaperViewWidget";
43
44 class TestEventHandler : public ui::EventHandler {
45 public:
TestEventHandler()46 TestEventHandler()
47 : target_root_(nullptr),
48 touch_radius_x_(0.0),
49 touch_radius_y_(0.0),
50 scroll_x_offset_(0.0),
51 scroll_y_offset_(0.0),
52 scroll_x_offset_ordinal_(0.0),
53 scroll_y_offset_ordinal_(0.0) {}
54 ~TestEventHandler() override = default;
55
OnMouseEvent(ui::MouseEvent * event)56 void OnMouseEvent(ui::MouseEvent* event) override {
57 if (event->flags() & ui::EF_IS_SYNTHESIZED)
58 return;
59 aura::Window* target = static_cast<aura::Window*>(event->target());
60 mouse_location_ = event->root_location();
61 target_root_ = target->GetRootWindow();
62 event->StopPropagation();
63 }
64
OnTouchEvent(ui::TouchEvent * event)65 void OnTouchEvent(ui::TouchEvent* event) override {
66 aura::Window* target = static_cast<aura::Window*>(event->target());
67 // Only record when the target is the wallpaper, which covers the entire
68 // root window.
69 if (target->GetName() != kWallpaperView)
70 return;
71 touch_radius_x_ = event->pointer_details().radius_x;
72 touch_radius_y_ = event->pointer_details().radius_y;
73 event->StopPropagation();
74 }
75
OnScrollEvent(ui::ScrollEvent * event)76 void OnScrollEvent(ui::ScrollEvent* event) override {
77 aura::Window* target = static_cast<aura::Window*>(event->target());
78 // Only record when the target is the wallpaper, which covers the entire
79 // root window.
80 if (target->GetName() != kWallpaperView)
81 return;
82
83 if (event->type() == ui::ET_SCROLL) {
84 scroll_x_offset_ = event->x_offset();
85 scroll_y_offset_ = event->y_offset();
86 scroll_x_offset_ordinal_ = event->x_offset_ordinal();
87 scroll_y_offset_ordinal_ = event->y_offset_ordinal();
88 }
89 event->StopPropagation();
90 }
91
GetLocationAndReset()92 std::string GetLocationAndReset() {
93 std::string result = mouse_location_.ToString();
94 mouse_location_.SetPoint(0, 0);
95 target_root_ = nullptr;
96 return result;
97 }
98
touch_radius_x() const99 float touch_radius_x() const { return touch_radius_x_; }
touch_radius_y() const100 float touch_radius_y() const { return touch_radius_y_; }
scroll_x_offset() const101 float scroll_x_offset() const { return scroll_x_offset_; }
scroll_y_offset() const102 float scroll_y_offset() const { return scroll_y_offset_; }
scroll_x_offset_ordinal() const103 float scroll_x_offset_ordinal() const { return scroll_x_offset_ordinal_; }
scroll_y_offset_ordinal() const104 float scroll_y_offset_ordinal() const { return scroll_y_offset_ordinal_; }
105
106 private:
107 gfx::Point mouse_location_;
108 aura::Window* target_root_;
109
110 float touch_radius_x_;
111 float touch_radius_y_;
112 float scroll_x_offset_;
113 float scroll_y_offset_;
114 float scroll_x_offset_ordinal_;
115 float scroll_y_offset_ordinal_;
116
117 DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
118 };
119
120 class RootWindowTransformersTest : public AshTestBase {
121 public:
122 RootWindowTransformersTest() = default;
123 ~RootWindowTransformersTest() override = default;
124
GetStoredZoomScale(int64_t id)125 float GetStoredZoomScale(int64_t id) {
126 return display_manager()->GetDisplayInfo(id).zoom_factor();
127 }
128
129 std::unique_ptr<RootWindowTransformer>
CreateCurrentRootWindowTransformerForMirroring()130 CreateCurrentRootWindowTransformerForMirroring() {
131 DCHECK(display_manager()->IsInMirrorMode());
132 const display::ManagedDisplayInfo& mirror_display_info =
133 display_manager()->GetDisplayInfo(
134 display_manager()->GetMirroringDestinationDisplayIdList()[0]);
135 const display::ManagedDisplayInfo& source_display_info =
136 display_manager()->GetDisplayInfo(
137 display::Screen::GetScreen()->GetPrimaryDisplay().id());
138 return std::unique_ptr<RootWindowTransformer>(
139 CreateRootWindowTransformerForMirroredDisplay(source_display_info,
140 mirror_display_info));
141 }
142
143 DISALLOW_COPY_AND_ASSIGN(RootWindowTransformersTest);
144 };
145
146 class UnfiedRootWindowTransformersTest : public RootWindowTransformersTest {
147 public:
148 UnfiedRootWindowTransformersTest() = default;
149 ~UnfiedRootWindowTransformersTest() override = default;
150
151 // RootWindowTransformersTest:
SetUp()152 void SetUp() override {
153 // kEnableUnifiedDesktop switch needs to be added before DisplayManager
154 // creation. Hence before calling SetUp.
155 base::CommandLine::ForCurrentProcess()->AppendSwitch(
156 switches::kEnableUnifiedDesktop);
157
158 RootWindowTransformersTest::SetUp();
159 }
160
161 DISALLOW_COPY_AND_ASSIGN(UnfiedRootWindowTransformersTest);
162 };
163
164 } // namespace
165
TEST_F(RootWindowTransformersTest,RotateAndMagnify)166 TEST_F(RootWindowTransformersTest, RotateAndMagnify) {
167 MagnificationController* magnifier = Shell::Get()->magnification_controller();
168
169 TestEventHandler event_handler;
170 Shell::Get()->AddPreTargetHandler(&event_handler);
171
172 UpdateDisplay("120x200,300x400*2");
173 display::test::DisplayManagerTestApi display_manager_test(display_manager());
174 display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
175 int64_t display2_id = display_manager_test.GetSecondaryDisplay().id();
176
177 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
178 ui::test::EventGenerator generator1(root_windows[0]);
179 ui::test::EventGenerator generator2(root_windows[1]);
180
181 magnifier->SetEnabled(true);
182 EXPECT_EQ(2.0f, magnifier->GetScale());
183 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
184 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
185 EXPECT_EQ("120,0 150x200",
186 display_manager_test.GetSecondaryDisplay().bounds().ToString());
187 generator1.MoveMouseToInHost(40, 80);
188 EXPECT_EQ("50,90", event_handler.GetLocationAndReset());
189 EXPECT_EQ("50,90",
190 aura::Env::GetInstance()->last_mouse_location().ToString());
191 EXPECT_EQ(display::Display::ROTATE_0,
192 GetActiveDisplayRotation(display1.id()));
193 EXPECT_EQ(display::Display::ROTATE_0, GetActiveDisplayRotation(display2_id));
194 magnifier->SetEnabled(false);
195
196 display_manager()->SetDisplayRotation(
197 display1.id(), display::Display::ROTATE_90,
198 display::Display::RotationSource::ACTIVE);
199 // Move the cursor to the center of the first root window.
200 generator1.MoveMouseToInHost(59, 100);
201
202 magnifier->SetEnabled(true);
203 EXPECT_EQ(2.0f, magnifier->GetScale());
204 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
205 EXPECT_EQ("150x200", root_windows[1]->bounds().size().ToString());
206 EXPECT_EQ("200,0 150x200",
207 display_manager_test.GetSecondaryDisplay().bounds().ToString());
208 generator1.MoveMouseToInHost(39, 120);
209 EXPECT_EQ("110,70", event_handler.GetLocationAndReset());
210 EXPECT_EQ("110,70",
211 aura::Env::GetInstance()->last_mouse_location().ToString());
212 EXPECT_EQ(display::Display::ROTATE_90,
213 GetActiveDisplayRotation(display1.id()));
214 EXPECT_EQ(display::Display::ROTATE_0, GetActiveDisplayRotation(display2_id));
215 magnifier->SetEnabled(false);
216
217 display_manager()->SetLayoutForCurrentDisplays(
218 display::test::CreateDisplayLayout(
219 display_manager(), display::DisplayPlacement::BOTTOM, 50));
220 EXPECT_EQ("50,120 150x200",
221 display_manager_test.GetSecondaryDisplay().bounds().ToString());
222
223 display_manager()->SetDisplayRotation(
224 display2_id, display::Display::ROTATE_270,
225 display::Display::RotationSource::ACTIVE);
226 // Move the cursor to the center of the second root window.
227 generator2.MoveMouseToInHost(151, 199);
228
229 magnifier->SetEnabled(true);
230 EXPECT_EQ("200x120", root_windows[0]->bounds().size().ToString());
231 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
232 EXPECT_EQ("50,120 200x150",
233 display_manager_test.GetSecondaryDisplay().bounds().ToString());
234 generator2.MoveMouseToInHost(172, 219);
235 EXPECT_EQ("95,80", event_handler.GetLocationAndReset());
236 EXPECT_EQ("145,200",
237 aura::Env::GetInstance()->last_mouse_location().ToString());
238 EXPECT_EQ(display::Display::ROTATE_90,
239 GetActiveDisplayRotation(display1.id()));
240 EXPECT_EQ(display::Display::ROTATE_270,
241 GetActiveDisplayRotation(display2_id));
242 magnifier->SetEnabled(false);
243
244 display_manager()->SetDisplayRotation(
245 display1.id(), display::Display::ROTATE_180,
246 display::Display::RotationSource::ACTIVE);
247 // Move the cursor to the center of the first root window.
248 generator1.MoveMouseToInHost(59, 99);
249
250 magnifier->SetEnabled(true);
251 EXPECT_EQ("120x200", root_windows[0]->bounds().size().ToString());
252 EXPECT_EQ("200x150", root_windows[1]->bounds().size().ToString());
253 // Display must share at least 100, so the x's offset becomes 20.
254 EXPECT_EQ("20,200 200x150",
255 display_manager_test.GetSecondaryDisplay().bounds().ToString());
256 generator1.MoveMouseToInHost(39, 59);
257 EXPECT_EQ("70,120", event_handler.GetLocationAndReset());
258 EXPECT_EQ(display::Display::ROTATE_180,
259 GetActiveDisplayRotation(display1.id()));
260 EXPECT_EQ(display::Display::ROTATE_270,
261 GetActiveDisplayRotation(display2_id));
262 magnifier->SetEnabled(false);
263
264 Shell::Get()->RemovePreTargetHandler(&event_handler);
265 }
266
TEST_F(RootWindowTransformersTest,ScaleAndMagnify)267 TEST_F(RootWindowTransformersTest, ScaleAndMagnify) {
268 TestEventHandler event_handler;
269 Shell::Get()->AddPreTargetHandler(&event_handler);
270
271 UpdateDisplay("600x400*1.6,500x300");
272
273 display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
274 display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
275 display1.id());
276 display::test::DisplayManagerTestApi display_manager_test(display_manager());
277 display::Display display2 = display_manager_test.GetSecondaryDisplay();
278 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
279 MagnificationController* magnifier = Shell::Get()->magnification_controller();
280
281 magnifier->SetEnabled(true);
282 EXPECT_EQ(2.0f, magnifier->GetScale());
283 EXPECT_EQ(1.6f, display1.device_scale_factor());
284 EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
285 EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
286 EXPECT_EQ("375,0 500x300", display2.bounds().ToString());
287 EXPECT_EQ(1.0f, GetStoredZoomScale(display1.id()));
288 EXPECT_EQ(1.0f, GetStoredZoomScale(display2.id()));
289
290 ui::test::EventGenerator generator(root_windows[0]);
291 generator.MoveMouseToInHost(500, 200);
292 EXPECT_EQ("249,124", event_handler.GetLocationAndReset());
293 magnifier->SetEnabled(false);
294
295 display_manager()->UpdateZoomFactor(display1.id(), 1.f / 1.2f);
296 display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
297 display2 = display_manager_test.GetSecondaryDisplay();
298 magnifier->SetEnabled(true);
299 EXPECT_EQ(2.0f, magnifier->GetScale());
300 EXPECT_EQ("0,0 450x300", display1.bounds().ToString());
301 EXPECT_EQ("0,0 450x300", root_windows[0]->bounds().ToString());
302 EXPECT_EQ("450,0 500x300", display2.bounds().ToString());
303 EXPECT_FLOAT_EQ(1.f / 1.2f, GetStoredZoomScale(display1.id()));
304 EXPECT_EQ(1.0f, GetStoredZoomScale(display2.id()));
305 magnifier->SetEnabled(false);
306
307 Shell::Get()->RemovePreTargetHandler(&event_handler);
308 }
309
TEST_F(RootWindowTransformersTest,TouchScaleAndMagnify)310 TEST_F(RootWindowTransformersTest, TouchScaleAndMagnify) {
311 TestEventHandler event_handler;
312 Shell::Get()->AddPreTargetHandler(&event_handler);
313
314 UpdateDisplay("200x200*2");
315 display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
316 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
317 aura::Window* root_window = root_windows[0];
318 ui::test::EventGenerator generator(root_window);
319 MagnificationController* magnifier = Shell::Get()->magnification_controller();
320
321 magnifier->SetEnabled(true);
322 EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
323 magnifier->SetScale(2.5f, false);
324 EXPECT_FLOAT_EQ(2.5f, magnifier->GetScale());
325 generator.PressMoveAndReleaseTouchTo(50, 50);
326 // Default test touches have radius_x/y = 1.0, with device scale
327 // factor = 2, the scaled radius_x/y should be 0.5.
328 EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_x());
329 EXPECT_FLOAT_EQ(0.2f, event_handler.touch_radius_y());
330
331 generator.ScrollSequence(gfx::Point(0, 0),
332 base::TimeDelta::FromMilliseconds(100), 10.0, 1.0, 5,
333 1);
334
335 // ordinal_offset is invariant to the device scale factor.
336 EXPECT_FLOAT_EQ(event_handler.scroll_x_offset(),
337 event_handler.scroll_x_offset_ordinal());
338 EXPECT_FLOAT_EQ(event_handler.scroll_y_offset(),
339 event_handler.scroll_y_offset_ordinal());
340 magnifier->SetEnabled(false);
341
342 Shell::Get()->RemovePreTargetHandler(&event_handler);
343 }
344
TEST_F(RootWindowTransformersTest,ConvertHostToRootCoords)345 TEST_F(RootWindowTransformersTest, ConvertHostToRootCoords) {
346 TestEventHandler event_handler;
347 Shell::Get()->AddPreTargetHandler(&event_handler);
348 MagnificationController* magnifier = Shell::Get()->magnification_controller();
349
350 // Test 1
351 UpdateDisplay("600x400*2/r@0.8");
352
353 display::Display display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
354 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
355 EXPECT_EQ("0,0 250x375", display1.bounds().ToString());
356 EXPECT_EQ("0,0 250x375", root_windows[0]->bounds().ToString());
357 EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
358
359 ui::test::EventGenerator generator(root_windows[0]);
360 generator.MoveMouseToInHost(300, 200);
361 magnifier->SetEnabled(true);
362 EXPECT_EQ("125,187", event_handler.GetLocationAndReset());
363 EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
364
365 generator.MoveMouseToInHost(300, 200);
366 EXPECT_EQ("124,186", event_handler.GetLocationAndReset());
367 generator.MoveMouseToInHost(200, 300);
368 EXPECT_EQ("155,218", event_handler.GetLocationAndReset());
369 generator.MoveMouseToInHost(100, 400);
370 EXPECT_EQ("204,249", event_handler.GetLocationAndReset());
371 generator.MoveMouseToInHost(0, 0);
372 EXPECT_EQ("125,298", event_handler.GetLocationAndReset());
373
374 magnifier->SetEnabled(false);
375 EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
376
377 // Test 2
378 UpdateDisplay("600x400*2/u@0.8");
379 display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
380 root_windows = Shell::GetAllRootWindows();
381 EXPECT_EQ("0,0 375x250", display1.bounds().ToString());
382 EXPECT_EQ("0,0 375x250", root_windows[0]->bounds().ToString());
383 EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
384
385 generator.MoveMouseToInHost(300, 200);
386 magnifier->SetEnabled(true);
387 EXPECT_EQ("187,125", event_handler.GetLocationAndReset());
388 EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
389
390 generator.MoveMouseToInHost(300, 200);
391 EXPECT_EQ("186,124", event_handler.GetLocationAndReset());
392 generator.MoveMouseToInHost(200, 300);
393 EXPECT_EQ("218,93", event_handler.GetLocationAndReset());
394 generator.MoveMouseToInHost(100, 400);
395 EXPECT_EQ("249,43", event_handler.GetLocationAndReset());
396 generator.MoveMouseToInHost(0, 0);
397 EXPECT_EQ("298,125", event_handler.GetLocationAndReset());
398
399 magnifier->SetEnabled(false);
400 EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
401
402 // Test 3
403 UpdateDisplay("600x400*2/l@0.8");
404 display1 = display::Screen::GetScreen()->GetPrimaryDisplay();
405 root_windows = Shell::GetAllRootWindows();
406 EXPECT_EQ("0,0 250x375", display1.bounds().ToString());
407 EXPECT_EQ("0,0 250x375", root_windows[0]->bounds().ToString());
408 EXPECT_EQ(0.8f, GetStoredZoomScale(display1.id()));
409
410 generator.MoveMouseToInHost(300, 200);
411 magnifier->SetEnabled(true);
412 EXPECT_EQ("125,187", event_handler.GetLocationAndReset());
413 EXPECT_FLOAT_EQ(2.0f, magnifier->GetScale());
414
415 generator.MoveMouseToInHost(300, 200);
416 EXPECT_EQ("124,186", event_handler.GetLocationAndReset());
417 generator.MoveMouseToInHost(200, 300);
418 EXPECT_EQ("93,155", event_handler.GetLocationAndReset());
419 generator.MoveMouseToInHost(100, 400);
420 EXPECT_EQ("43,124", event_handler.GetLocationAndReset());
421 generator.MoveMouseToInHost(0, 0);
422 EXPECT_EQ("125,74", event_handler.GetLocationAndReset());
423
424 magnifier->SetEnabled(false);
425 EXPECT_FLOAT_EQ(1.0f, magnifier->GetScale());
426
427 Shell::Get()->RemovePreTargetHandler(&event_handler);
428 }
429
TEST_F(RootWindowTransformersTest,LetterBoxPillarBox)430 TEST_F(RootWindowTransformersTest, LetterBoxPillarBox) {
431 MirrorWindowTestApi test_api;
432 UpdateDisplay("400x200,500x500");
433 display_manager()->SetMirrorMode(display::MirrorMode::kNormal, base::nullopt);
434 std::unique_ptr<RootWindowTransformer> transformer(
435 CreateCurrentRootWindowTransformerForMirroring());
436 // Y margin must be margin is (500 - 500/400 * 200) / 2 = 125.
437 EXPECT_EQ("0,125,0,125", transformer->GetHostInsets().ToString());
438
439 UpdateDisplay("200x400,500x500");
440 // The aspect ratio is flipped, so X margin is now 125.
441 transformer = CreateCurrentRootWindowTransformerForMirroring();
442 EXPECT_EQ("125,0,125,0", transformer->GetHostInsets().ToString());
443 }
444
TEST_F(RootWindowTransformersTest,ShouldSetWindowSize)445 TEST_F(RootWindowTransformersTest, ShouldSetWindowSize) {
446 UpdateDisplay("800x600");
447 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
448 aura::Window* root_window = root_windows[0];
449
450 // Rotate screen 90 degrees to "right".
451 // Will triger window_tree_host->SetRootWindowTransformer().
452 // The window size will be updated because there is no ongoing transform
453 // animation.
454 UpdateDisplay("800x600/r");
455 EXPECT_EQ(root_window->GetTargetBounds(), gfx::Rect(0, 0, 600, 800));
456 }
457
TEST_F(RootWindowTransformersTest,ShouldNotSetWindowSizeWithEnqueuedTransformAnimation)458 TEST_F(RootWindowTransformersTest,
459 ShouldNotSetWindowSizeWithEnqueuedTransformAnimation) {
460 UpdateDisplay("800x600");
461 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
462 aura::Window* root_window = root_windows[0];
463
464 ui::ScopedAnimationDurationScaleMode test_duration(
465 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
466 ui::Layer* layer = root_window->layer();
467 {
468 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
469 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100));
470 gfx::Transform transform;
471 transform.Translate(100, 200);
472 layer->SetTransform(transform);
473 }
474 layer->GetAnimator()->set_preemption_strategy(
475 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
476
477 // Rotate screen 90 degrees to "right".
478 // Will triger window_tree_host->SetRootWindowTransformer().
479 // The window size will not be updated because there is ongoing transform
480 // animation.
481 UpdateDisplay("800x600/r");
482 EXPECT_NE(root_window->GetTargetBounds(), gfx::Rect(0, 0, 600, 800));
483 }
484
TEST_F(RootWindowTransformersTest,ShouldSetWindowSizeWithStoppedTransformAnimation)485 TEST_F(RootWindowTransformersTest,
486 ShouldSetWindowSizeWithStoppedTransformAnimation) {
487 UpdateDisplay("800x600");
488 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
489 aura::Window* root_window = root_windows[0];
490
491 ui::ScopedAnimationDurationScaleMode test_duration(
492 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
493 ui::Layer* layer = root_window->layer();
494 {
495 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
496 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100));
497 gfx::Transform transform;
498 transform.Translate(100, 200);
499 layer->SetTransform(transform);
500 }
501 layer->GetAnimator()->set_preemption_strategy(
502 ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
503
504 // Rotate screen 90 degrees to "right".
505 // Will triger window_tree_host->SetRootWindowTransformer().
506 // The window size will be updated because there is no ongoing transform
507 // animation.
508 UpdateDisplay("800x600/r");
509 EXPECT_EQ(root_window->GetTargetBounds(), gfx::Rect(0, 0, 600, 800));
510 }
511
TEST_F(RootWindowTransformersTest,ShouldSetWindowSizeDuringOpacityAnimation)512 TEST_F(RootWindowTransformersTest, ShouldSetWindowSizeDuringOpacityAnimation) {
513 UpdateDisplay("800x600");
514 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
515 aura::Window* root_window = root_windows[0];
516
517 ui::ScopedAnimationDurationScaleMode test_duration(
518 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
519 {
520 ui::Layer* layer = root_window->layer();
521 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
522 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100));
523 layer->SetOpacity(0.1f);
524 }
525
526 // Rotate screen 90 degrees to "right".
527 // Will triger window_tree_host->SetRootWindowTransformer().
528 // The window size will be updated because there is no ongoing transform
529 // animation, even there is an opacity animation.
530 UpdateDisplay("800x600/r");
531 EXPECT_EQ(root_window->GetTargetBounds(), gfx::Rect(0, 0, 600, 800));
532 }
533
TEST_F(UnfiedRootWindowTransformersTest,HostBoundsAndTransform)534 TEST_F(UnfiedRootWindowTransformersTest, HostBoundsAndTransform) {
535 UpdateDisplay("800x600,800x600");
536 // Has only one logical root window.
537 EXPECT_EQ(1u, Shell::GetAllRootWindows().size());
538
539 MirrorWindowTestApi test_api;
540 std::vector<aura::WindowTreeHost*> hosts = test_api.GetHosts();
541 // Have 2 WindowTreeHosts, one per display.
542 ASSERT_EQ(2u, hosts.size());
543
544 EXPECT_EQ(gfx::Rect(0, 0, 800, 600), hosts[0]->window()->GetBoundsInScreen());
545 gfx::Point viewport_0_origin(0, 0);
546 hosts[0]->window()->transform().TransformPointReverse(&viewport_0_origin);
547 EXPECT_EQ(gfx::Point(0, 0), viewport_0_origin);
548
549 EXPECT_EQ(gfx::Rect(800, 0, 800, 600),
550 hosts[1]->window()->GetBoundsInScreen());
551 gfx::Point viewport_1_origin(0, 0);
552 hosts[1]->window()->transform().TransformPointReverse(&viewport_1_origin);
553 EXPECT_EQ(gfx::Point(800, 0), viewport_1_origin);
554 }
555
556 } // namespace ash
557