Index: ash/rotator/screen_rotation_animator_unittest.cc |
diff --git a/ash/rotator/screen_rotation_animator_unittest.cc b/ash/rotator/screen_rotation_animator_unittest.cc |
index 1b464c6404a39360b8eaa7605f35361b461710eb..14eb5f20cab3e1e182c5dca43896b2b501b2b2b8 100644 |
--- a/ash/rotator/screen_rotation_animator_unittest.cc |
+++ b/ash/rotator/screen_rotation_animator_unittest.cc |
@@ -8,7 +8,11 @@ |
#include "ash/rotator/test/screen_rotation_animator_test_api.h" |
#include "ash/shell.h" |
#include "ash/test/ash_test_base.h" |
+#include "base/callback_forward.h" |
#include "base/memory/ptr_util.h" |
+#include "base/run_loop.h" |
+#include "cc/output/copy_output_request.h" |
+#include "cc/output/copy_output_result.h" |
#include "ui/compositor/scoped_animation_duration_scale_mode.h" |
#include "ui/display/display.h" |
#include "ui/display/manager/display_manager.h" |
@@ -49,6 +53,47 @@ class AnimationObserver : public ScreenRotationAnimatorObserver { |
DISALLOW_COPY_AND_ASSIGN(AnimationObserver); |
}; |
+class ScreenRotationTestAnimator : public ScreenRotationAnimator { |
+ public: |
+ explicit ScreenRotationTestAnimator(int64_t display_id); |
+ ~ScreenRotationTestAnimator() override {} |
+ |
+ void set_callback(const base::Closure& callback) { callback_ = callback; } |
+ |
+ protected: |
+ std::unique_ptr<cc::CopyOutputRequest> CreateAfterCopyCallback( |
+ std::unique_ptr<ScreenRotationRequest> rotation_request) override; |
+ |
+ private: |
+ void OnRootLayerCopiedBeforeRotationForTest( |
+ std::unique_ptr<ScreenRotationRequest> rotation_request, |
+ std::unique_ptr<cc::CopyOutputResult> result); |
+ |
+ base::Closure callback_; |
+ base::WeakPtrFactory<ScreenRotationTestAnimator> weak_factory_test_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ScreenRotationTestAnimator); |
+}; |
+ |
+ScreenRotationTestAnimator::ScreenRotationTestAnimator(int64_t display_id) |
+ : ScreenRotationAnimator(display_id), weak_factory_test_(this) {} |
+ |
+void ScreenRotationTestAnimator::OnRootLayerCopiedBeforeRotationForTest( |
+ std::unique_ptr<ScreenRotationRequest> rotation_request, |
+ std::unique_ptr<cc::CopyOutputResult> result) { |
+ callback_.Run(); |
+ OnRootLayerCopiedBeforeRotation(std::move(rotation_request), |
+ std::move(result)); |
+} |
+ |
+std::unique_ptr<cc::CopyOutputRequest> |
+ScreenRotationTestAnimator::CreateAfterCopyCallback( |
+ std::unique_ptr<ScreenRotationRequest> rotation_request) { |
+ return cc::CopyOutputRequest::CreateRequest(base::Bind( |
+ &ScreenRotationTestAnimator::OnRootLayerCopiedBeforeRotationForTest, |
+ weak_factory_test_.GetWeakPtr(), base::Passed(&rotation_request))); |
+} |
+ |
} // namespace |
class ScreenRotationAnimatorTest : public test::AshTestBase { |
@@ -59,30 +104,55 @@ class ScreenRotationAnimatorTest : public test::AshTestBase { |
// AshTestBase: |
void SetUp() override; |
+ void DoNothingCallback(); |
+ |
+ void RemoveSecondaryDisplay(const std::string& specs); |
+ |
protected: |
int64_t display_id() const { return display_.id(); } |
- ScreenRotationAnimator* animator() { return animator_.get(); } |
+ ScreenRotationTestAnimator* animator() { return animator_.get(); } |
+ |
+ void SetSecreenRotatioAnimator(int64_t display_id); |
test::ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); } |
+ void AddSecondaryDisplay(const std::string& specs); |
+ |
+ void WaitForCopyCallback(); |
+ |
std::unique_ptr<ui::ScopedAnimationDurationScaleMode> non_zero_duration_mode_; |
+ std::unique_ptr<base::RunLoop> run_loop_; |
private: |
display::Display display_; |
- std::unique_ptr<ScreenRotationAnimator> animator_; |
+ std::unique_ptr<ScreenRotationTestAnimator> animator_; |
std::unique_ptr<test::ScreenRotationAnimatorTestApi> test_api_; |
DISALLOW_COPY_AND_ASSIGN(ScreenRotationAnimatorTest); |
}; |
+void ScreenRotationAnimatorTest::DoNothingCallback() { |
+ run_loop_->Quit(); |
+} |
+ |
+void ScreenRotationAnimatorTest::RemoveSecondaryDisplay( |
+ const std::string& specs) { |
+ UpdateDisplay(specs); |
+ run_loop_->Quit(); |
+} |
+ |
void ScreenRotationAnimatorTest::SetUp() { |
AshTestBase::SetUp(); |
display_ = display::Screen::GetScreen()->GetPrimaryDisplay(); |
- animator_ = base::MakeUnique<ScreenRotationAnimator>(display_.id()); |
+ SetSecreenRotatioAnimator(display_.id()); |
+} |
+ |
+void ScreenRotationAnimatorTest::SetSecreenRotatioAnimator(int64_t display_id) { |
+ animator_ = base::MakeUnique<ScreenRotationTestAnimator>(display_id); |
test_api_ = |
base::MakeUnique<test::ScreenRotationAnimatorTestApi>(animator_.get()); |
test_api()->DisableAnimationTimers(); |
@@ -91,6 +161,15 @@ void ScreenRotationAnimatorTest::SetUp() { |
ui::ScopedAnimationDurationScaleMode::SLOW_DURATION); |
} |
+void ScreenRotationAnimatorTest::AddSecondaryDisplay(const std::string& specs) { |
+ UpdateDisplay(specs); |
+} |
+ |
+void ScreenRotationAnimatorTest::WaitForCopyCallback() { |
+ run_loop_.reset(new base::RunLoop); |
+ run_loop_->Run(); |
+} |
+ |
TEST_F(ScreenRotationAnimatorTest, ShouldNotifyObserver) { |
// TODO(wutao): needs GetDisplayInfo http://crbug.com/622480. |
if (WmShell::Get()->IsRunningInMash()) { |
@@ -223,4 +302,54 @@ TEST_F(ScreenRotationAnimatorTest, ShouldCompleteAnimations) { |
EXPECT_EQ(display::Display::ROTATE_270, GetDisplayRotation(display_id())); |
} |
+// Test enable smooth screen rotation code path. |
+TEST_F(ScreenRotationAnimatorTest, RotatesToDifferentRotationWithCopyCallback) { |
+ // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480. |
+ if (WmShell::Get()->IsRunningInMash()) { |
+ ASSERT_TRUE(WmShell::Get()->GetDisplayInfo(display_id()).id() != |
+ display_id()); |
+ return; |
+ } |
+ |
+ SetDisplayRotation(display_id(), display::Display::ROTATE_0); |
+ animator()->set_callback(base::Bind( |
+ &ScreenRotationAnimatorTest::DoNothingCallback, base::Unretained(this))); |
+ test_api()->EnableSmoothRotation(); |
+ animator()->Rotate(display::Display::ROTATE_90, |
+ display::Display::RotationSource::ROTATION_SOURCE_USER); |
+ WaitForCopyCallback(); |
+ EXPECT_TRUE(test_api()->HasActiveAnimations()); |
+ |
+ test_api()->CompleteAnimations(); |
+ EXPECT_FALSE(test_api()->HasActiveAnimations()); |
+} |
+ |
+// If the external display is removed, it should not crash. |
+TEST_F(ScreenRotationAnimatorTest, RemoveSecondaryDisplayAfterCopyCallback) { |
+ // TODO(wutao): needs GetDisplayInfo http://crbug.com/622480. |
+ if (WmShell::Get()->IsRunningInMash()) { |
+ ASSERT_TRUE(WmShell::Get()->GetDisplayInfo(display_id()).id() != |
+ display_id()); |
+ return; |
+ } |
+ |
+ AddSecondaryDisplay("640x480,800x600"); |
+ EXPECT_EQ(2U, display_manager()->GetNumDisplays()); |
+ |
+ const unsigned int primary_display_id = |
+ display_manager()->GetDisplayAt(0).id(); |
+ SetSecreenRotatioAnimator(display_manager()->GetDisplayAt(1).id()); |
+ animator()->set_callback( |
+ base::Bind(&ScreenRotationAnimatorTest::RemoveSecondaryDisplay, |
+ base::Unretained(this), "640x480")); |
+ test_api()->EnableSmoothRotation(); |
+ SetDisplayRotation(display_manager()->GetDisplayAt(1).id(), |
+ display::Display::ROTATE_0); |
+ animator()->Rotate(display::Display::ROTATE_90, |
+ display::Display::RotationSource::ROTATION_SOURCE_USER); |
+ WaitForCopyCallback(); |
+ EXPECT_EQ(1U, display_manager()->GetNumDisplays()); |
+ EXPECT_EQ(primary_display_id, display_manager()->GetDisplayAt(0).id()); |
+} |
+ |
} // namespace ash |