multitask_menu_nudge_controller_unittest.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Copyright 2022 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. #include "ash/wm/multitask_menu_nudge_controller.h"
  5. #include "ash/constants/ash_features.h"
  6. #include "ash/display/display_move_window_util.h"
  7. #include "ash/session/session_controller_impl.h"
  8. #include "ash/shell.h"
  9. #include "ash/test/ash_test_base.h"
  10. #include "ash/wm/window_state.h"
  11. #include "ash/wm/wm_event.h"
  12. #include "base/test/scoped_feature_list.h"
  13. #include "base/test/simple_test_clock.h"
  14. #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h"
  15. #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h"
  16. #include "chromeos/ui/wm/features.h"
  17. namespace ash {
  18. class MultitaskMenuNudgeControllerTest : public AshTestBase {
  19. public:
  20. MultitaskMenuNudgeControllerTest() = default;
  21. MultitaskMenuNudgeControllerTest(const MultitaskMenuNudgeControllerTest&) =
  22. delete;
  23. MultitaskMenuNudgeControllerTest& operator=(
  24. const MultitaskMenuNudgeControllerTest&) = delete;
  25. ~MultitaskMenuNudgeControllerTest() override = default;
  26. views::Widget* GetWidget() { return controller_->nudge_widget_.get(); }
  27. void FireDismissNudgeTimer() { controller_->nudge_dismiss_timer_.FireNow(); }
  28. // AshTestBase:
  29. void SetUp() override {
  30. scoped_feature_list_.InitAndEnableFeature(
  31. chromeos::wm::features::kFloatWindow);
  32. AshTestBase::SetUp();
  33. controller_ = Shell::Get()->multitask_menu_nudge_controller();
  34. controller_->SetOverrideClockForTesting(&test_clock_);
  35. // Advance the test clock so we aren't at zero time.
  36. test_clock_.Advance(base::Hours(50));
  37. }
  38. void TearDown() override {
  39. controller_->SetOverrideClockForTesting(nullptr);
  40. AshTestBase::TearDown();
  41. }
  42. protected:
  43. base::SimpleTestClock test_clock_;
  44. private:
  45. MultitaskMenuNudgeController* controller_;
  46. base::test::ScopedFeatureList scoped_feature_list_;
  47. };
  48. // Tests that the nudge is shown after resizing a window.
  49. TEST_F(MultitaskMenuNudgeControllerTest, NudgeShownAfterWindowResize) {
  50. auto window = CreateAppWindow(gfx::Rect(300, 300));
  51. // Drag to resize from the bottom right corner of `window`.
  52. auto* event_generator = GetEventGenerator();
  53. event_generator->set_current_screen_location(gfx::Point(300, 300));
  54. event_generator->PressLeftButton();
  55. EXPECT_FALSE(GetWidget());
  56. event_generator->MoveMouseBy(10, 10);
  57. EXPECT_TRUE(GetWidget());
  58. }
  59. TEST_F(MultitaskMenuNudgeControllerTest, NudgeShownAfterStateChange) {
  60. auto window = CreateAppWindow(gfx::Rect(300, 300));
  61. ASSERT_FALSE(GetWidget());
  62. WindowState::Get(window.get())->Maximize();
  63. EXPECT_TRUE(GetWidget());
  64. }
  65. // Tests that there is no crash after toggling fullscreen on and off. Regression
  66. // test for https://crbug.com/1341142.
  67. TEST_F(MultitaskMenuNudgeControllerTest, NoCrashAfterFullscreening) {
  68. auto window = CreateAppWindow(gfx::Rect(300, 300));
  69. ASSERT_FALSE(GetWidget());
  70. // Turn of animations for immersive mode, so we don't have to wait for the top
  71. // container to hide on fullscreen.
  72. auto* immersive_controller = chromeos::ImmersiveFullscreenController::Get(
  73. views::Widget::GetWidgetForNativeView(window.get()));
  74. chromeos::ImmersiveFullscreenControllerTestApi(immersive_controller)
  75. .SetupForTest();
  76. const WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
  77. WindowState::Get(window.get())->OnWMEvent(&event);
  78. // Window needs to be immersive enabled, but not revealed for the bug to
  79. // reproduce.
  80. ASSERT_TRUE(immersive_controller->IsEnabled());
  81. ASSERT_FALSE(immersive_controller->IsRevealed());
  82. WindowState::Get(window.get())->OnWMEvent(&event);
  83. EXPECT_FALSE(GetWidget());
  84. }
  85. TEST_F(MultitaskMenuNudgeControllerTest, NudgeTimeout) {
  86. auto window = CreateAppWindow(gfx::Rect(300, 300));
  87. WindowState::Get(window.get())->Maximize();
  88. ASSERT_TRUE(GetWidget());
  89. FireDismissNudgeTimer();
  90. EXPECT_FALSE(GetWidget());
  91. }
  92. // Tests that if a window gets destroyed while the nduge is showing, the nudge
  93. // disappears and there is no crash.
  94. TEST_F(MultitaskMenuNudgeControllerTest, WindowDestroyedWhileNudgeShown) {
  95. auto window = CreateAppWindow(gfx::Rect(300, 300));
  96. WindowState::Get(window.get())->Maximize();
  97. ASSERT_TRUE(GetWidget());
  98. window.reset();
  99. EXPECT_FALSE(GetWidget());
  100. }
  101. TEST_F(MultitaskMenuNudgeControllerTest, NudgeMultiDisplay) {
  102. UpdateDisplay("800x700,801+0-800x700");
  103. ASSERT_EQ(2u, Shell::GetAllRootWindows().size());
  104. auto window = CreateAppWindow(gfx::Rect(300, 300));
  105. // Maximize and restore so the nudge shows and we can still drag the window.
  106. WindowState::Get(window.get())->Maximize();
  107. WindowState::Get(window.get())->Restore();
  108. ASSERT_TRUE(GetWidget());
  109. // Drag from the caption the window to the other display. The nudge should be
  110. // on the other display, even though the window is not (the window stays
  111. // offscreen and a mirrored version called the drag window is the one on the
  112. // secondary display).
  113. auto* event_generator = GetEventGenerator();
  114. event_generator->set_current_screen_location(gfx::Point(150, 10));
  115. event_generator->PressLeftButton();
  116. event_generator->MoveMouseTo(gfx::Point(900, 0));
  117. EXPECT_EQ(Shell::GetAllRootWindows()[1],
  118. GetWidget()->GetNativeWindow()->GetRootWindow());
  119. event_generator->ReleaseLeftButton();
  120. EXPECT_EQ(Shell::GetAllRootWindows()[1],
  121. GetWidget()->GetNativeWindow()->GetRootWindow());
  122. display_move_window_util::HandleMoveActiveWindowBetweenDisplays();
  123. EXPECT_EQ(Shell::GetAllRootWindows()[0],
  124. GetWidget()->GetNativeWindow()->GetRootWindow());
  125. }
  126. // Tests that based on preferences (shown count, and last shown time), the nudge
  127. // may or may not be shown.
  128. TEST_F(MultitaskMenuNudgeControllerTest, NudgePreferences) {
  129. // Maximize the window to show the nudge for the first time.
  130. auto window = CreateAppWindow(gfx::Rect(300, 300));
  131. WindowState::Get(window.get())->Maximize();
  132. ASSERT_TRUE(GetWidget());
  133. FireDismissNudgeTimer();
  134. ASSERT_FALSE(GetWidget());
  135. // Restore the window. This does not show the nudge as 24 hours have not
  136. // elapsed since the nudge was shown.
  137. WindowState::Get(window.get())->Restore();
  138. ASSERT_FALSE(GetWidget());
  139. // Maximize and try restoring again after waiting 25 hours. The nudge should
  140. // now show for the second time.
  141. WindowState::Get(window.get())->Maximize();
  142. test_clock_.Advance(base::Hours(25));
  143. WindowState::Get(window.get())->Restore();
  144. ASSERT_TRUE(GetWidget());
  145. FireDismissNudgeTimer();
  146. ASSERT_FALSE(GetWidget());
  147. // Show the nudge for a third time. This will be the last time it is shown.
  148. test_clock_.Advance(base::Hours(25));
  149. WindowState::Get(window.get())->Maximize();
  150. ASSERT_TRUE(GetWidget());
  151. FireDismissNudgeTimer();
  152. ASSERT_FALSE(GetWidget());
  153. // Advance the clock and attempt to show the nudge for a forth time. Verify
  154. // that it will not show.
  155. test_clock_.Advance(base::Hours(25));
  156. WindowState::Get(window.get())->Restore();
  157. EXPECT_FALSE(GetWidget());
  158. }
  159. } // namespace ash