backlights_forced_off_setter.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2017 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/power/backlights_forced_off_setter.h"
  5. #include "ash/constants/ash_switches.h"
  6. #include "ash/shell.h"
  7. #include "ash/system/power/scoped_backlights_forced_off.h"
  8. #include "ash/touch/touch_devices_controller.h"
  9. #include "base/bind.h"
  10. #include "base/check_op.h"
  11. #include "base/command_line.h"
  12. #include "chromeos/dbus/power_manager/backlight.pb.h"
  13. #include "ui/display/manager/touch_device_manager.h"
  14. namespace ash {
  15. BacklightsForcedOffSetter::BacklightsForcedOffSetter() {
  16. InitDisableTouchscreenWhileScreenOff();
  17. power_manager_observation_.Observe(chromeos::PowerManagerClient::Get());
  18. GetInitialBacklightsForcedOff();
  19. }
  20. BacklightsForcedOffSetter::~BacklightsForcedOffSetter() {
  21. if (active_backlights_forced_off_count_ > 0) {
  22. chromeos::PowerManagerClient::Get()->SetBacklightsForcedOff(false);
  23. }
  24. }
  25. void BacklightsForcedOffSetter::AddObserver(ScreenBacklightObserver* observer) {
  26. observers_.AddObserver(observer);
  27. }
  28. void BacklightsForcedOffSetter::RemoveObserver(
  29. ScreenBacklightObserver* observer) {
  30. observers_.RemoveObserver(observer);
  31. }
  32. ScreenBacklightState BacklightsForcedOffSetter::GetScreenBacklightState()
  33. const {
  34. return screen_backlight_state_;
  35. }
  36. std::unique_ptr<ScopedBacklightsForcedOff>
  37. BacklightsForcedOffSetter::ForceBacklightsOff() {
  38. auto scoped_backlights_forced_off =
  39. std::make_unique<ScopedBacklightsForcedOff>(base::BindOnce(
  40. &BacklightsForcedOffSetter::OnScopedBacklightsForcedOffDestroyed,
  41. weak_ptr_factory_.GetWeakPtr()));
  42. ++active_backlights_forced_off_count_;
  43. SetBacklightsForcedOff(true);
  44. return scoped_backlights_forced_off;
  45. }
  46. void BacklightsForcedOffSetter::ScreenBrightnessChanged(
  47. const power_manager::BacklightBrightnessChange& change) {
  48. const bool user_initiated =
  49. change.cause() ==
  50. power_manager::BacklightBrightnessChange_Cause_USER_REQUEST;
  51. const ScreenBacklightState old_state = screen_backlight_state_;
  52. if (change.percent() > 0.0)
  53. screen_backlight_state_ = ScreenBacklightState::ON;
  54. else
  55. screen_backlight_state_ = user_initiated ? ScreenBacklightState::OFF
  56. : ScreenBacklightState::OFF_AUTO;
  57. if (screen_backlight_state_ != old_state) {
  58. for (auto& observer : observers_)
  59. observer.OnScreenBacklightStateChanged(screen_backlight_state_);
  60. }
  61. // Disable the touchscreen when the screen is turned off due to inactivity:
  62. // https://crbug.com/743291
  63. if ((screen_backlight_state_ == ScreenBacklightState::OFF_AUTO) !=
  64. (old_state == ScreenBacklightState::OFF_AUTO) &&
  65. disable_touchscreen_while_screen_off_) {
  66. UpdateTouchscreenStatus();
  67. }
  68. }
  69. void BacklightsForcedOffSetter::PowerManagerRestarted() {
  70. if (backlights_forced_off_.has_value()) {
  71. chromeos::PowerManagerClient::Get()->SetBacklightsForcedOff(
  72. backlights_forced_off_.value());
  73. } else {
  74. GetInitialBacklightsForcedOff();
  75. }
  76. }
  77. void BacklightsForcedOffSetter::ResetForTest() {
  78. if (active_backlights_forced_off_count_ > 0) {
  79. chromeos::PowerManagerClient::Get()->SetBacklightsForcedOff(false);
  80. }
  81. // Cancel all backlights forced off requests.
  82. weak_ptr_factory_.InvalidateWeakPtrs();
  83. active_backlights_forced_off_count_ = 0;
  84. InitDisableTouchscreenWhileScreenOff();
  85. backlights_forced_off_.reset();
  86. GetInitialBacklightsForcedOff();
  87. }
  88. void BacklightsForcedOffSetter::InitDisableTouchscreenWhileScreenOff() {
  89. disable_touchscreen_while_screen_off_ =
  90. !base::CommandLine::ForCurrentProcess()->HasSwitch(
  91. switches::kTouchscreenUsableWhileScreenOff);
  92. }
  93. void BacklightsForcedOffSetter::GetInitialBacklightsForcedOff() {
  94. chromeos::PowerManagerClient::Get()->GetBacklightsForcedOff(base::BindOnce(
  95. &BacklightsForcedOffSetter::OnGotInitialBacklightsForcedOff,
  96. weak_ptr_factory_.GetWeakPtr()));
  97. }
  98. void BacklightsForcedOffSetter::OnGotInitialBacklightsForcedOff(
  99. absl::optional<bool> is_forced_off) {
  100. if (backlights_forced_off_.has_value() || !is_forced_off.has_value())
  101. return;
  102. backlights_forced_off_ = is_forced_off;
  103. UpdateTouchscreenStatus();
  104. for (auto& observer : observers_)
  105. observer.OnBacklightsForcedOffChanged(backlights_forced_off_.value());
  106. }
  107. void BacklightsForcedOffSetter::OnScopedBacklightsForcedOffDestroyed() {
  108. DCHECK_GT(active_backlights_forced_off_count_, 0);
  109. --active_backlights_forced_off_count_;
  110. SetBacklightsForcedOff(active_backlights_forced_off_count_ > 0);
  111. }
  112. void BacklightsForcedOffSetter::SetBacklightsForcedOff(bool forced_off) {
  113. if (backlights_forced_off_.has_value() &&
  114. backlights_forced_off_.value() == forced_off) {
  115. return;
  116. }
  117. backlights_forced_off_ = forced_off;
  118. chromeos::PowerManagerClient::Get()->SetBacklightsForcedOff(forced_off);
  119. UpdateTouchscreenStatus();
  120. for (auto& observer : observers_)
  121. observer.OnBacklightsForcedOffChanged(backlights_forced_off_.value());
  122. }
  123. void BacklightsForcedOffSetter::UpdateTouchscreenStatus() {
  124. // If there is an external touch display connected to the device, then we want
  125. // to allow users to wake up the device using this external touch device. The
  126. // kernel blocks wake up events from internal input devices when the screen is
  127. // off or is in the suspended state.
  128. // See https://crbug/797411 for more details.
  129. const bool disable_touchscreen =
  130. backlights_forced_off_.value_or(false) ||
  131. (screen_backlight_state_ == ScreenBacklightState::OFF_AUTO &&
  132. disable_touchscreen_while_screen_off_ &&
  133. !display::HasExternalTouchscreenDevice());
  134. Shell::Get()->touch_devices_controller()->SetTouchscreenEnabled(
  135. !disable_touchscreen, TouchDeviceEnabledSource::GLOBAL);
  136. }
  137. } // namespace ash