human_presence_orientation_controller.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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/public/cpp/tablet_mode_observer.h"
  6. #include "ash/shell.h"
  7. #include "ash/wm/tablet_mode/tablet_mode_controller.h"
  8. #include "base/bind.h"
  9. #include "base/scoped_observation.h"
  10. #include "chromeos/dbus/power/power_manager_client.h"
  11. #include "ui/display/display.h"
  12. #include "ui/display/display_observer.h"
  13. #include "ui/display/manager/display_manager.h"
  14. #include "ui/display/util/display_util.h"
  15. namespace ash {
  16. HumanPresenceOrientationController::HumanPresenceOrientationController() {
  17. TabletModeController* tablet_mode_controller =
  18. Shell::Get()->tablet_mode_controller();
  19. DCHECK(tablet_mode_controller);
  20. physical_tablet_state_ =
  21. tablet_mode_controller->is_in_tablet_physical_state();
  22. tablet_mode_observation_.Observe(tablet_mode_controller);
  23. chromeos::PowerManagerClient* power_manager_client =
  24. chromeos::PowerManagerClient::Get();
  25. DCHECK(power_manager_client);
  26. power_manager_client_observation_.Observe(power_manager_client);
  27. power_manager_client->GetSwitchStates(
  28. base::BindOnce(&HumanPresenceOrientationController::OnReceiveSwitchStates,
  29. weak_factory_.GetWeakPtr()));
  30. // Only care about rotation of the actual device.
  31. if (!display::HasInternalDisplay())
  32. return;
  33. display::DisplayManager* display_manager = Shell::Get()->display_manager();
  34. DCHECK(display_manager);
  35. display_rotated_ =
  36. display_manager->GetDisplayForId(display::Display::InternalDisplayId())
  37. .rotation() != display::Display::ROTATE_0;
  38. }
  39. HumanPresenceOrientationController::~HumanPresenceOrientationController() =
  40. default;
  41. void HumanPresenceOrientationController::AddObserver(Observer* observer) {
  42. observers_.AddObserver(observer);
  43. }
  44. void HumanPresenceOrientationController::RemoveObserver(Observer* observer) {
  45. observers_.RemoveObserver(observer);
  46. }
  47. bool HumanPresenceOrientationController::IsOrientationSuitable() const {
  48. return !physical_tablet_state_ && !display_rotated_ && !lid_closed_;
  49. }
  50. void HumanPresenceOrientationController::OnTabletPhysicalStateChanged() {
  51. TabletModeController* tablet_mode_controller =
  52. Shell::Get()->tablet_mode_controller();
  53. DCHECK(tablet_mode_controller);
  54. const bool physical_tablet_state =
  55. tablet_mode_controller->is_in_tablet_physical_state();
  56. UpdateOrientation(physical_tablet_state, display_rotated_, lid_closed_);
  57. }
  58. void HumanPresenceOrientationController::OnDisplayMetricsChanged(
  59. const display::Display& display,
  60. uint32_t changed_metrics) {
  61. // We only care when the rotation of the in-built display changes.
  62. if (!display.IsInternal() ||
  63. !(changed_metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION)) {
  64. return;
  65. }
  66. const bool display_rotated = display.rotation() != display::Display::ROTATE_0;
  67. UpdateOrientation(physical_tablet_state_, display_rotated, lid_closed_);
  68. }
  69. void HumanPresenceOrientationController::LidEventReceived(
  70. chromeos::PowerManagerClient::LidState state,
  71. base::TimeTicks /* timestamp */) {
  72. const bool lid_closed = state != chromeos::PowerManagerClient::LidState::OPEN;
  73. UpdateOrientation(physical_tablet_state_, display_rotated_, lid_closed);
  74. }
  75. void HumanPresenceOrientationController::OnReceiveSwitchStates(
  76. absl::optional<chromeos::PowerManagerClient::SwitchStates> switch_states) {
  77. if (switch_states.has_value()) {
  78. const bool lid_closed = switch_states->lid_state !=
  79. chromeos::PowerManagerClient::LidState::OPEN;
  80. UpdateOrientation(physical_tablet_state_, display_rotated_, lid_closed);
  81. }
  82. }
  83. void HumanPresenceOrientationController::UpdateOrientation(
  84. bool physical_tablet_state,
  85. bool display_rotated,
  86. bool lid_closed) {
  87. const bool was_suitable = IsOrientationSuitable();
  88. physical_tablet_state_ = physical_tablet_state;
  89. display_rotated_ = display_rotated;
  90. lid_closed_ = lid_closed;
  91. const bool is_suitable = IsOrientationSuitable();
  92. if (was_suitable == is_suitable)
  93. return;
  94. for (Observer& observer : observers_)
  95. observer.OnOrientationChanged(is_suitable);
  96. }
  97. } // namespace ash