human_presence_orientation_controller_unittest.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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/system/human_presence/human_presence_orientation_controller.h"
  5. #include "ash/constants/ash_features.h"
  6. #include "ash/constants/ash_switches.h"
  7. #include "ash/shell.h"
  8. #include "ash/test/ash_test_base.h"
  9. #include "base/command_line.h"
  10. #include "base/test/scoped_command_line.h"
  11. #include "base/test/scoped_feature_list.h"
  12. #include "base/time/time.h"
  13. #include "chromeos/dbus/power/fake_power_manager_client.h"
  14. #include "ui/display/display.h"
  15. #include "ui/display/manager/display_manager.h"
  16. #include "ui/display/test/display_manager_test_api.h"
  17. namespace ash {
  18. namespace {
  19. // A simple observer that lists its last observation.
  20. class TestObserver : public HumanPresenceOrientationController::Observer {
  21. public:
  22. TestObserver() = default;
  23. TestObserver(const TestObserver&) = delete;
  24. TestObserver& operator=(const TestObserver&) = delete;
  25. ~TestObserver() override = default;
  26. // HumanPresenceOrientationController::Observer::
  27. void OnOrientationChanged(bool suitable_for_hps) override {
  28. ++observation_count_;
  29. last_observation_ = suitable_for_hps;
  30. }
  31. int observation_count() { return observation_count_; }
  32. int last_observation() { return last_observation_; }
  33. private:
  34. int observation_count_ = 0;
  35. bool last_observation_ = false;
  36. };
  37. class HumanPresenceOrientationControllerTest : public AshTestBase {
  38. public:
  39. HumanPresenceOrientationControllerTest() = default;
  40. HumanPresenceOrientationControllerTest(
  41. const HumanPresenceOrientationControllerTest&) = delete;
  42. HumanPresenceOrientationControllerTest& operator=(
  43. const HumanPresenceOrientationControllerTest&) = delete;
  44. ~HumanPresenceOrientationControllerTest() override = default;
  45. void SetUp() override {
  46. scoped_feature_list_.InitWithFeatures({ash::features::kSnoopingProtection},
  47. {ash::features::kQuickDim});
  48. base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kHasHps);
  49. PowerManagerClient::InitializeFake();
  50. AshTestBase::SetUp();
  51. orientation_controller_ =
  52. Shell::Get()->human_presence_orientation_controller();
  53. tablet_mode_controller_ = Shell::Get()->tablet_mode_controller();
  54. display_manager_ = Shell::Get()->display_manager();
  55. power_manager_client_ = AshTestBase::power_manager_client();
  56. // Two displays: the first internal and the second external.
  57. UpdateDisplay("800x600,1024x768");
  58. display::test::DisplayManagerTestApi(display_manager_)
  59. .SetFirstDisplayAsInternalDisplay();
  60. }
  61. protected:
  62. void RotateDisplay(int display_index, int degrees) {
  63. const int64_t id = display_manager_->GetDisplayAt(display_index).id();
  64. display_manager_->SetDisplayRotation(
  65. id, display::Display::DegreesToRotation(degrees),
  66. display::Display::RotationSource::ACTIVE);
  67. }
  68. HumanPresenceOrientationController* orientation_controller_ = nullptr;
  69. TabletModeController* tablet_mode_controller_ = nullptr;
  70. display::DisplayManager* display_manager_ = nullptr;
  71. chromeos::FakePowerManagerClient* power_manager_client_ = nullptr;
  72. private:
  73. base::test::ScopedFeatureList scoped_feature_list_;
  74. base::test::ScopedCommandLine scoped_command_line_;
  75. };
  76. TEST_F(HumanPresenceOrientationControllerTest, TabletMode) {
  77. ASSERT_TRUE(orientation_controller_->IsOrientationSuitable());
  78. tablet_mode_controller_->SetEnabledForTest(true);
  79. EXPECT_FALSE(orientation_controller_->IsOrientationSuitable());
  80. tablet_mode_controller_->SetEnabledForTest(false);
  81. EXPECT_TRUE(orientation_controller_->IsOrientationSuitable());
  82. }
  83. TEST_F(HumanPresenceOrientationControllerTest, DisplayOrientation) {
  84. ASSERT_TRUE(orientation_controller_->IsOrientationSuitable());
  85. // Rotating the external display has no effect on our sensor.
  86. RotateDisplay(/*display_index=*/1, /*degrees=*/90);
  87. EXPECT_TRUE(orientation_controller_->IsOrientationSuitable());
  88. // Rotating the internal display _does_ have an effect on our sensor.
  89. RotateDisplay(/*display_index=*/0, /*degrees=*/270);
  90. EXPECT_FALSE(orientation_controller_->IsOrientationSuitable());
  91. RotateDisplay(/*display_index=*/1, /*degrees=*/0);
  92. EXPECT_FALSE(orientation_controller_->IsOrientationSuitable());
  93. RotateDisplay(/*display_index=*/0, /*degrees=*/0);
  94. EXPECT_TRUE(orientation_controller_->IsOrientationSuitable());
  95. }
  96. TEST_F(HumanPresenceOrientationControllerTest, LidState) {
  97. ASSERT_TRUE(orientation_controller_->IsOrientationSuitable());
  98. power_manager_client_->SetLidState(
  99. chromeos::PowerManagerClient::LidState::CLOSED, base::TimeTicks());
  100. ASSERT_FALSE(orientation_controller_->IsOrientationSuitable());
  101. power_manager_client_->SetLidState(
  102. chromeos::PowerManagerClient::LidState::OPEN, base::TimeTicks());
  103. ASSERT_TRUE(orientation_controller_->IsOrientationSuitable());
  104. }
  105. TEST_F(HumanPresenceOrientationControllerTest, Observer) {
  106. TestObserver observer;
  107. orientation_controller_->AddObserver(&observer);
  108. ASSERT_TRUE(orientation_controller_->IsOrientationSuitable());
  109. ASSERT_EQ(observer.observation_count(), 0);
  110. // Rotating the external display has no effect on our sensor, so no event
  111. // should fire.
  112. RotateDisplay(/*display_index=*/1, /*degrees=*/90);
  113. EXPECT_EQ(observer.observation_count(), 0);
  114. // Entering tablet mode should explicitly notify observers.
  115. tablet_mode_controller_->SetEnabledForTest(true);
  116. EXPECT_EQ(observer.observation_count(), 1);
  117. EXPECT_EQ(observer.last_observation(), /*suitable_for_hps=*/false);
  118. // While rotating the internal display makes the device unsuitable, no event
  119. // should fire because the suitability hasn't _changed_.
  120. RotateDisplay(/*display_index=*/0, /*degrees=*/90);
  121. EXPECT_EQ(observer.observation_count(), 1);
  122. EXPECT_EQ(observer.last_observation(), /*suitable_for_hps=*/false);
  123. tablet_mode_controller_->SetEnabledForTest(false);
  124. RotateDisplay(/*display_index=*/0, /*degrees=*/0);
  125. EXPECT_EQ(observer.observation_count(), 2);
  126. EXPECT_EQ(observer.last_observation(), /*suitable_for_hps=*/true);
  127. // Closing the device lid makes the device unsuitable.
  128. power_manager_client_->SetLidState(
  129. chromeos::PowerManagerClient::LidState::CLOSED, base::TimeTicks());
  130. EXPECT_EQ(observer.observation_count(), 3);
  131. ASSERT_FALSE(observer.last_observation());
  132. // Opening the device lid makes the device suitable.
  133. power_manager_client_->SetLidState(
  134. chromeos::PowerManagerClient::LidState::OPEN, base::TimeTicks());
  135. EXPECT_EQ(observer.observation_count(), 4);
  136. EXPECT_TRUE(observer.last_observation());
  137. orientation_controller_->RemoveObserver(&observer);
  138. }
  139. } // namespace
  140. } // namespace ash