Index: ash/wm/power_button_controller_unittest.cc |
diff --git a/ash/wm/power_button_controller_unittest.cc b/ash/wm/power_button_controller_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..85ff5aa3f1d7d4efc452cef2f8c605c53e3af230 |
--- /dev/null |
+++ b/ash/wm/power_button_controller_unittest.cc |
@@ -0,0 +1,276 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ash/wm/power_button_controller.h" |
+ |
+#include "ash/shell.h" |
+#include "ash/test/aura_shell_test_base.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/time.h" |
+#include "ui/aura/root_window.h" |
+ |
+namespace ash { |
+namespace test { |
+ |
+// Fake implementation of PowerButtonControllerDelegate that just logs requests |
+// to lock the screen and shut down the device. |
+class TestPowerButtonControllerDelegate : public PowerButtonControllerDelegate { |
+ public: |
+ TestPowerButtonControllerDelegate() |
+ : num_lock_requests_(0), |
+ num_shutdown_requests_(0) {} |
+ |
+ int num_lock_requests() const { return num_lock_requests_; } |
+ int num_shutdown_requests() const { return num_shutdown_requests_; } |
+ |
+ // PowerButtonControllerDelegate implementation. |
+ virtual void RequestLockScreen() OVERRIDE { |
+ num_lock_requests_++; |
+ } |
+ virtual void RequestShutdown() OVERRIDE { |
+ num_shutdown_requests_++; |
+ } |
+ |
+ private: |
+ int num_lock_requests_; |
+ int num_shutdown_requests_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestPowerButtonControllerDelegate); |
+}; |
+ |
+class PowerButtonControllerTest : public AuraShellTestBase { |
+ public: |
+ PowerButtonControllerTest() : controller_(NULL), delegate_(NULL) {} |
+ virtual ~PowerButtonControllerTest() {} |
+ |
+ void SetUp() OVERRIDE { |
+ AuraShellTestBase::SetUp(); |
+ delegate_ = new TestPowerButtonControllerDelegate; |
+ controller_ = Shell::GetInstance()->power_button_controller(); |
+ controller_->set_delegate(delegate_); // transfers ownership |
+ test_api_.reset(new PowerButtonController::TestApi(controller_)); |
+ } |
+ |
+ protected: |
+ PowerButtonController* controller_; // not owned |
+ TestPowerButtonControllerDelegate* delegate_; // not owned |
+ scoped_ptr<PowerButtonController::TestApi> test_api_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(PowerButtonControllerTest); |
+}; |
+ |
+// When we hold the power button while the user isn't logged in, we should shut |
+// down the machine directly. |
+TEST_F(PowerButtonControllerTest, ShutdownWhenNotLoggedIn) { |
+ controller_->OnLoginStateChange(false /*logged_in*/, false /*is_guest*/); |
+ controller_->OnLockStateChange(false); |
+ EXPECT_FALSE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // Press the power button and check that we start the shutdown timer. |
+ controller_->OnPowerButtonEvent(true, base::TimeTicks::Now()); |
+ EXPECT_FALSE(test_api_->lock_timer_is_running()); |
+ EXPECT_TRUE(test_api_->shutdown_timer_is_running()); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_CONTAINERS, |
+ PowerButtonController::ANIMATION_SLOW_CLOSE)); |
+ EXPECT_TRUE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // Release the power button before the shutdown timer fires. |
+ controller_->OnPowerButtonEvent(false, base::TimeTicks::Now()); |
+ EXPECT_FALSE(test_api_->shutdown_timer_is_running()); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_CONTAINERS, |
+ PowerButtonController::ANIMATION_UNDO_SLOW_CLOSE)); |
+ EXPECT_TRUE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // We should re-hide the black background layer after waiting long enough for |
+ // the animation to finish. |
+ EXPECT_TRUE(test_api_->hide_background_layer_timer_is_running()); |
+ test_api_->trigger_hide_background_layer_timeout(); |
+ EXPECT_FALSE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // Press the button again and make the shutdown timeout fire this time. |
+ // Check that we start the timer for actually requesting the shutdown. |
+ controller_->OnPowerButtonEvent(true, base::TimeTicks::Now()); |
+ EXPECT_TRUE(test_api_->shutdown_timer_is_running()); |
+ test_api_->trigger_shutdown_timeout(); |
+ EXPECT_TRUE(test_api_->real_shutdown_timer_is_running()); |
+ EXPECT_EQ(0, delegate_->num_shutdown_requests()); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_CONTAINERS, |
+ PowerButtonController::ANIMATION_FAST_CLOSE)); |
+ |
+ // When the timout fires, we should request a shutdown. |
+ test_api_->trigger_real_shutdown_timeout(); |
+ EXPECT_EQ(1, delegate_->num_shutdown_requests()); |
+} |
+ |
+// Test that we lock the screen and deal with unlocking correctly. |
+TEST_F(PowerButtonControllerTest, LockAndUnlock) { |
+ controller_->OnLoginStateChange(true /*logged_in*/, false /*is_guest*/); |
+ controller_->OnLockStateChange(false); |
+ EXPECT_FALSE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // We should initially be showing the screen locker containers, since they |
+ // also contain login-related windows that we want to show during the |
+ // logging-in animation. |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::SCREEN_LOCKER_CONTAINERS, |
+ PowerButtonController::ANIMATION_RESTORE)); |
+ |
+ // Press the power button and check that the lock timer is started and that we |
+ // start scaling the non-screen-locker containers. |
+ controller_->OnPowerButtonEvent(true, base::TimeTicks::Now()); |
+ EXPECT_TRUE(test_api_->lock_timer_is_running()); |
+ EXPECT_FALSE(test_api_->shutdown_timer_is_running()); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS, |
+ PowerButtonController::ANIMATION_SLOW_CLOSE)); |
+ EXPECT_TRUE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // Release the button before the lock timer fires. |
+ controller_->OnPowerButtonEvent(false, base::TimeTicks::Now()); |
+ EXPECT_FALSE(test_api_->lock_timer_is_running()); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS, |
+ PowerButtonController::ANIMATION_UNDO_SLOW_CLOSE)); |
+ EXPECT_TRUE(test_api_->BackgroundLayerIsVisible()); |
+ EXPECT_TRUE(test_api_->hide_background_layer_timer_is_running()); |
+ test_api_->trigger_hide_background_layer_timeout(); |
+ EXPECT_FALSE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // Press the button and fire the lock timer. We should request that the |
+ // screen be locked, but we should still be in the slow-close animation. |
+ controller_->OnPowerButtonEvent(true, base::TimeTicks::Now()); |
+ EXPECT_TRUE(test_api_->lock_timer_is_running()); |
+ EXPECT_EQ(0, delegate_->num_lock_requests()); |
+ test_api_->trigger_lock_timeout(); |
+ EXPECT_EQ(1, delegate_->num_lock_requests()); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS, |
+ PowerButtonController::ANIMATION_SLOW_CLOSE)); |
+ EXPECT_TRUE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // Notify that we locked successfully. |
+ controller_->OnStartingLock(); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS, |
+ PowerButtonController::ANIMATION_FAST_CLOSE)); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::SCREEN_LOCKER_CONTAINERS, |
+ PowerButtonController::ANIMATION_HIDE)); |
+ |
+ // Notify that the lock window is visible. We should make it fade in. |
+ controller_->OnLockStateChange(true); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::SCREEN_LOCKER_AND_RELATED_CONTAINERS, |
+ PowerButtonController::ANIMATION_FADE_IN)); |
+ |
+ // When we release the power button, the lock-to-shutdown timer should be |
+ // stopped. |
+ EXPECT_TRUE(test_api_->lock_to_shutdown_timer_is_running()); |
+ controller_->OnPowerButtonEvent(false, base::TimeTicks::Now()); |
+ EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running()); |
+ |
+ // Notify that the screen has been unlocked. We should show the |
+ // non-screen-locker windows and hide the background layer. |
+ controller_->OnLockStateChange(false); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS, |
+ PowerButtonController::ANIMATION_RESTORE)); |
+ EXPECT_FALSE(test_api_->BackgroundLayerIsVisible()); |
+} |
+ |
+// Hold the power button down from the unlocked state to eventual shutdown. |
+TEST_F(PowerButtonControllerTest, LockToShutdown) { |
+ controller_->OnLoginStateChange(true /*logged_in*/, false /*is_guest*/); |
+ controller_->OnLockStateChange(false); |
+ |
+ // Hold the power button and lock the screen. |
+ controller_->OnPowerButtonEvent(true, base::TimeTicks::Now()); |
+ EXPECT_TRUE(test_api_->lock_timer_is_running()); |
+ test_api_->trigger_lock_timeout(); |
+ controller_->OnStartingLock(); |
+ controller_->OnLockStateChange(true); |
+ EXPECT_TRUE(test_api_->BackgroundLayerIsVisible()); |
+ |
+ // When the lock-to-shutdown timeout fires, we should start the shutdown |
+ // timer. |
+ EXPECT_TRUE(test_api_->lock_to_shutdown_timer_is_running()); |
+ test_api_->trigger_lock_to_shutdown_timeout(); |
+ EXPECT_TRUE(test_api_->shutdown_timer_is_running()); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_CONTAINERS, |
+ PowerButtonController::ANIMATION_SLOW_CLOSE)); |
+ |
+ // Fire the shutdown timeout and check that we request shutdown. |
+ test_api_->trigger_shutdown_timeout(); |
+ EXPECT_TRUE(test_api_->real_shutdown_timer_is_running()); |
+ EXPECT_EQ(0, delegate_->num_shutdown_requests()); |
+ test_api_->trigger_real_shutdown_timeout(); |
+ EXPECT_EQ(1, delegate_->num_shutdown_requests()); |
+ EXPECT_TRUE(test_api_->BackgroundLayerIsVisible()); |
+} |
+ |
+// Test that we handle the case where lock requests are ignored. |
+TEST_F(PowerButtonControllerTest, LockFail) { |
+ controller_->OnLoginStateChange(true /*logged_in*/, false /*is_guest*/); |
+ controller_->OnLockStateChange(false); |
+ |
+ // Hold the power button and lock the screen. |
+ controller_->OnPowerButtonEvent(true, base::TimeTicks::Now()); |
+ EXPECT_TRUE(test_api_->lock_timer_is_running()); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS, |
+ PowerButtonController::ANIMATION_RESTORE)); |
+ EXPECT_TRUE(test_api_->BackgroundLayerIsVisible()); |
+ test_api_->trigger_lock_timeout(); |
+ EXPECT_EQ(1, delegate_->num_lock_requests()); |
+ EXPECT_TRUE(test_api_->lock_fail_timer_is_running()); |
+ |
+ // We shouldn't start the lock-to-shutdown timer until the screen has actually |
+ // been locked. |
+ EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running()); |
+ |
+ // Act as if the request timed out. We should restore the windows. |
+ test_api_->trigger_lock_fail_timeout(); |
+ EXPECT_TRUE( |
+ test_api_->ContainerGroupIsAnimated( |
+ PowerButtonController::ALL_BUT_SCREEN_LOCKER_AND_RELATED_CONTAINERS, |
+ PowerButtonController::ANIMATION_RESTORE)); |
+ EXPECT_FALSE(test_api_->BackgroundLayerIsVisible()); |
+} |
+ |
+// Test that we start the timer to hide the background layer when the power |
+// button is released, but that we cancel the timer if the button is pressed |
+// again before the timer has fired. |
+TEST_F(PowerButtonControllerTest, CancelHideBackground) { |
+ controller_->OnLoginStateChange(false /*logged_in*/, false /*is_guest*/); |
+ controller_->OnLockStateChange(false); |
+ |
+ controller_->OnPowerButtonEvent(true, base::TimeTicks::Now()); |
+ controller_->OnPowerButtonEvent(false, base::TimeTicks::Now()); |
+ EXPECT_TRUE(test_api_->hide_background_layer_timer_is_running()); |
+ |
+ // We should cancel the timer if we get another button-down event. |
+ controller_->OnPowerButtonEvent(true, base::TimeTicks::Now()); |
+ EXPECT_FALSE(test_api_->hide_background_layer_timer_is_running()); |
+} |
+ |
+} // namespace test |
+} // namespace ash |