Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: ash/rotator/screen_rotation_animator_unittest.cc

Issue 2790583004: Add second copy request after screen rotation to flatten the layers in animation. (Closed)
Patch Set: Add one more state for rotating and fix corner case. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/rotator/screen_rotation_animator.h" 5 #include "ash/rotator/screen_rotation_animator.h"
6 6
7 #include "ash/ash_switches.h" 7 #include "ash/ash_switches.h"
8 #include "ash/display/window_tree_host_manager.h"
8 #include "ash/public/cpp/config.h" 9 #include "ash/public/cpp/config.h"
9 #include "ash/rotator/screen_rotation_animator_observer.h" 10 #include "ash/rotator/screen_rotation_animator_observer.h"
10 #include "ash/rotator/test/screen_rotation_animator_test_api.h" 11 #include "ash/rotator/test/screen_rotation_animator_test_api.h"
11 #include "ash/shell.h" 12 #include "ash/shell.h"
12 #include "ash/shell_port.h" 13 #include "ash/shell_port.h"
13 #include "ash/test/ash_test_base.h" 14 #include "ash/test/ash_test_base.h"
14 #include "base/callback_forward.h" 15 #include "base/callback_forward.h"
15 #include "base/command_line.h" 16 #include "base/command_line.h"
16 #include "base/memory/ptr_util.h" 17 #include "base/memory/ptr_util.h"
17 #include "base/run_loop.h" 18 #include "base/run_loop.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 } 53 }
53 54
54 private: 55 private:
55 bool notified_ = false; 56 bool notified_ = false;
56 57
57 DISALLOW_COPY_AND_ASSIGN(AnimationObserver); 58 DISALLOW_COPY_AND_ASSIGN(AnimationObserver);
58 }; 59 };
59 60
60 class TestScreenRotationAnimator : public ScreenRotationAnimator { 61 class TestScreenRotationAnimator : public ScreenRotationAnimator {
61 public: 62 public:
62 TestScreenRotationAnimator(int64_t display_id, const base::Closure& callback); 63 TestScreenRotationAnimator(int64_t display_id,
64 const base::Closure& before_callback,
65 const base::Closure& after_callback);
63 ~TestScreenRotationAnimator() override {} 66 ~TestScreenRotationAnimator() override {}
64 67
65 private: 68 private:
66 CopyCallback CreateAfterCopyCallback( 69 CopyCallback CreateAfterCopyCallbackBeforeRotation(
70 std::unique_ptr<ScreenRotationRequest> rotation_request) override;
71 CopyCallback CreateAfterCopyCallbackAfterRotation(
67 std::unique_ptr<ScreenRotationRequest> rotation_request) override; 72 std::unique_ptr<ScreenRotationRequest> rotation_request) override;
68 73
69 void IntersectBefore(CopyCallback next_callback, 74 void IntersectBefore(CopyCallback next_callback,
70 std::unique_ptr<cc::CopyOutputResult> result); 75 std::unique_ptr<cc::CopyOutputResult> result);
76 void IntersectAfter(CopyCallback next_callback,
77 std::unique_ptr<cc::CopyOutputResult> result);
71 78
72 base::Closure intersect_callback_; 79 base::Closure intersect_before_callback_;
80 base::Closure intersect_after_callback_;
73 81
74 DISALLOW_COPY_AND_ASSIGN(TestScreenRotationAnimator); 82 DISALLOW_COPY_AND_ASSIGN(TestScreenRotationAnimator);
75 }; 83 };
76 84
77 TestScreenRotationAnimator::TestScreenRotationAnimator( 85 TestScreenRotationAnimator::TestScreenRotationAnimator(
78 int64_t display_id, 86 int64_t display_id,
79 const base::Closure& callback) 87 const base::Closure& before_callback,
80 : ScreenRotationAnimator(display_id), intersect_callback_(callback) {} 88 const base::Closure& after_callback)
89 : ScreenRotationAnimator(display_id),
90 intersect_before_callback_(before_callback),
91 intersect_after_callback_(after_callback) {}
81 92
82 ScreenRotationAnimator::CopyCallback 93 ScreenRotationAnimator::CopyCallback
83 TestScreenRotationAnimator::CreateAfterCopyCallback( 94 TestScreenRotationAnimator::CreateAfterCopyCallbackBeforeRotation(
84 std::unique_ptr<ScreenRotationRequest> rotation_request) { 95 std::unique_ptr<ScreenRotationRequest> rotation_request) {
85 CopyCallback next_callback = ScreenRotationAnimator::CreateAfterCopyCallback( 96 CopyCallback next_callback =
86 std::move(rotation_request)); 97 ScreenRotationAnimator::CreateAfterCopyCallbackBeforeRotation(
98 std::move(rotation_request));
87 return base::Bind(&TestScreenRotationAnimator::IntersectBefore, 99 return base::Bind(&TestScreenRotationAnimator::IntersectBefore,
88 base::Unretained(this), next_callback); 100 base::Unretained(this), next_callback);
89 } 101 }
90 102
103 ScreenRotationAnimator::CopyCallback
104 TestScreenRotationAnimator::CreateAfterCopyCallbackAfterRotation(
105 std::unique_ptr<ScreenRotationRequest> rotation_request) {
106 CopyCallback next_callback =
107 ScreenRotationAnimator::CreateAfterCopyCallbackAfterRotation(
108 std::move(rotation_request));
109 return base::Bind(&TestScreenRotationAnimator::IntersectAfter,
110 base::Unretained(this), next_callback);
111 }
112
91 void TestScreenRotationAnimator::IntersectBefore( 113 void TestScreenRotationAnimator::IntersectBefore(
92 CopyCallback next_callback, 114 CopyCallback next_callback,
93 std::unique_ptr<cc::CopyOutputResult> result) { 115 std::unique_ptr<cc::CopyOutputResult> result) {
94 intersect_callback_.Run(); 116 intersect_before_callback_.Run();
95 next_callback.Run(std::move(result)); 117 next_callback.Run(std::move(result));
96 } 118 }
97 119
120 void TestScreenRotationAnimator::IntersectAfter(
121 CopyCallback next_callback,
122 std::unique_ptr<cc::CopyOutputResult> result) {
123 intersect_after_callback_.Run();
124 next_callback.Run(std::move(result));
125 }
126
98 } // namespace 127 } // namespace
99 128
100 class ScreenRotationAnimatorTest : public test::AshTestBase { 129 class ScreenRotationAnimatorTest : public test::AshTestBase {
101 public: 130 public:
102 ScreenRotationAnimatorTest() {} 131 ScreenRotationAnimatorTest() {}
103 ~ScreenRotationAnimatorTest() override {} 132 ~ScreenRotationAnimatorTest() override {}
104 133
105 // AshTestBase: 134 // AshTestBase:
106 void SetUp() override; 135 void SetUp() override;
107 136
108 void RemoveSecondaryDisplay(const std::string& specs); 137 void RemoveSecondaryDisplay(const std::string& specs);
138 void QuitWaitForCopyCallback();
109 139
110 protected: 140 protected:
111 int64_t display_id() const { return display_.id(); } 141 int64_t display_id() const { return display_.id(); }
112 142
113 TestScreenRotationAnimator* animator() { return animator_.get(); } 143 TestScreenRotationAnimator* animator() { return animator_.get(); }
114 144
115 void SetScreenRotationAnimator(int64_t display_id, 145 void SetScreenRotationAnimator(int64_t display_id,
116 const base::Closure& callback); 146 const base::Closure& before_callback,
147 const base::Closure& after_callback);
117 148
118 test::ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); } 149 test::ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); }
119 150
120 void WaitForCopyCallback(); 151 void WaitForCopyCallback();
121 152
122 std::unique_ptr<base::RunLoop> run_loop_; 153 std::unique_ptr<base::RunLoop> run_loop_;
123 154
124 private: 155 private:
125 display::Display display_; 156 display::Display display_;
126 157
127 std::unique_ptr<TestScreenRotationAnimator> animator_; 158 std::unique_ptr<TestScreenRotationAnimator> animator_;
128 159
129 std::unique_ptr<test::ScreenRotationAnimatorTestApi> test_api_; 160 std::unique_ptr<test::ScreenRotationAnimatorTestApi> test_api_;
130 161
131 std::unique_ptr<ui::ScopedAnimationDurationScaleMode> non_zero_duration_mode_; 162 std::unique_ptr<ui::ScopedAnimationDurationScaleMode> non_zero_duration_mode_;
132 163
133 DISALLOW_COPY_AND_ASSIGN(ScreenRotationAnimatorTest); 164 DISALLOW_COPY_AND_ASSIGN(ScreenRotationAnimatorTest);
134 }; 165 };
135 166
136 void ScreenRotationAnimatorTest::RemoveSecondaryDisplay( 167 void ScreenRotationAnimatorTest::RemoveSecondaryDisplay(
137 const std::string& specs) { 168 const std::string& specs) {
138 UpdateDisplay(specs); 169 UpdateDisplay(specs);
170 QuitWaitForCopyCallback();
171 }
172
173 void ScreenRotationAnimatorTest::QuitWaitForCopyCallback() {
139 run_loop_->QuitWhenIdle(); 174 run_loop_->QuitWhenIdle();
140 } 175 }
141 176
142 void ScreenRotationAnimatorTest::SetUp() { 177 void ScreenRotationAnimatorTest::SetUp() {
143 AshTestBase::SetUp(); 178 AshTestBase::SetUp();
144 179
145 display_ = display::Screen::GetScreen()->GetPrimaryDisplay(); 180 display_ = display::Screen::GetScreen()->GetPrimaryDisplay();
181 if (Shell::GetAshConfig() == Config::MASH) {
182 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() !=
183 display_id());
184 return;
185 }
186
146 run_loop_ = base::MakeUnique<base::RunLoop>(); 187 run_loop_ = base::MakeUnique<base::RunLoop>();
147 SetScreenRotationAnimator(display_.id(), run_loop_->QuitWhenIdleClosure()); 188 SetScreenRotationAnimator(display_.id(), run_loop_->QuitWhenIdleClosure(),
189 run_loop_->QuitWhenIdleClosure());
148 non_zero_duration_mode_ = 190 non_zero_duration_mode_ =
149 base::MakeUnique<ui::ScopedAnimationDurationScaleMode>( 191 base::MakeUnique<ui::ScopedAnimationDurationScaleMode>(
150 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION); 192 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
151 } 193 }
152 194
153 void ScreenRotationAnimatorTest::SetScreenRotationAnimator( 195 void ScreenRotationAnimatorTest::SetScreenRotationAnimator(
154 int64_t display_id, 196 int64_t display_id,
155 const base::Closure& callback) { 197 const base::Closure& before_callback,
156 animator_ = 198 const base::Closure& after_callback) {
157 base::MakeUnique<TestScreenRotationAnimator>(display_id, callback); 199 animator_ = base::MakeUnique<TestScreenRotationAnimator>(
200 display_id, before_callback, after_callback);
158 test_api_ = 201 test_api_ =
159 base::MakeUnique<test::ScreenRotationAnimatorTestApi>(animator_.get()); 202 base::MakeUnique<test::ScreenRotationAnimatorTestApi>(animator_.get());
160 test_api()->DisableAnimationTimers(); 203 test_api()->DisableAnimationTimers();
161 } 204 }
162 205
163 void ScreenRotationAnimatorTest::WaitForCopyCallback() { 206 void ScreenRotationAnimatorTest::WaitForCopyCallback() {
207 run_loop_.reset(new base::RunLoop());
164 run_loop_->Run(); 208 run_loop_->Run();
165 } 209 }
166 210
167 TEST_F(ScreenRotationAnimatorTest, ShouldNotifyObserver) { 211 TEST_F(ScreenRotationAnimatorTest, ShouldNotifyObserver) {
168 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480. 212 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480.
169 if (Shell::GetAshConfig() == Config::MASH) { 213 if (Shell::GetAshConfig() == Config::MASH) {
170 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() != 214 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() !=
171 display_id()); 215 display_id());
172 return; 216 return;
173 } 217 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 342
299 // Test enable smooth screen rotation code path. 343 // Test enable smooth screen rotation code path.
300 TEST_F(ScreenRotationAnimatorTest, RotatesToDifferentRotationWithCopyCallback) { 344 TEST_F(ScreenRotationAnimatorTest, RotatesToDifferentRotationWithCopyCallback) {
301 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480. 345 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480.
302 if (Shell::GetAshConfig() == Config::MASH) { 346 if (Shell::GetAshConfig() == Config::MASH) {
303 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() != 347 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() !=
304 display_id()); 348 display_id());
305 return; 349 return;
306 } 350 }
307 351
352 SetScreenRotationAnimator(
353 display_manager()->GetDisplayAt(0).id(), run_loop_->QuitWhenIdleClosure(),
354 base::Bind(&ScreenRotationAnimatorTest::QuitWaitForCopyCallback,
355 base::Unretained(this)));
356 test_api()->EnableSmoothRotation();
308 SetDisplayRotation(display_id(), display::Display::ROTATE_0); 357 SetDisplayRotation(display_id(), display::Display::ROTATE_0);
309 base::CommandLine::ForCurrentProcess()->AppendSwitch(
310 switches::kAshEnableSmoothScreenRotation);
311 animator()->Rotate(display::Display::ROTATE_90, 358 animator()->Rotate(display::Display::ROTATE_90,
312 display::Display::RotationSource::ROTATION_SOURCE_USER); 359 display::Display::RotationSource::ROTATION_SOURCE_USER);
313 WaitForCopyCallback(); 360 WaitForCopyCallback();
314 EXPECT_TRUE(test_api()->HasActiveAnimations()); 361 EXPECT_TRUE(test_api()->HasActiveAnimations());
315 362
316 test_api()->CompleteAnimations(); 363 test_api()->CompleteAnimations();
317 EXPECT_FALSE(test_api()->HasActiveAnimations()); 364 EXPECT_FALSE(test_api()->HasActiveAnimations());
318 } 365 }
319 366
320 // If the external display is removed, it should not crash. 367 // If the external secondary display is removed before the first copy request
321 TEST_F(ScreenRotationAnimatorTest, RemoveSecondaryDisplayAfterCopyCallback) { 368 // callback called, it should not crash.
369 TEST_F(ScreenRotationAnimatorTest,
370 RemoveExternalSecondaryDisplayBeforeFirstCopyCallback) {
322 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480. 371 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480.
323 if (Shell::GetAshConfig() == Config::MASH) { 372 if (Shell::GetAshConfig() == Config::MASH) {
324 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() != 373 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() !=
325 display_id()); 374 display_id());
326 return; 375 return;
327 } 376 }
328 377
329 UpdateDisplay("640x480,800x600"); 378 UpdateDisplay("640x480,800x600");
330 EXPECT_EQ(2U, display_manager()->GetNumDisplays()); 379 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
331 380
332 const unsigned int primary_display_id = 381 const unsigned int primary_display_id =
333 display_manager()->GetDisplayAt(0).id(); 382 display_manager()->GetDisplayAt(0).id();
334 SetScreenRotationAnimator( 383 SetScreenRotationAnimator(
335 display_manager()->GetDisplayAt(1).id(), 384 display_manager()->GetDisplayAt(1).id(),
336 base::Bind(&ScreenRotationAnimatorTest::RemoveSecondaryDisplay, 385 base::Bind(&ScreenRotationAnimatorTest::RemoveSecondaryDisplay,
337 base::Unretained(this), "640x480")); 386 base::Unretained(this), "640x480"),
338 base::CommandLine::ForCurrentProcess()->AppendSwitch( 387 run_loop_->QuitWhenIdleClosure());
339 switches::kAshEnableSmoothScreenRotation); 388 test_api()->EnableSmoothRotation();
340 SetDisplayRotation(display_manager()->GetDisplayAt(1).id(), 389 SetDisplayRotation(display_manager()->GetDisplayAt(1).id(),
341 display::Display::ROTATE_0); 390 display::Display::ROTATE_0);
342 animator()->Rotate(display::Display::ROTATE_90, 391 animator()->Rotate(display::Display::ROTATE_90,
392 display::Display::RotationSource::ROTATION_SOURCE_USER);
393 WaitForCopyCallback();
394 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
395 EXPECT_EQ(primary_display_id, display_manager()->GetDisplayAt(0).id());
396 }
397
398 // If the external primary display is removed before the first copy request
399 // callback called, it should not crash.
400 TEST_F(ScreenRotationAnimatorTest,
401 RemoveExternalPrimaryDisplayBeforeFirstCopyCallback) {
402 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480.
403 if (Shell::GetAshConfig() == Config::MASH) {
404 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() !=
405 display_id());
406 return;
407 }
408
409 UpdateDisplay("640x480,800x600");
410 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
411
412 Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(
413 display_manager()->GetDisplayAt(1).id());
414 const unsigned int secondary_display_id =
415 display_manager()->GetDisplayAt(0).id();
416 SetScreenRotationAnimator(
417 display_manager()->GetDisplayAt(1).id(),
418 base::Bind(&ScreenRotationAnimatorTest::RemoveSecondaryDisplay,
419 base::Unretained(this), "640x480"),
420 run_loop_->QuitWhenIdleClosure());
421 test_api()->EnableSmoothRotation();
422 SetDisplayRotation(display_manager()->GetDisplayAt(1).id(),
423 display::Display::ROTATE_0);
424 animator()->Rotate(display::Display::ROTATE_90,
425 display::Display::RotationSource::ROTATION_SOURCE_USER);
426 WaitForCopyCallback();
427 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
428 EXPECT_EQ(secondary_display_id, display_manager()->GetDisplayAt(0).id());
429 }
430
431 // If the external secondary display is removed before the second copy request
432 // callback called, it should not crash.
433 TEST_F(ScreenRotationAnimatorTest,
434 RemoveExternalSecondaryDisplayBeforeSecondCopyCallback) {
435 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480.
436 if (Shell::GetAshConfig() == Config::MASH) {
437 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() !=
438 display_id());
439 return;
440 }
441
442 UpdateDisplay("640x480,800x600");
443 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
444
445 const unsigned int primary_display_id =
446 display_manager()->GetDisplayAt(0).id();
447 SetScreenRotationAnimator(
448 display_manager()->GetDisplayAt(1).id(), run_loop_->QuitWhenIdleClosure(),
449 base::Bind(&ScreenRotationAnimatorTest::RemoveSecondaryDisplay,
450 base::Unretained(this), "640x480"));
451 test_api()->EnableSmoothRotation();
452 SetDisplayRotation(display_manager()->GetDisplayAt(1).id(),
453 display::Display::ROTATE_0);
454 animator()->Rotate(display::Display::ROTATE_90,
343 display::Display::RotationSource::ROTATION_SOURCE_USER); 455 display::Display::RotationSource::ROTATION_SOURCE_USER);
344 WaitForCopyCallback(); 456 WaitForCopyCallback();
345 EXPECT_EQ(1U, display_manager()->GetNumDisplays()); 457 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
346 EXPECT_EQ(primary_display_id, display_manager()->GetDisplayAt(0).id()); 458 EXPECT_EQ(primary_display_id, display_manager()->GetDisplayAt(0).id());
347 } 459 }
348 460
461 // If the external primary display is removed before the second copy request
462 // callback called, it should not crash.
463 TEST_F(ScreenRotationAnimatorTest,
464 RemoveExternalPrimaryDisplayBeforeSecondCopyCallback) {
465 // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480.
466 if (Shell::GetAshConfig() == Config::MASH) {
467 ASSERT_TRUE(ShellPort::Get()->GetDisplayInfo(display_id()).id() !=
468 display_id());
469 return;
470 }
471
472 UpdateDisplay("640x480,800x600");
473 EXPECT_EQ(2U, display_manager()->GetNumDisplays());
474
475 Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(
476 display_manager()->GetDisplayAt(1).id());
477 const unsigned int secondary_display_id =
478 display_manager()->GetDisplayAt(0).id();
479 SetScreenRotationAnimator(
480 display_manager()->GetDisplayAt(1).id(), run_loop_->QuitWhenIdleClosure(),
481 base::Bind(&ScreenRotationAnimatorTest::RemoveSecondaryDisplay,
482 base::Unretained(this), "640x480"));
483 test_api()->EnableSmoothRotation();
484 SetDisplayRotation(display_manager()->GetDisplayAt(1).id(),
485 display::Display::ROTATE_0);
486 animator()->Rotate(display::Display::ROTATE_90,
487 display::Display::RotationSource::ROTATION_SOURCE_USER);
488 WaitForCopyCallback();
489 EXPECT_EQ(1U, display_manager()->GetNumDisplays());
490 EXPECT_EQ(secondary_display_id, display_manager()->GetDisplayAt(0).id());
491 }
492
349 } // namespace ash 493 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698