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