Commit 9d0c82f4 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Introduce BacklightsForcedOffSetter

Extracts code that deals with calling powerd SetBacklightsForcedOff
method from PowerButtonDisplayController to a separate class that can
handle multiple concurrent requests to set backlights off (by keeping
track of the active set backlights forced off requests).

While currently only PowerButtonDisplayController uses
SetBackligthsForcedOff, it's planned to add similar ability to lock
screen note launching code in a follow-up (the idea is to force
backlights off if the lock screen app is launched while the display is
turned off, until the app launch is done).
Goal of BacklightsForcedOffSetter is to prevent these two classes from
conflicting with each other - it will ensure backlights are forced off
as long as at least one backlights forced off request is active.

Backlights can be forced off using
BacklightsForcedOffSetter::ForceBacklightsOff, which returns
ScopedBacklightsForcedOff unique ptr - to stop backlights forced off
request, callers should just reset the returned unique ptr.

BUG=767711
TEST=Press power button, verify display is turned off. Press power
     button again - display is turned on.

Change-Id: Ie47f546edb51659bb82ba4618b069569a2d188c6
Reviewed-on: https://chromium-review.googlesource.com/758963
Commit-Queue: Toni Barzic <tbarzic@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Reviewed-by: default avatarQiang(Joe) Xu <warx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521923}
parent cdfd4cb7
...@@ -564,6 +564,8 @@ component("ash") { ...@@ -564,6 +564,8 @@ component("ash") {
"system/palette/tools/magnifier_mode.h", "system/palette/tools/magnifier_mode.h",
"system/palette/tools/metalayer_mode.cc", "system/palette/tools/metalayer_mode.cc",
"system/palette/tools/metalayer_mode.h", "system/palette/tools/metalayer_mode.h",
"system/power/backlights_forced_off_setter.cc",
"system/power/backlights_forced_off_setter.h",
"system/power/battery_notification.cc", "system/power/battery_notification.cc",
"system/power/battery_notification.h", "system/power/battery_notification.h",
"system/power/dual_role_notification.cc", "system/power/dual_role_notification.cc",
...@@ -582,6 +584,8 @@ component("ash") { ...@@ -582,6 +584,8 @@ component("ash") {
"system/power/power_status.h", "system/power/power_status.h",
"system/power/power_status_view.cc", "system/power/power_status_view.cc",
"system/power/power_status_view.h", "system/power/power_status_view.h",
"system/power/scoped_backlights_forced_off.cc",
"system/power/scoped_backlights_forced_off.h",
"system/power/tablet_power_button_controller.cc", "system/power/tablet_power_button_controller.cc",
"system/power/tablet_power_button_controller.h", "system/power/tablet_power_button_controller.h",
"system/power/tray_power.cc", "system/power/tray_power.cc",
...@@ -1441,6 +1445,7 @@ test("ash_unittests") { ...@@ -1441,6 +1445,7 @@ test("ash_unittests") {
"system/palette/tools/create_note_unittest.cc", "system/palette/tools/create_note_unittest.cc",
"system/palette/tools/metalayer_unittest.cc", "system/palette/tools/metalayer_unittest.cc",
"system/palette/tools/screenshot_unittest.cc", "system/palette/tools/screenshot_unittest.cc",
"system/power/backlights_forced_off_setter_unittest.cc",
"system/power/peripheral_battery_notifier_unittest.cc", "system/power/peripheral_battery_notifier_unittest.cc",
"system/power/power_button_screenshot_controller_unittest.cc", "system/power/power_button_screenshot_controller_unittest.cc",
"system/power/power_event_observer_unittest.cc", "system/power/power_event_observer_unittest.cc",
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
#include "ash/system/night_light/night_light_controller.h" #include "ash/system/night_light/night_light_controller.h"
#include "ash/system/palette/palette_tray.h" #include "ash/system/palette/palette_tray.h"
#include "ash/system/palette/palette_welcome_bubble.h" #include "ash/system/palette/palette_welcome_bubble.h"
#include "ash/system/power/backlights_forced_off_setter.h"
#include "ash/system/power/peripheral_battery_notifier.h" #include "ash/system/power/peripheral_battery_notifier.h"
#include "ash/system/power/power_button_controller.h" #include "ash/system/power/power_button_controller.h"
#include "ash/system/power/power_event_observer.h" #include "ash/system/power/power_event_observer.h"
...@@ -725,6 +726,7 @@ Shell::~Shell() { ...@@ -725,6 +726,7 @@ Shell::~Shell() {
power_button_controller_.reset(); power_button_controller_.reset();
lock_state_controller_.reset(); lock_state_controller_.reset();
backlights_forced_off_setter_.reset();
screen_pinning_controller_.reset(); screen_pinning_controller_.reset();
...@@ -1009,9 +1011,12 @@ void Shell::Init(ui::ContextFactory* context_factory, ...@@ -1009,9 +1011,12 @@ void Shell::Init(ui::ContextFactory* context_factory,
sticky_keys_controller_.reset(new StickyKeysController); sticky_keys_controller_.reset(new StickyKeysController);
screen_pinning_controller_ = std::make_unique<ScreenPinningController>(); screen_pinning_controller_ = std::make_unique<ScreenPinningController>();
backlights_forced_off_setter_ = std::make_unique<BacklightsForcedOffSetter>();
lock_state_controller_ = lock_state_controller_ =
std::make_unique<LockStateController>(shutdown_controller_.get()); std::make_unique<LockStateController>(shutdown_controller_.get());
power_button_controller_ = std::make_unique<PowerButtonController>(); power_button_controller_ = std::make_unique<PowerButtonController>(
backlights_forced_off_setter_.get());
// Pass the initial display state to PowerButtonController. // Pass the initial display state to PowerButtonController.
power_button_controller_->OnDisplayModeChanged( power_button_controller_->OnDisplayModeChanged(
display_configurator_->cached_displays()); display_configurator_->cached_displays());
......
...@@ -86,6 +86,7 @@ class AppListDelegateImpl; ...@@ -86,6 +86,7 @@ class AppListDelegateImpl;
class NativeCursorManagerAsh; class NativeCursorManagerAsh;
class AshTouchTransformController; class AshTouchTransformController;
class AutoclickController; class AutoclickController;
class BacklightsForcedOffSetter;
class BluetoothNotificationController; class BluetoothNotificationController;
class BluetoothPowerController; class BluetoothPowerController;
class BrightnessControlDelegate; class BrightnessControlDelegate;
...@@ -635,6 +636,7 @@ class ASH_EXPORT Shell : public SessionObserver, ...@@ -635,6 +636,7 @@ class ASH_EXPORT Shell : public SessionObserver,
std::unique_ptr<AccessibilityController> accessibility_controller_; std::unique_ptr<AccessibilityController> accessibility_controller_;
std::unique_ptr<AccessibilityDelegate> accessibility_delegate_; std::unique_ptr<AccessibilityDelegate> accessibility_delegate_;
std::unique_ptr<AshDisplayController> ash_display_controller_; std::unique_ptr<AshDisplayController> ash_display_controller_;
std::unique_ptr<BacklightsForcedOffSetter> backlights_forced_off_setter_;
std::unique_ptr<BrightnessControlDelegate> brightness_control_delegate_; std::unique_ptr<BrightnessControlDelegate> brightness_control_delegate_;
std::unique_ptr<CastConfigController> cast_config_; std::unique_ptr<CastConfigController> cast_config_;
std::unique_ptr<DragDropController> drag_drop_controller_; std::unique_ptr<DragDropController> drag_drop_controller_;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ash/root_window_controller.h" #include "ash/root_window_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/system/power/backlights_forced_off_setter.h"
#include "ash/system/power/power_button_controller.h" #include "ash/system/power/power_button_controller.h"
#include "components/prefs/testing_pref_service.h" #include "components/prefs/testing_pref_service.h"
...@@ -47,7 +48,9 @@ void ShellTestApi::OnLocalStatePrefServiceInitialized( ...@@ -47,7 +48,9 @@ void ShellTestApi::OnLocalStatePrefServiceInitialized(
} }
void ShellTestApi::ResetPowerButtonControllerForTest() { void ShellTestApi::ResetPowerButtonControllerForTest() {
shell_->power_button_controller_ = std::make_unique<PowerButtonController>(); shell_->backlights_forced_off_setter_->ResetForTest();
shell_->power_button_controller_ = std::make_unique<PowerButtonController>(
shell_->backlights_forced_off_setter_.get());
} }
} // namespace ash } // namespace ash
// Copyright 2017 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/system/power/backlights_forced_off_setter.h"
#include "ash/public/cpp/ash_switches.h"
#include "ash/shell.h"
#include "ash/system/power/scoped_backlights_forced_off.h"
#include "ash/touch/touch_devices_controller.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "chromeos/dbus/dbus_thread_manager.h"
namespace ash {
BacklightsForcedOffSetter::BacklightsForcedOffSetter()
: power_manager_observer_(this), weak_ptr_factory_(this) {
InitDisableTouchscreenWhileScreenOff();
power_manager_observer_.Add(
chromeos::DBusThreadManager::Get()->GetPowerManagerClient());
GetInitialBacklightsForcedOff();
}
BacklightsForcedOffSetter::~BacklightsForcedOffSetter() {
if (active_backlights_forced_off_count_ > 0) {
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->SetBacklightsForcedOff(false);
}
}
void BacklightsForcedOffSetter::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void BacklightsForcedOffSetter::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
std::unique_ptr<ScopedBacklightsForcedOff>
BacklightsForcedOffSetter::ForceBacklightsOff() {
auto scoped_backlights_forced_off =
std::make_unique<ScopedBacklightsForcedOff>(base::BindOnce(
&BacklightsForcedOffSetter::OnScopedBacklightsForcedOffDestroyed,
weak_ptr_factory_.GetWeakPtr()));
++active_backlights_forced_off_count_;
SetBacklightsForcedOff(true);
return scoped_backlights_forced_off;
}
void BacklightsForcedOffSetter::BrightnessChanged(int level,
bool user_initiated) {
const ScreenState old_state = screen_state_;
if (level != 0)
screen_state_ = ScreenState::ON;
else
screen_state_ = user_initiated ? ScreenState::OFF : ScreenState::OFF_AUTO;
if (screen_state_ != old_state) {
for (auto& observer : observers_)
observer.OnScreenStateChanged(screen_state_);
}
// Disable the touchscreen when the screen is turned off due to inactivity:
// https://crbug.com/743291
if ((screen_state_ == ScreenState::OFF_AUTO) !=
(old_state == ScreenState::OFF_AUTO) &&
disable_touchscreen_while_screen_off_) {
UpdateTouchscreenStatus();
}
}
void BacklightsForcedOffSetter::PowerManagerRestarted() {
if (backlights_forced_off_.has_value()) {
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->SetBacklightsForcedOff(backlights_forced_off_.value());
} else {
GetInitialBacklightsForcedOff();
}
}
void BacklightsForcedOffSetter::ResetForTest() {
if (active_backlights_forced_off_count_ > 0) {
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->SetBacklightsForcedOff(false);
}
// Cancel all backlights forced off requests.
weak_ptr_factory_.InvalidateWeakPtrs();
active_backlights_forced_off_count_ = 0;
InitDisableTouchscreenWhileScreenOff();
backlights_forced_off_.reset();
GetInitialBacklightsForcedOff();
}
void BacklightsForcedOffSetter::InitDisableTouchscreenWhileScreenOff() {
disable_touchscreen_while_screen_off_ =
!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kTouchscreenUsableWhileScreenOff);
}
void BacklightsForcedOffSetter::GetInitialBacklightsForcedOff() {
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->GetBacklightsForcedOff(base::BindOnce(
&BacklightsForcedOffSetter::OnGotInitialBacklightsForcedOff,
weak_ptr_factory_.GetWeakPtr()));
}
void BacklightsForcedOffSetter::OnGotInitialBacklightsForcedOff(
base::Optional<bool> is_forced_off) {
if (backlights_forced_off_.has_value() || !is_forced_off.has_value())
return;
backlights_forced_off_ = is_forced_off;
UpdateTouchscreenStatus();
for (auto& observer : observers_)
observer.OnBacklightsForcedOffChanged(backlights_forced_off_.value());
}
void BacklightsForcedOffSetter::OnScopedBacklightsForcedOffDestroyed() {
DCHECK_GT(active_backlights_forced_off_count_, 0);
--active_backlights_forced_off_count_;
SetBacklightsForcedOff(active_backlights_forced_off_count_ > 0);
}
void BacklightsForcedOffSetter::SetBacklightsForcedOff(bool forced_off) {
if (backlights_forced_off_.has_value() &&
backlights_forced_off_.value() == forced_off) {
return;
}
backlights_forced_off_ = forced_off;
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->SetBacklightsForcedOff(forced_off);
UpdateTouchscreenStatus();
for (auto& observer : observers_)
observer.OnBacklightsForcedOffChanged(backlights_forced_off_.value());
}
void BacklightsForcedOffSetter::UpdateTouchscreenStatus() {
const bool disable_touchscreen = backlights_forced_off_.value_or(false) ||
(screen_state_ == ScreenState::OFF_AUTO &&
disable_touchscreen_while_screen_off_);
Shell::Get()->touch_devices_controller()->SetTouchscreenEnabled(
!disable_touchscreen, TouchscreenEnabledSource::GLOBAL);
}
} // namespace ash
// Copyright 2017 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.
#ifndef ASH_SYSTEM_POWER_BACKLIGHTS_FORCED_OFF_SETTER_H_
#define ASH_SYSTEM_POWER_BACKLIGHTS_FORCED_OFF_SETTER_H_
#include <memory>
#include "ash/ash_export.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "chromeos/dbus/power_manager_client.h"
namespace ash {
class ScopedBacklightsForcedOff;
// BacklightsForcedOffSetter manages multiple requests to force the backlights
// off and coalesces them into SetBacklightsForcedOff D-Bus calls to powerd.
class ASH_EXPORT BacklightsForcedOffSetter
: public chromeos::PowerManagerClient::Observer {
public:
// Screen state as communicated by D-Bus signals from powerd about backlight
// brightness changes.
enum class ScreenState {
// The screen is on.
ON,
// The screen is off.
OFF,
// The screen is off, specifically due to an automated change like user
// inactivity.
OFF_AUTO,
};
class Observer {
public:
virtual ~Observer() = default;
// Called when the observed BacklightsForcedOffSetter instance stops or
// starts forcing backlights off.
virtual void OnBacklightsForcedOffChanged(bool backlights_forced_off) {}
// Called when the screen state change is detected.
virtual void OnScreenStateChanged(ScreenState screen_state) {}
};
BacklightsForcedOffSetter();
~BacklightsForcedOffSetter() override;
bool backlights_forced_off() const {
return backlights_forced_off_.value_or(false);
}
ScreenState screen_state() const { return screen_state_; }
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Forces the backlights off. The backlights will be kept in the forced-off
// state until all requests have been destroyed.
std::unique_ptr<ScopedBacklightsForcedOff> ForceBacklightsOff();
// Overridden from chromeos::PowerManagerClient::Observer:
void BrightnessChanged(int level, bool user_initiated) override;
void PowerManagerRestarted() override;
// Resets internal state for tests.
// Note: This will silently cancel all active backlights forced off requests.
void ResetForTest();
private:
// Sets |disable_touchscreen_while_screen_off_| depending on the state of the
// current command line,
void InitDisableTouchscreenWhileScreenOff();
// Sends a request to powerd to get the backlights forced off state so that
// |backlights_forced_off_| can be initialized.
void GetInitialBacklightsForcedOff();
// Callback for |GetInitialBacklightsForcedOff()|.
void OnGotInitialBacklightsForcedOff(base::Optional<bool> is_forced_off);
// Removes a force backlights off request from the list of active ones, which
// effectively cancels the request. This is passed to every
// ScopedBacklightsForcedOff created by |ForceBacklightsOff| as its
// cancellation callback.
void OnScopedBacklightsForcedOffDestroyed();
// Updates the power manager's backlights-forced-off state.
void SetBacklightsForcedOff(bool forced_off);
// Enables or disables the touchscreen by updating the global touchscreen
// enabled status. The touchscreen is disabled when backlights are forced off
// or |screen_state_| is OFF_AUTO.
void UpdateTouchscreenStatus();
// Controls whether the touchscreen is disabled when the screen is turned off
// due to user inactivity.
bool disable_touchscreen_while_screen_off_ = true;
// Current forced-off state of backlights.
base::Optional<bool> backlights_forced_off_;
// Current screen state.
ScreenState screen_state_ = ScreenState::ON;
// Number of active backlights forced off requests.
int active_backlights_forced_off_count_ = 0;
base::ObserverList<Observer> observers_;
ScopedObserver<chromeos::PowerManagerClient,
chromeos::PowerManagerClient::Observer>
power_manager_observer_;
base::WeakPtrFactory<BacklightsForcedOffSetter> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BacklightsForcedOffSetter);
};
} // namespace ash
#endif // ASH_SYSTEM_POWER_BACKLIGHTS_FORCED_OFF_SETTER_H_
// Copyright 2017 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/system/power/backlights_forced_off_setter.h"
#include <memory>
#include <utility>
#include <vector>
#include "ash/system/power/scoped_backlights_forced_off.h"
#include "ash/test/ash_test_base.h"
#include "base/macros.h"
#include "base/scoped_observer.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_power_manager_client.h"
namespace ash {
namespace {
class TestObserver : public BacklightsForcedOffSetter::Observer {
public:
explicit TestObserver(BacklightsForcedOffSetter* backlights_forced_off_setter)
: backlights_forced_off_setter_(backlights_forced_off_setter),
scoped_observer_(this) {
scoped_observer_.Add(backlights_forced_off_setter);
}
~TestObserver() override = default;
const std::vector<bool>& forced_off_states() const {
return forced_off_states_;
}
void ClearForcedOffStates() { forced_off_states_.clear(); }
// BacklightsForcedOffSetter::Observer:
void OnBacklightsForcedOffChanged(bool backlights_forced_off) override {
ASSERT_EQ(backlights_forced_off,
backlights_forced_off_setter_->backlights_forced_off());
forced_off_states_.push_back(backlights_forced_off);
}
private:
BacklightsForcedOffSetter* const backlights_forced_off_setter_;
std::vector<bool> forced_off_states_;
ScopedObserver<BacklightsForcedOffSetter, BacklightsForcedOffSetter::Observer>
scoped_observer_;
DISALLOW_COPY_AND_ASSIGN(TestObserver);
};
} // namespace
class BacklightsForcedOffSetterTest : public AshTestBase {
public:
BacklightsForcedOffSetterTest() = default;
~BacklightsForcedOffSetterTest() override = default;
void SetUp() override {
auto power_manager_client =
std::make_unique<chromeos::FakePowerManagerClient>();
power_manager_client_ = power_manager_client.get();
chromeos::DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient(
std::move(power_manager_client));
AshTestBase::SetUp();
backlights_forced_off_setter_ =
std::make_unique<BacklightsForcedOffSetter>();
backlights_forced_off_observer_ =
std::make_unique<TestObserver>(backlights_forced_off_setter_.get());
}
void TearDown() override {
backlights_forced_off_observer_.reset();
backlights_forced_off_setter_.reset();
AshTestBase::TearDown();
chromeos::DBusThreadManager::Shutdown();
}
void ResetBacklightsForcedOffSetter() {
backlights_forced_off_observer_.reset();
backlights_forced_off_setter_.reset();
}
protected:
// Owned by DBusThreadManager.
chromeos::FakePowerManagerClient* power_manager_client_ = nullptr;
std::unique_ptr<BacklightsForcedOffSetter> backlights_forced_off_setter_;
std::unique_ptr<TestObserver> backlights_forced_off_observer_;
private:
DISALLOW_COPY_AND_ASSIGN(BacklightsForcedOffSetterTest);
};
TEST_F(BacklightsForcedOffSetterTest, SingleForcedOffRequest) {
ASSERT_FALSE(power_manager_client_->backlights_forced_off());
std::unique_ptr<ScopedBacklightsForcedOff> scoped_forced_off =
backlights_forced_off_setter_->ForceBacklightsOff();
EXPECT_TRUE(power_manager_client_->backlights_forced_off());
EXPECT_EQ(std::vector<bool>({true}),
backlights_forced_off_observer_->forced_off_states());
backlights_forced_off_observer_->ClearForcedOffStates();
scoped_forced_off.reset();
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
EXPECT_EQ(std::vector<bool>({false}),
backlights_forced_off_observer_->forced_off_states());
}
TEST_F(BacklightsForcedOffSetterTest, BacklightsForcedOffSetterDeleted) {
ASSERT_FALSE(power_manager_client_->backlights_forced_off());
std::unique_ptr<ScopedBacklightsForcedOff> scoped_forced_off =
backlights_forced_off_setter_->ForceBacklightsOff();
EXPECT_TRUE(power_manager_client_->backlights_forced_off());
EXPECT_EQ(std::vector<bool>({true}),
backlights_forced_off_observer_->forced_off_states());
backlights_forced_off_observer_->ClearForcedOffStates();
ResetBacklightsForcedOffSetter();
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
// Verify that deleting scoped forced off request does not affect
// power manager state (nor cause a crash).
scoped_forced_off.reset();
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
}
TEST_F(BacklightsForcedOffSetterTest,
OverlappingRequests_SecondRequestResetFirst) {
ASSERT_FALSE(power_manager_client_->backlights_forced_off());
std::unique_ptr<ScopedBacklightsForcedOff> scoped_forced_off_1 =
backlights_forced_off_setter_->ForceBacklightsOff();
EXPECT_TRUE(power_manager_client_->backlights_forced_off());
EXPECT_EQ(std::vector<bool>({true}),
backlights_forced_off_observer_->forced_off_states());
backlights_forced_off_observer_->ClearForcedOffStates();
std::unique_ptr<ScopedBacklightsForcedOff> scoped_forced_off_2 =
backlights_forced_off_setter_->ForceBacklightsOff();
EXPECT_TRUE(power_manager_client_->backlights_forced_off());
EXPECT_TRUE(backlights_forced_off_observer_->forced_off_states().empty());
scoped_forced_off_2.reset();
EXPECT_TRUE(power_manager_client_->backlights_forced_off());
EXPECT_TRUE(backlights_forced_off_observer_->forced_off_states().empty());
scoped_forced_off_1.reset();
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
EXPECT_EQ(std::vector<bool>({false}),
backlights_forced_off_observer_->forced_off_states());
}
TEST_F(BacklightsForcedOffSetterTest,
OverlappingRequests_FirstRequestResetFirst) {
ASSERT_FALSE(power_manager_client_->backlights_forced_off());
std::unique_ptr<ScopedBacklightsForcedOff> scoped_forced_off_1 =
backlights_forced_off_setter_->ForceBacklightsOff();
EXPECT_TRUE(power_manager_client_->backlights_forced_off());
EXPECT_EQ(std::vector<bool>({true}),
backlights_forced_off_observer_->forced_off_states());
backlights_forced_off_observer_->ClearForcedOffStates();
std::unique_ptr<ScopedBacklightsForcedOff> scoped_forced_off_2 =
backlights_forced_off_setter_->ForceBacklightsOff();
EXPECT_TRUE(power_manager_client_->backlights_forced_off());
EXPECT_TRUE(backlights_forced_off_observer_->forced_off_states().empty());
scoped_forced_off_1.reset();
EXPECT_TRUE(backlights_forced_off_observer_->forced_off_states().empty());
scoped_forced_off_2.reset();
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
EXPECT_EQ(std::vector<bool>({false}),
backlights_forced_off_observer_->forced_off_states());
}
} // namespace ash
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "ash/system/power/power_button_controller.h" #include "ash/system/power/power_button_controller.h"
#include <utility>
#include "ash/accelerators/accelerator_controller.h" #include "ash/accelerators/accelerator_controller.h"
#include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
...@@ -31,12 +33,14 @@ constexpr base::TimeDelta kDisplayOffAfterLockDelay = ...@@ -31,12 +33,14 @@ constexpr base::TimeDelta kDisplayOffAfterLockDelay =
} // namespace } // namespace
PowerButtonController::PowerButtonController() PowerButtonController::PowerButtonController(
: lock_state_controller_(Shell::Get()->lock_state_controller()), BacklightsForcedOffSetter* backlights_forced_off_setter)
: backlights_forced_off_setter_(backlights_forced_off_setter),
lock_state_controller_(Shell::Get()->lock_state_controller()),
tick_clock_(new base::DefaultTickClock) { tick_clock_(new base::DefaultTickClock) {
ProcessCommandLine(); ProcessCommandLine();
display_controller_ = display_controller_ = std::make_unique<PowerButtonDisplayController>(
std::make_unique<PowerButtonDisplayController>(tick_clock_.get()); backlights_forced_off_setter_, tick_clock_.get());
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
this); this);
chromeos::AccelerometerReader::GetInstance()->AddObserver(this); chromeos::AccelerometerReader::GetInstance()->AddObserver(this);
...@@ -186,7 +190,7 @@ void PowerButtonController::PowerButtonEventReceived( ...@@ -186,7 +190,7 @@ void PowerButtonController::PowerButtonEventReceived(
// stop forcing the display off if TabletPowerButtonController isn't being // stop forcing the display off if TabletPowerButtonController isn't being
// used. // used.
if (down && force_clamshell_power_button_) if (down && force_clamshell_power_button_)
display_controller_->SetDisplayForcedOff(false); display_controller_->SetBacklightsForcedOff(false);
// Handle tablet mode power button screenshot accelerator. // Handle tablet mode power button screenshot accelerator.
if (screenshot_controller_ && if (screenshot_controller_ &&
...@@ -228,8 +232,8 @@ void PowerButtonController::SetTickClockForTesting( ...@@ -228,8 +232,8 @@ void PowerButtonController::SetTickClockForTesting(
DCHECK(tick_clock); DCHECK(tick_clock);
tick_clock_ = std::move(tick_clock); tick_clock_ = std::move(tick_clock);
display_controller_ = display_controller_ = std::make_unique<PowerButtonDisplayController>(
std::make_unique<PowerButtonDisplayController>(tick_clock_.get()); backlights_forced_off_setter_, tick_clock_.get());
} }
bool PowerButtonController::TriggerDisplayOffTimerForTesting() { bool PowerButtonController::TriggerDisplayOffTimerForTesting() {
...@@ -253,7 +257,7 @@ void PowerButtonController::ProcessCommandLine() { ...@@ -253,7 +257,7 @@ void PowerButtonController::ProcessCommandLine() {
} }
void PowerButtonController::ForceDisplayOffAfterLock() { void PowerButtonController::ForceDisplayOffAfterLock() {
display_controller_->SetDisplayForcedOff(true); display_controller_->SetBacklightsForcedOff(true);
} }
} // namespace ash } // namespace ash
...@@ -22,6 +22,7 @@ class TimeTicks; ...@@ -22,6 +22,7 @@ class TimeTicks;
namespace ash { namespace ash {
class BacklightsForcedOffSetter;
class LockStateController; class LockStateController;
class PowerButtonDisplayController; class PowerButtonDisplayController;
class PowerButtonScreenshotController; class PowerButtonScreenshotController;
...@@ -48,7 +49,8 @@ class ASH_EXPORT PowerButtonController ...@@ -48,7 +49,8 @@ class ASH_EXPORT PowerButtonController
LEGACY, LEGACY,
}; };
PowerButtonController(); explicit PowerButtonController(
BacklightsForcedOffSetter* backlights_forced_off_setter);
~PowerButtonController() override; ~PowerButtonController() override;
// Handles clamshell power button behavior. // Handles clamshell power button behavior.
...@@ -103,6 +105,9 @@ class ASH_EXPORT PowerButtonController ...@@ -103,6 +105,9 @@ class ASH_EXPORT PowerButtonController
// screen is locked. Only used when |force_clamshell_power_button_| is true. // screen is locked. Only used when |force_clamshell_power_button_| is true.
void ForceDisplayOffAfterLock(); void ForceDisplayOffAfterLock();
// Used to force backlights off, when needed.
BacklightsForcedOffSetter* backlights_forced_off_setter_; // Not owned.
// Are the power or lock buttons currently held? // Are the power or lock buttons currently held?
bool power_button_down_ = false; bool power_button_down_ = false;
bool lock_button_down_ = false; bool lock_button_down_ = false;
......
...@@ -6,12 +6,9 @@ ...@@ -6,12 +6,9 @@
#include "ash/accessibility/accessibility_controller.h" #include "ash/accessibility/accessibility_controller.h"
#include "ash/media_controller.h" #include "ash/media_controller.h"
#include "ash/public/cpp/ash_switches.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/touch/touch_devices_controller.h" #include "ash/system/power/scoped_backlights_forced_off.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/time/tick_clock.h" #include "base/time/tick_clock.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "ui/events/devices/input_device_manager.h" #include "ui/events/devices/input_device_manager.h"
...@@ -33,18 +30,18 @@ bool IsTabletModeActive() { ...@@ -33,18 +30,18 @@ bool IsTabletModeActive() {
} // namespace } // namespace
PowerButtonDisplayController::PowerButtonDisplayController( PowerButtonDisplayController::PowerButtonDisplayController(
BacklightsForcedOffSetter* backlights_forced_off_setter,
base::TickClock* tick_clock) base::TickClock* tick_clock)
: tick_clock_(tick_clock), weak_ptr_factory_(this) { : backlights_forced_off_setter_(backlights_forced_off_setter),
backlights_forced_off_observer_(this),
tick_clock_(tick_clock),
weak_ptr_factory_(this) {
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
this); this);
ui::InputDeviceManager::GetInstance()->AddObserver(this); ui::InputDeviceManager::GetInstance()->AddObserver(this);
Shell::Get()->PrependPreTargetHandler(this); Shell::Get()->PrependPreTargetHandler(this);
disable_touchscreen_while_screen_off_ = backlights_forced_off_observer_.Add(backlights_forced_off_setter_);
!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kTouchscreenUsableWhileScreenOff);
GetInitialBacklightsForcedOff();
} }
PowerButtonDisplayController::~PowerButtonDisplayController() { PowerButtonDisplayController::~PowerButtonDisplayController() {
...@@ -54,68 +51,60 @@ PowerButtonDisplayController::~PowerButtonDisplayController() { ...@@ -54,68 +51,60 @@ PowerButtonDisplayController::~PowerButtonDisplayController() {
this); this);
} }
void PowerButtonDisplayController::SetDisplayForcedOff(bool forced_off) { bool PowerButtonDisplayController::IsScreenOn() const {
if (backlights_forced_off_ == forced_off) return backlights_forced_off_setter_->screen_state() ==
BacklightsForcedOffSetter::ScreenState::ON;
}
void PowerButtonDisplayController::SetBacklightsForcedOff(bool forced_off) {
if ((backlights_forced_off_ != nullptr) == forced_off)
return; return;
// Set the display and keyboard backlights (if present) to |forced_off|. send_accessibility_alert_on_backlights_forced_off_change_ = true;
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->SetBacklightsForcedOff(forced_off);
backlights_forced_off_ = forced_off;
UpdateTouchscreenStatus();
if (backlights_forced_off_) if (forced_off) {
Shell::Get()->media_controller()->SuspendMediaSessions(); backlights_forced_off_ =
backlights_forced_off_setter_->ForceBacklightsOff();
} else {
backlights_forced_off_.reset();
}
// Send an a11y alert. if (forced_off)
Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert( Shell::Get()->media_controller()->SuspendMediaSessions();
forced_off ? mojom::AccessibilityAlert::SCREEN_OFF
: mojom::AccessibilityAlert::SCREEN_ON);
} }
void PowerButtonDisplayController::PowerManagerRestarted() { void PowerButtonDisplayController::OnBacklightsForcedOffChanged(
chromeos::DBusThreadManager::Get() bool forced_off) {
->GetPowerManagerClient() if (send_accessibility_alert_on_backlights_forced_off_change_) {
->SetBacklightsForcedOff(backlights_forced_off_); Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert(
forced_off ? mojom::AccessibilityAlert::SCREEN_OFF
: mojom::AccessibilityAlert::SCREEN_ON);
}
send_accessibility_alert_on_backlights_forced_off_change_ = false;
} }
void PowerButtonDisplayController::BrightnessChanged(int level, void PowerButtonDisplayController::OnScreenStateChanged(
bool user_initiated) { BacklightsForcedOffSetter::ScreenState screen_state) {
const ScreenState old_state = screen_state_; screen_state_last_changed_ = tick_clock_->NowTicks();
if (level != 0)
screen_state_ = ScreenState::ON;
else
screen_state_ = user_initiated ? ScreenState::OFF : ScreenState::OFF_AUTO;
if (screen_state_ != old_state)
screen_state_last_changed_ = tick_clock_->NowTicks();
// Disable the touchscreen when the screen is turned off due to inactivity:
// https://crbug.com/743291
if ((screen_state_ == ScreenState::OFF_AUTO) !=
(old_state == ScreenState::OFF_AUTO) &&
disable_touchscreen_while_screen_off_)
UpdateTouchscreenStatus();
} }
void PowerButtonDisplayController::SuspendDone( void PowerButtonDisplayController::SuspendDone(
const base::TimeDelta& sleep_duration) { const base::TimeDelta& sleep_duration) {
// Stop forcing backlights off on resume to handle situations where the power // Stop forcing backlights off on resume to handle situations where the power
// button resumed but we didn't receive the event (crbug.com/735291). // button resumed but we didn't receive the event (crbug.com/735291).
SetDisplayForcedOff(false); SetBacklightsForcedOff(false);
} }
void PowerButtonDisplayController::LidEventReceived( void PowerButtonDisplayController::LidEventReceived(
chromeos::PowerManagerClient::LidState state, chromeos::PowerManagerClient::LidState state,
const base::TimeTicks& timestamp) { const base::TimeTicks& timestamp) {
SetDisplayForcedOff(false); SetBacklightsForcedOff(false);
} }
void PowerButtonDisplayController::TabletModeEventReceived( void PowerButtonDisplayController::TabletModeEventReceived(
chromeos::PowerManagerClient::TabletMode mode, chromeos::PowerManagerClient::TabletMode mode,
const base::TimeTicks& timestamp) { const base::TimeTicks& timestamp) {
SetDisplayForcedOff(false); SetBacklightsForcedOff(false);
} }
void PowerButtonDisplayController::OnKeyEvent(ui::KeyEvent* event) { void PowerButtonDisplayController::OnKeyEvent(ui::KeyEvent* event) {
...@@ -125,7 +114,7 @@ void PowerButtonDisplayController::OnKeyEvent(ui::KeyEvent* event) { ...@@ -125,7 +114,7 @@ void PowerButtonDisplayController::OnKeyEvent(ui::KeyEvent* event) {
return; return;
if (!IsTabletModeActive()) if (!IsTabletModeActive())
SetDisplayForcedOff(false); SetBacklightsForcedOff(false);
} }
void PowerButtonDisplayController::OnMouseEvent(ui::MouseEvent* event) { void PowerButtonDisplayController::OnMouseEvent(ui::MouseEvent* event) {
...@@ -133,34 +122,12 @@ void PowerButtonDisplayController::OnMouseEvent(ui::MouseEvent* event) { ...@@ -133,34 +122,12 @@ void PowerButtonDisplayController::OnMouseEvent(ui::MouseEvent* event) {
return; return;
if (!IsTabletModeActive()) if (!IsTabletModeActive())
SetDisplayForcedOff(false); SetBacklightsForcedOff(false);
} }
void PowerButtonDisplayController::OnStylusStateChanged(ui::StylusState state) { void PowerButtonDisplayController::OnStylusStateChanged(ui::StylusState state) {
if (state == ui::StylusState::REMOVED) if (state == ui::StylusState::REMOVED)
SetDisplayForcedOff(false); SetBacklightsForcedOff(false);
}
void PowerButtonDisplayController::GetInitialBacklightsForcedOff() {
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->GetBacklightsForcedOff(base::BindOnce(
&PowerButtonDisplayController::OnGotInitialBacklightsForcedOff,
weak_ptr_factory_.GetWeakPtr()));
}
void PowerButtonDisplayController::OnGotInitialBacklightsForcedOff(
base::Optional<bool> is_forced_off) {
backlights_forced_off_ = is_forced_off.value_or(false);
UpdateTouchscreenStatus();
}
void PowerButtonDisplayController::UpdateTouchscreenStatus() {
const bool disable_touchscreen =
backlights_forced_off_ || (screen_state_ == ScreenState::OFF_AUTO &&
disable_touchscreen_while_screen_off_);
Shell::Get()->touch_devices_controller()->SetTouchscreenEnabled(
!disable_touchscreen, TouchscreenEnabledSource::GLOBAL);
} }
} // namespace ash } // namespace ash
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
#ifndef ASH_SYSTEM_POWER_POWER_BUTTON_DISPLAY_CONTROLLER_H_ #ifndef ASH_SYSTEM_POWER_POWER_BUTTON_DISPLAY_CONTROLLER_H_
#define ASH_SYSTEM_POWER_POWER_BUTTON_DISPLAY_CONTROLLER_H_ #define ASH_SYSTEM_POWER_POWER_BUTTON_DISPLAY_CONTROLLER_H_
#include <memory>
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/system/power/backlights_forced_off_setter.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/scoped_observer.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chromeos/dbus/power_manager_client.h" #include "chromeos/dbus/power_manager_client.h"
#include "ui/events/devices/input_device_event_observer.h" #include "ui/events/devices/input_device_event_observer.h"
...@@ -20,30 +23,24 @@ class TickClock; ...@@ -20,30 +23,24 @@ class TickClock;
namespace ash { namespace ash {
class ScopedBacklightsForcedOff;
// PowerButtonDisplayController performs display-related tasks (e.g. forcing // PowerButtonDisplayController performs display-related tasks (e.g. forcing
// backlights off or disabling the touchscreen) on behalf of // backlights off or disabling the touchscreen) on behalf of
// PowerButtonController and TabletPowerButtonController. // PowerButtonController and TabletPowerButtonController.
class ASH_EXPORT PowerButtonDisplayController class ASH_EXPORT PowerButtonDisplayController
: public chromeos::PowerManagerClient::Observer, : public BacklightsForcedOffSetter::Observer,
public chromeos::PowerManagerClient::Observer,
public ui::EventHandler, public ui::EventHandler,
public ui::InputDeviceEventObserver { public ui::InputDeviceEventObserver {
public: public:
// Screen state as communicated by D-Bus signals from powerd about backlight PowerButtonDisplayController(
// brightness changes. BacklightsForcedOffSetter* backlights_forced_off_setter,
enum class ScreenState { base::TickClock* tick_clock);
// The screen is on.
ON,
// The screen is off.
OFF,
// The screen is off, specifically due to an automated change like user
// inactivity.
OFF_AUTO,
};
explicit PowerButtonDisplayController(base::TickClock* tick_clock);
~PowerButtonDisplayController() override; ~PowerButtonDisplayController() override;
ScreenState screen_state() const { return screen_state_; } bool IsScreenOn() const;
base::TimeTicks screen_state_last_changed() const { base::TimeTicks screen_state_last_changed() const {
return screen_state_last_changed_; return screen_state_last_changed_;
} }
...@@ -51,11 +48,14 @@ class ASH_EXPORT PowerButtonDisplayController ...@@ -51,11 +48,14 @@ class ASH_EXPORT PowerButtonDisplayController
// Updates the power manager's backlights-forced-off state and enables or // Updates the power manager's backlights-forced-off state and enables or
// disables the touchscreen. No-op if |backlights_forced_off_| already equals // disables the touchscreen. No-op if |backlights_forced_off_| already equals
// |forced_off|. // |forced_off|.
void SetDisplayForcedOff(bool forced_off); void SetBacklightsForcedOff(bool forced_off);
// Overridden from BacklightsForcedOffObserver:
void OnBacklightsForcedOffChanged(bool forced_off) override;
void OnScreenStateChanged(
BacklightsForcedOffSetter::ScreenState screen_state) override;
// Overridden from chromeos::PowerManagerClient::Observer: // Overridden from chromeos::PowerManagerClient::Observer:
void PowerManagerRestarted() override;
void BrightnessChanged(int level, bool user_initiated) override;
void SuspendDone(const base::TimeDelta& sleep_duration) override; void SuspendDone(const base::TimeDelta& sleep_duration) override;
void LidEventReceived(chromeos::PowerManagerClient::LidState state, void LidEventReceived(chromeos::PowerManagerClient::LidState state,
const base::TimeTicks& timestamp) override; const base::TimeTicks& timestamp) override;
...@@ -70,34 +70,25 @@ class ASH_EXPORT PowerButtonDisplayController ...@@ -70,34 +70,25 @@ class ASH_EXPORT PowerButtonDisplayController
void OnStylusStateChanged(ui::StylusState state) override; void OnStylusStateChanged(ui::StylusState state) override;
private: private:
// Sends a request to powerd to get the backlights forced off state so that
// |backlights_forced_off_| can be initialized.
void GetInitialBacklightsForcedOff();
// Initializes |backlights_forced_off_|.
void OnGotInitialBacklightsForcedOff(base::Optional<bool> is_forced_off);
// Enables or disables the touchscreen by updating the global touchscreen
// enabled status. The touchscreen is disabled when backlights are forced off
// or |screen_state_| is OFF_AUTO.
void UpdateTouchscreenStatus();
// Current screen state.
ScreenState screen_state_ = ScreenState::ON;
// Current forced-off state of backlights.
bool backlights_forced_off_ = false;
// Saves the most recent timestamp that screen state changed. // Saves the most recent timestamp that screen state changed.
base::TimeTicks screen_state_last_changed_; base::TimeTicks screen_state_last_changed_;
// Controls whether the touchscreen is disabled when the screen is turned off BacklightsForcedOffSetter* backlights_forced_off_setter_; // Not owned.
// due to user inactivity.
bool disable_touchscreen_while_screen_off_ = true; ScopedObserver<BacklightsForcedOffSetter, BacklightsForcedOffSetter::Observer>
backlights_forced_off_observer_;
// Whether an accessibility alert should be sent when the backlights
// forced-off state changes.
bool send_accessibility_alert_on_backlights_forced_off_change_ = false;
// Time source for performed action times. // Time source for performed action times.
base::TickClock* tick_clock_; // Not owned. base::TickClock* tick_clock_; // Not owned.
// If set, the active request passed to |backlights_forced_off_setter_| in
// order to force the backlights off.
std::unique_ptr<ScopedBacklightsForcedOff> backlights_forced_off_;
base::WeakPtrFactory<PowerButtonDisplayController> weak_ptr_factory_; base::WeakPtrFactory<PowerButtonDisplayController> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PowerButtonDisplayController); DISALLOW_COPY_AND_ASSIGN(PowerButtonDisplayController);
......
// Copyright 2017 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/system/power/scoped_backlights_forced_off.h"
#include <utility>
namespace ash {
ScopedBacklightsForcedOff::ScopedBacklightsForcedOff(
base::OnceClosure unregister_callback)
: unregister_callback_(std::move(unregister_callback)) {}
ScopedBacklightsForcedOff::~ScopedBacklightsForcedOff() {
if (unregister_callback_)
std::move(unregister_callback_).Run();
}
} // namespace ash
// Copyright 2017 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.
#ifndef ASH_SYSTEM_POWER_SCOPED_BACKLIGHTS_FORCED_OFF_H_
#define ASH_SYSTEM_POWER_SCOPED_BACKLIGHTS_FORCED_OFF_H_
#include "ash/ash_export.h"
#include "base/callback.h"
#include "base/macros.h"
namespace ash {
// RAII-style class used to force the backlights off.
// Returned by BacklightsForcedOffSetter::ForceBacklightsOff.
class ASH_EXPORT ScopedBacklightsForcedOff {
public:
explicit ScopedBacklightsForcedOff(base::OnceClosure unregister_callback);
~ScopedBacklightsForcedOff();
private:
// Callback that should be called in order for |this| to unregister backlights
// forced off request.
base::OnceClosure unregister_callback_;
DISALLOW_COPY_AND_ASSIGN(ScopedBacklightsForcedOff);
};
} // namespace ash
#endif // ASH_SYSTEM_POWER_SCOPED_BACKLIGHTS_FORCED_OFF_H_
...@@ -91,10 +91,8 @@ void TabletPowerButtonController::OnPowerButtonEvent( ...@@ -91,10 +91,8 @@ void TabletPowerButtonController::OnPowerButtonEvent(
force_off_on_button_up_ = false; force_off_on_button_up_ = false;
} }
screen_off_when_power_button_down_ = screen_off_when_power_button_down_ = !display_controller_->IsScreenOn();
display_controller_->screen_state() != display_controller_->SetBacklightsForcedOff(false);
PowerButtonDisplayController::ScreenState::ON;
display_controller_->SetDisplayForcedOff(false);
StartShutdownTimer(); StartShutdownTimer();
} else { } else {
const base::TimeTicks previous_up_time = last_button_up_time_; const base::TimeTicks previous_up_time = last_button_up_time_;
...@@ -114,7 +112,7 @@ void TabletPowerButtonController::OnPowerButtonEvent( ...@@ -114,7 +112,7 @@ void TabletPowerButtonController::OnPowerButtonEvent(
if (shutdown_timer_.IsRunning()) { if (shutdown_timer_.IsRunning()) {
shutdown_timer_.Stop(); shutdown_timer_.Stop();
if (!screen_off_when_power_button_down_ && force_off_on_button_up_) { if (!screen_off_when_power_button_down_ && force_off_on_button_up_) {
display_controller_->SetDisplayForcedOff(true); display_controller_->SetBacklightsForcedOff(true);
LockScreenIfRequired(); LockScreenIfRequired();
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment