Commit 85ae39e9 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Control stylus related lock screen note state from ash

Move logic to
 *  launch lock screen note when stylus is removed
 *  close lock screen note when screen is forced off
    (e.g. due to power button press)
from lock_screen_apps/state_controller to ash, into a newly added
LockScreenNoteDisplayHandler.

The main goal of this is to better handle lock screen app launch when
stylus is ejected with display forced off. This action should perform
two actions:
 1. turn the display on
 2. launch the lock screen note (if lock screen note action is enabled)
Doing this at the same time can cause a flash of lock screen UI before
the lock screen note app window is shown. With logic for launching
the note moved to ash, it's possible to delay changing display state
until the lock screen app window becomes visible, which should be long
enough to prevent lock screen UI flash.

BUG=767711

Change-Id: I7754050cb1275a6526a66843435b9f2d5837371f
Reviewed-on: https://chromium-review.googlesource.com/807671
Commit-Queue: Toni Barzic <tbarzic@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#522354}
parent 3e7b87db
......@@ -245,6 +245,8 @@ component("ash") {
"lock_screen_action/lock_screen_action_background_state.h",
"lock_screen_action/lock_screen_action_background_view.cc",
"lock_screen_action/lock_screen_action_background_view.h",
"lock_screen_action/lock_screen_note_display_state_handler.cc",
"lock_screen_action/lock_screen_note_display_state_handler.h",
"lock_screen_action/lock_screen_note_launcher.cc",
"lock_screen_action/lock_screen_note_launcher.h",
"login/lock_screen_apps_focus_observer.h",
......@@ -1367,6 +1369,7 @@ test("ash_unittests") {
"laser/laser_pointer_controller_unittest.cc",
"laser/laser_segment_utils_unittest.cc",
"lock_screen_action/lock_screen_action_background_controller_impl_unittest.cc",
"lock_screen_action/lock_screen_note_display_state_handler_unittest.cc",
"lock_screen_action/lock_screen_note_launcher_unittest.cc",
"login/login_screen_controller_unittest.cc",
"login/mock_login_screen_client.cc",
......
// 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/lock_screen_action/lock_screen_note_display_state_handler.h"
#include <utility>
#include "ash/lock_screen_action/lock_screen_note_launcher.h"
#include "ash/public/interfaces/tray_action.mojom.h"
#include "ash/shell.h"
#include "ash/system/power/scoped_backlights_forced_off.h"
#include "ash/tray_action/tray_action.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/time/time.h"
namespace ash {
namespace {
// The max amount of time display state change handling can be delayed due to a
// lock screen note action launch. The time starts running when the app launch
// is requested.
constexpr base::TimeDelta kNoteLaunchTimeout =
base::TimeDelta::FromMilliseconds(1500);
} // namespace
LockScreenNoteDisplayStateHandler::LockScreenNoteDisplayStateHandler(
BacklightsForcedOffSetter* backlights_forced_off_setter)
: backlights_forced_off_setter_(backlights_forced_off_setter),
backlights_forced_off_observer_(this),
weak_ptr_factory_(this) {
backlights_forced_off_observer_.Add(backlights_forced_off_setter_);
}
LockScreenNoteDisplayStateHandler::~LockScreenNoteDisplayStateHandler() =
default;
void LockScreenNoteDisplayStateHandler::OnBacklightsForcedOffChanged(
bool backlights_forced_off) {
// Close lock screen note when backlights are forced off - unless the
// backlights are forced off by this as part of note app launch.
if (backlights_forced_off && !backlights_forced_off_) {
Shell::Get()->tray_action()->CloseLockScreenNote(
mojom::CloseLockScreenNoteReason::kScreenDimmed);
}
}
void LockScreenNoteDisplayStateHandler::OnScreenStateChanged(
BacklightsForcedOffSetter::ScreenState screen_state) {
if (screen_state != BacklightsForcedOffSetter::ScreenState::ON &&
note_launch_delayed_until_screen_off_) {
RunLockScreenNoteLauncher();
}
}
void LockScreenNoteDisplayStateHandler::AttemptNoteLaunchForStylusEject() {
if (!LockScreenNoteLauncher::CanAttemptLaunch() ||
NoteLaunchInProgressOrDelayed()) {
return;
}
if (!backlights_forced_off_ && ShouldForceBacklightsOffForNoteLaunch()) {
backlights_forced_off_ =
backlights_forced_off_setter_->ForceBacklightsOff();
}
DCHECK(!launch_timer_.IsRunning());
launch_timer_.Start(
FROM_HERE, kNoteLaunchTimeout,
base::Bind(&LockScreenNoteDisplayStateHandler::NoteLaunchDone,
weak_ptr_factory_.GetWeakPtr(), false));
// Delay note launch if backlights are forced off, but the screen hasn't
// been turned off yet - the note should be launched when the pending
// backlights state is finished (i.e. the screen is turned off).
if (backlights_forced_off_setter_->backlights_forced_off() &&
backlights_forced_off_setter_->screen_state() ==
BacklightsForcedOffSetter::ScreenState::ON) {
note_launch_delayed_until_screen_off_ = true;
return;
}
RunLockScreenNoteLauncher();
}
void LockScreenNoteDisplayStateHandler::Reset() {
note_launch_delayed_until_screen_off_ = false;
backlights_forced_off_.reset();
lock_screen_note_launcher_.reset();
launch_timer_.Stop();
}
void LockScreenNoteDisplayStateHandler::RunLockScreenNoteLauncher() {
DCHECK(!lock_screen_note_launcher_);
if (!LockScreenNoteLauncher::CanAttemptLaunch()) {
Reset();
return;
}
note_launch_delayed_until_screen_off_ = false;
lock_screen_note_launcher_ = std::make_unique<LockScreenNoteLauncher>();
lock_screen_note_launcher_->Run(
mojom::LockScreenNoteOrigin::kStylusEject,
base::BindOnce(&LockScreenNoteDisplayStateHandler::NoteLaunchDone,
weak_ptr_factory_.GetWeakPtr()));
}
bool LockScreenNoteDisplayStateHandler::ShouldForceBacklightsOffForNoteLaunch()
const {
// Backlights should be kept off during app launch if the display has been
// turned off without user interaction (e.g. due to user inactivity), or if
// the backlights are currently being forced off - the goal is to avoid flash
// of lock screen UI if the display gets turned on before lock screen app
// window is shown.
// There is no need to force the backlight off if the display has been turned
// off due to user action - in this case display brightness will not change
// when backlights stop being forced off (due to stylus eject) - the
// brightness will remain at user selected level, so the lock screen UI will
// not actually become visible.
//
// Note that backlights_forced_off_setter_ check is required as there is a
// delay between request to force backlights off and screen state getting
// updated due to that request.
return backlights_forced_off_setter_->backlights_forced_off() ||
backlights_forced_off_setter_->screen_state() ==
BacklightsForcedOffSetter::ScreenState::OFF_AUTO;
}
bool LockScreenNoteDisplayStateHandler::NoteLaunchInProgressOrDelayed() const {
return note_launch_delayed_until_screen_off_ || lock_screen_note_launcher_;
}
void LockScreenNoteDisplayStateHandler::NoteLaunchDone(bool success) {
Reset();
}
} // 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_LOCK_SCREEN_ACTION_LOCK_SCREEN_NOTE_DISPLAY_STATE_HANDLER_H_
#define ASH_LOCK_SCREEN_ACTION_LOCK_SCREEN_NOTE_DISPLAY_STATE_HANDLER_H_
#include <memory>
#include "ash/system/power/backlights_forced_off_setter.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "base/timer/timer.h"
namespace ash {
class LockScreenNoteLauncher;
class ScopedBacklightsForcedOff;
// Handles display state changes related to lock screen note state.
// For example it will close any active lock screen notes if the display is
// forced off.
// This class also handles a lock screen note launch when stylus is ejected.
// When the note is launched while the screen is off, note launch forces the
// display off, in order to delay screen being turned on (which happens, among
// other things, when the stylus gets ejected) until the lock screen note is
// visible. This is to prevent a flash of the lock screen UI as the lock screen
// note app window is being shown.
class LockScreenNoteDisplayStateHandler
: public BacklightsForcedOffSetter::Observer {
public:
explicit LockScreenNoteDisplayStateHandler(
BacklightsForcedOffSetter* backlights_forced_off_setter);
~LockScreenNoteDisplayStateHandler() override;
base::OneShotTimer* launch_timer_for_test() { return &launch_timer_; }
// BacklightsForcedOffSetter::Observer:
void OnBacklightsForcedOffChanged(bool backlights_forced_off) override;
void OnScreenStateChanged(
BacklightsForcedOffSetter::ScreenState screen_state) override;
// If lock screen note action is available, it requests a new lock screen note
// with launch reason set to stylus eject.
void AttemptNoteLaunchForStylusEject();
// Resets the internal state, cancelling any in progress launch.
void Reset();
private:
// Runs lock screen note launcher, which starts lock screen app launch.
void RunLockScreenNoteLauncher();
// Whether the backlights should be forced off during lock screen note
// launch.
bool ShouldForceBacklightsOffForNoteLaunch() const;
// Whether a lock screen note is currently being launched by |this|.
bool NoteLaunchInProgressOrDelayed() const;
// Called by |lock_screen_note_launcher_| when lock screen note launch is
// done.
void NoteLaunchDone(bool success);
// Object used to force the backlights off.
BacklightsForcedOffSetter* const backlights_forced_off_setter_;
// Whether lock screen note launch is delayed until the screen is reported to
// be off - this is used if lock screen note launch is requested when
// backlights have been forced off, but the power manager still reports screen
// to be on.
bool note_launch_delayed_until_screen_off_ = false;
std::unique_ptr<LockScreenNoteLauncher> lock_screen_note_launcher_;
// Scoped backlights forced off request - this is returned by
// |backlights_forced_off_setter_->ForceBacklightsOff()|, and will keep the
// backlights in forced-off state until they are reset.
std::unique_ptr<ScopedBacklightsForcedOff> backlights_forced_off_;
// Timer used to set up timeout for lock screen note launch.
base::OneShotTimer launch_timer_;
ScopedObserver<BacklightsForcedOffSetter, BacklightsForcedOffSetter::Observer>
backlights_forced_off_observer_;
base::WeakPtrFactory<LockScreenNoteDisplayStateHandler> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(LockScreenNoteDisplayStateHandler);
};
} // namespace ash
#endif // ASH_LOCK_SCREEN_ACTION_LOCK_SCREEN_NOTE_DISPLAY_STATE_HANDLER_H_
......@@ -599,7 +599,6 @@ Shell::Shell(std::unique_ptr<ShellDelegate> shell_delegate,
shutdown_controller_(std::make_unique<ShutdownController>()),
system_tray_controller_(std::make_unique<SystemTrayController>()),
system_tray_notifier_(std::make_unique<SystemTrayNotifier>()),
tray_action_(std::make_unique<TrayAction>()),
vpn_list_(std::make_unique<VpnList>()),
window_cycle_controller_(std::make_unique<WindowCycleController>()),
window_selector_controller_(std::make_unique<WindowSelectorController>()),
......@@ -724,6 +723,8 @@ Shell::~Shell() {
toplevel_window_event_handler_.reset();
visibility_controller_.reset();
tray_action_.reset();
power_button_controller_.reset();
lock_state_controller_.reset();
backlights_forced_off_setter_.reset();
......@@ -1013,6 +1014,9 @@ void Shell::Init(ui::ContextFactory* context_factory,
backlights_forced_off_setter_ = std::make_unique<BacklightsForcedOffSetter>();
tray_action_ =
std::make_unique<TrayAction>(backlights_forced_off_setter_.get());
lock_state_controller_ =
std::make_unique<LockStateController>(shutdown_controller_.get());
power_button_controller_ = std::make_unique<PowerButtonController>(
......
......@@ -6,14 +6,22 @@
#include <utility>
#include "ash/lock_screen_action/lock_screen_note_display_state_handler.h"
#include "ash/tray_action/tray_action_observer.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "ui/events/devices/input_device_manager.h"
#include "ui/events/devices/stylus_state.h"
namespace ash {
TrayAction::TrayAction() : binding_(this) {}
TrayAction::TrayAction(BacklightsForcedOffSetter* backlights_forced_off_setter)
: backlights_forced_off_setter_(backlights_forced_off_setter),
binding_(this),
stylus_observer_(this) {
stylus_observer_.Add(ui::InputDeviceManager::GetInstance());
}
TrayAction::~TrayAction() = default;
......@@ -51,6 +59,12 @@ void TrayAction::SetClient(mojom::TrayActionClientPtr tray_action_client,
base::Bind(&TrayAction::SetClient, base::Unretained(this), nullptr,
mojom::TrayActionState::kNotAvailable));
lock_screen_note_state_ = lock_screen_note_state;
lock_screen_note_display_state_handler_ =
std::make_unique<LockScreenNoteDisplayStateHandler>(
backlights_forced_off_setter_);
} else {
lock_screen_note_display_state_handler_.reset();
}
// Setting action handler value can change effective state - notify observers
......@@ -65,6 +79,9 @@ void TrayAction::UpdateLockScreenNoteState(mojom::TrayActionState state) {
lock_screen_note_state_ = state;
if (lock_screen_note_state_ == mojom::TrayActionState::kNotAvailable)
lock_screen_note_display_state_handler_->Reset();
// If the client is not set, the effective state has not changed, so no need
// to notify observers of a state change.
if (tray_action_client_)
......@@ -85,6 +102,11 @@ void TrayAction::CloseLockScreenNote(mojom::CloseLockScreenNoteReason reason) {
tray_action_client_->CloseLockScreenNote(reason);
}
void TrayAction::OnStylusStateChanged(ui::StylusState state) {
if (state == ui::StylusState::REMOVED)
lock_screen_note_display_state_handler_->AttemptNoteLaunchForStylusEject();
}
void TrayAction::FlushMojoForTesting() {
if (tray_action_client_)
tray_action_client_.FlushForTesting();
......
......@@ -5,14 +5,25 @@
#ifndef ASH_TRAY_ACTION_TRAY_ACTION_H_
#define ASH_TRAY_ACTION_TRAY_ACTION_H_
#include <memory>
#include "ash/ash_export.h"
#include "ash/public/interfaces/tray_action.mojom.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/scoped_observer.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "ui/events/devices/input_device_event_observer.h"
namespace ui {
class InputDeviceManager;
enum class StylusState;
} // namespace ui
namespace ash {
class BacklightsForcedOffSetter;
class LockScreenNoteDisplayStateHandler;
class TrayActionObserver;
// Controller that ash can use to request a predefined set of actions to be
......@@ -24,11 +35,17 @@ class TrayActionObserver;
// Currently, only single action is supported - creating new note on the lock
// screen - Chrome handles this action by launching an app (if any) that is
// registered as a lock screen enabled action handler for the new note action.
class ASH_EXPORT TrayAction : public mojom::TrayAction {
class ASH_EXPORT TrayAction : public mojom::TrayAction,
public ui::InputDeviceEventObserver {
public:
TrayAction();
explicit TrayAction(BacklightsForcedOffSetter* backlights_forced_off_setter);
~TrayAction() override;
LockScreenNoteDisplayStateHandler*
lock_screen_note_display_state_handler_for_test() {
return lock_screen_note_display_state_handler_.get();
}
void AddObserver(TrayActionObserver* observer);
void RemoveObserver(TrayActionObserver* observer);
......@@ -54,6 +71,9 @@ class ASH_EXPORT TrayAction : public mojom::TrayAction {
mojom::TrayActionState lock_screen_note_state) override;
void UpdateLockScreenNoteState(mojom::TrayActionState state) override;
// ui::InputDeviceEventObserver:
void OnStylusStateChanged(ui::StylusState state) override;
void FlushMojoForTesting();
private:
......@@ -61,16 +81,24 @@ class ASH_EXPORT TrayAction : public mojom::TrayAction {
// updated.
void NotifyLockScreenNoteStateChanged();
BacklightsForcedOffSetter* const backlights_forced_off_setter_;
// Last known state for lock screen note action.
mojom::TrayActionState lock_screen_note_state_ =
mojom::TrayActionState::kNotAvailable;
std::unique_ptr<LockScreenNoteDisplayStateHandler>
lock_screen_note_display_state_handler_;
base::ObserverList<TrayActionObserver> observers_;
mojo::Binding<mojom::TrayAction> binding_;
mojom::TrayActionClientPtr tray_action_client_;
ScopedObserver<ui::InputDeviceManager, ui::InputDeviceEventObserver>
stylus_observer_;
DISALLOW_COPY_AND_ASSIGN(TrayAction);
};
......
......@@ -43,7 +43,6 @@
#include "extensions/common/extension.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/events/devices/input_device_manager.h"
#include "ui/events/devices/stylus_state.h"
using ash::mojom::CloseLockScreenNoteReason;
using ash::mojom::LockScreenNoteOrigin;
......@@ -53,10 +52,6 @@ namespace lock_screen_apps {
namespace {
// The time span a stylus eject is considered valid - i.e. the time period
// within a stylus eject event can cause a lock screen note launch.
constexpr int kStylusEjectValidityMs = 1000;
// Key for user pref that contains the 256 bit AES key that should be used to
// encrypt persisted user data created on the lock screen.
constexpr char kDataCryptoKeyPref[] = "lockScreenAppDataCryptoKey";
......@@ -267,11 +262,6 @@ void StateController::InitializeWithCryptoKey(Profile* profile,
void StateController::InitializeWithStylusInputPresent() {
stylus_input_missing_ = false;
chromeos::DBusThreadManager::Get()
->GetPowerManagerClient()
->GetScreenBrightnessPercent(
base::Bind(&StateController::SetInitialScreenState,
weak_ptr_factory_.GetWeakPtr()));
power_manager_client_observer_.Add(
chromeos::DBusThreadManager::Get()->GetPowerManagerClient());
session_observer_.Add(session_manager::SessionManager::Get());
......@@ -406,36 +396,11 @@ void StateController::OnAppWindowRemoved(extensions::AppWindow* app_window) {
false /*close_window*/, CloseLockScreenNoteReason::kAppWindowClosed);
}
void StateController::OnStylusStateChanged(ui::StylusState state) {
if (lock_screen_note_state_ != TrayActionState::kAvailable)
return;
if (state != ui::StylusState::REMOVED) {
stylus_eject_timestamp_ = base::TimeTicks();
return;
}
if (screen_state_ == ScreenState::kOn) {
RequestNewLockScreenNote(LockScreenNoteOrigin::kStylusEject);
} else {
stylus_eject_timestamp_ = tick_clock_->NowTicks();
}
}
void StateController::OnTouchscreenDeviceConfigurationChanged() {
if (stylus_input_missing_ && ash::stylus_utils::HasStylusInput())
InitializeWithStylusInputPresent();
}
void StateController::BrightnessChanged(int level, bool user_initiated) {
if (level == 0 && !user_initiated) {
ResetNoteTakingWindowAndMoveToNextState(
true /*close_window*/, CloseLockScreenNoteReason::kScreenDimmed);
}
SetScreenState(level == 0 ? ScreenState::kOff : ScreenState::kOn);
}
void StateController::SuspendImminent(
power_manager::SuspendImminent::Reason reason) {
ResetNoteTakingWindowAndMoveToNextState(true /*close_window*/,
......@@ -527,35 +492,11 @@ void StateController::FocusAppWindow(bool reverse) {
note_app_window_->web_contents()->Focus();
}
void StateController::SetInitialScreenState(
base::Optional<double> screen_brightness) {
if (screen_state_ != ScreenState::kUnknown || !screen_brightness.has_value())
return;
SetScreenState(screen_brightness.value() == 0 ? ScreenState::kOff
: ScreenState::kOn);
}
void StateController::SetScreenState(ScreenState screen_state) {
if (screen_state_ == screen_state)
return;
screen_state_ = screen_state;
if (screen_state_ == ScreenState::kOn && !stylus_eject_timestamp_.is_null() &&
tick_clock_->NowTicks() - stylus_eject_timestamp_ <
base::TimeDelta::FromMilliseconds(kStylusEjectValidityMs)) {
stylus_eject_timestamp_ = base::TimeTicks();
RequestNewLockScreenNote(LockScreenNoteOrigin::kStylusEject);
}
}
void StateController::ResetNoteTakingWindowAndMoveToNextState(
bool close_window,
CloseLockScreenNoteReason reason) {
note_window_observer_.RemoveAll();
app_window_observer_.RemoveAll();
stylus_eject_timestamp_ = base::TimeTicks();
app_launch_delayed_for_animation_ = false;
if (first_app_run_toast_manager_)
first_app_run_toast_manager_->Reset();
......@@ -587,7 +528,8 @@ void StateController::ResetNoteTakingWindowAndMoveToNextState(
note_app_window_ = nullptr;
}
UpdateLockScreenNoteState(app_manager_->IsNoteTakingAppAvailable()
UpdateLockScreenNoteState(app_manager_ &&
app_manager_->IsNoteTakingAppAvailable()
? TrayActionState::kAvailable
: TrayActionState::kNotAvailable);
}
......
......@@ -14,7 +14,6 @@
#include "base/observer_list.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/lock_screen_apps/app_manager.h"
#include "chrome/browser/chromeos/lock_screen_apps/state_observer.h"
#include "chromeos/dbus/power_manager_client.h"
......@@ -153,11 +152,9 @@ class StateController : public ash::mojom::TrayActionClient,
void OnAppWindowRemoved(extensions::AppWindow* app_window) override;
// ui::InputDeviceEventObserver:
void OnStylusStateChanged(ui::StylusState state) override;
void OnTouchscreenDeviceConfigurationChanged() override;
// chromeos::PowerManagerClient::Observer
void BrightnessChanged(int level, bool user_initiated) override;
void SuspendImminent(power_manager::SuspendImminent::Reason reason) override;
// Creates and registers an app window as action handler for the action on
......@@ -188,17 +185,6 @@ class StateController : public ash::mojom::TrayActionClient,
}
private:
// The screen state determined by observing brightness changes from power
// manager client.
enum class ScreenState {
// The screen state has not yet been initialized.
kUnknown,
// The screen is on - i.e. not completely dimmed.
kOn,
// The screen is off - it's brightness level is 0.
kOff
};
// Gets the encryption key that should be used to encrypt user data created on
// the lock screen. If a key hadn't previously been created and saved to
// user prefs, a new key is created and saved.
......@@ -243,16 +229,6 @@ class StateController : public ash::mojom::TrayActionClient,
// It focuses the app window.
void FocusAppWindow(bool reverse);
// Updates the screen state to match the current screen brightness - no-op
// unless the current screen state is unknown.
void SetInitialScreenState(base::Optional<double> screen_brightness);
// Updates ths screen state - if the stylus was recently removed and screen
// has turned on, this will launch a new note action (stylus being removed
// should launch the note action, but this is deferred if the screen is off
// when the removal event occurs).
void SetScreenState(ScreenState screen_state);
// Lock screen note action state.
ash::mojom::TrayActionState lock_screen_note_state_ =
ash::mojom::TrayActionState::kNotAvailable;
......@@ -264,15 +240,6 @@ class StateController : public ash::mojom::TrayActionClient,
std::unique_ptr<LockScreenProfileCreator> lock_screen_profile_creator_;
// The current screen state.
ScreenState screen_state_ = ScreenState::kUnknown;
// The time-stamp of the last observed stylus eject event. This will get set
// if stylus was ejected while the screen was off, and the note action launch
// was thus deferred. If the screen is turned on soon after the stylus is
// ejected, lock screen note action will be launched.
base::TimeTicks stylus_eject_timestamp_;
// Whether sending app launch request to the note taking app (using
// |app_manager_|) was delayed until the note action launch animation is
// completed by lock screen UI - this is only used with Web UI lock
......
......@@ -59,6 +59,11 @@ void FakePowerManagerClient::IncreaseScreenBrightness() {}
void FakePowerManagerClient::SetScreenBrightnessPercent(double percent,
bool gradual) {
screen_brightness_percent_ = percent;
requested_screen_brightness_percent_ = percent;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&FakePowerManagerClient::SendBrightnessChanged,
weak_ptr_factory_.GetWeakPtr(), percent, true));
}
void FakePowerManagerClient::GetScreenBrightnessPercent(
......@@ -96,7 +101,10 @@ void FakePowerManagerClient::RequestShutdown(
}
void FakePowerManagerClient::NotifyUserActivity(
power_manager::UserActivityType type) {}
power_manager::UserActivityType type) {
if (user_activity_callback_)
user_activity_callback_.Run();
}
void FakePowerManagerClient::NotifyVideoActivity(bool is_fullscreen) {
video_activity_reports_.push_back(is_fullscreen);
......@@ -136,6 +144,19 @@ void FakePowerManagerClient::SetPowerSource(const std::string& id) {
void FakePowerManagerClient::SetBacklightsForcedOff(bool forced_off) {
backlights_forced_off_ = forced_off;
++num_set_backlights_forced_off_calls_;
double target_brightness =
forced_off ? 0 : requested_screen_brightness_percent_;
if (enqueue_brightness_changes_on_backlights_forced_off_) {
pending_brightness_changes_.push(target_brightness);
} else {
screen_brightness_percent_ = target_brightness;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FakePowerManagerClient::SendBrightnessChanged,
weak_ptr_factory_.GetWeakPtr(), target_brightness,
false));
}
}
void FakePowerManagerClient::GetBacklightsForcedOff(
......@@ -252,4 +273,17 @@ void FakePowerManagerClient::SetPowerPolicyQuitClosure(
power_policy_quit_closure_ = std::move(quit_closure);
}
bool FakePowerManagerClient::ApplyPendingBrightnessChange() {
if (pending_brightness_changes_.empty())
return false;
double brightness = pending_brightness_changes_.front();
pending_brightness_changes_.pop();
DCHECK(brightness == 0 || brightness == requested_screen_brightness_percent_);
screen_brightness_percent_ = brightness;
SendBrightnessChanged(brightness, false);
return true;
}
} // namespace chromeos
......@@ -5,7 +5,9 @@
#ifndef CHROMEOS_DBUS_FAKE_POWER_MANAGER_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_POWER_MANAGER_CLIENT_H_
#include <queue>
#include <string>
#include <utility>
#include "base/callback_forward.h"
#include "base/containers/circular_deque.h"
......@@ -48,6 +50,15 @@ class CHROMEOS_EXPORT FakePowerManagerClient : public PowerManagerClient {
int num_set_backlights_forced_off_calls() const {
return num_set_backlights_forced_off_calls_;
}
void set_enqueue_brightness_changes_on_backlights_forced_off(bool enqueue) {
enqueue_brightness_changes_on_backlights_forced_off_ = enqueue;
}
const std::queue<double>& pending_brightness_changes() const {
return pending_brightness_changes_;
}
void set_user_activity_callback(base::RepeatingClosure callback) {
user_activity_callback_ = std::move(callback);
}
// PowerManagerClient overrides:
void Init(dbus::Bus* bus) override;
......@@ -117,6 +128,12 @@ class CHROMEOS_EXPORT FakePowerManagerClient : public PowerManagerClient {
// lock has been created.
void SetPowerPolicyQuitClosure(base::OnceClosure quit_closure);
// Updates screen brightness to the first pending value in
// |pending_brightness_changes_|.
// Returns whether the screen brightness change was applied - this will
// return false if there are no pending brightness changes.
bool ApplyPendingBrightnessChange();
// Sets the screen brightness percent to be returned.
// The nullopt |percent| means an error. In case of success,
// |percent| must be in the range of [0, 100].
......@@ -150,9 +167,16 @@ class CHROMEOS_EXPORT FakePowerManagerClient : public PowerManagerClient {
// Number of pending suspend readiness callbacks.
int num_pending_suspend_readiness_callbacks_ = 0;
// The ratio of the screen brightness.
// Current screen brightness in the range [0.0, 100.0].
base::Optional<double> screen_brightness_percent_;
// Last screen brightness requested via SetScreenBrightnessPercent().
// Unlike |screen_brightness_percent_|, this value will not be changed by
// SetBacklightsForcedOff() method - a method that implicitly changes screen
// brightness.
// Initially set to an arbitrary non-null value.
double requested_screen_brightness_percent_ = 80;
// Last projecting state set in SetIsProjecting().
bool is_projecting_ = false;
......@@ -160,6 +184,20 @@ class CHROMEOS_EXPORT FakePowerManagerClient : public PowerManagerClient {
// SetBacklightsForcedOff().
bool backlights_forced_off_ = false;
// Whether screen brightness changes in SetBacklightsForcedOff() should be
// enqueued.
// If not set, SetBacklightsForcedOff() will update current screen
// brightness and send a brightness change event (provided undimmed
// brightness percent is set).
// If set, brightness changes will be enqueued to
// pending_brightness_changes_, and will have to be applied explicitly by
// calling ApplyPendingBrightnessChange().
bool enqueue_brightness_changes_on_backlights_forced_off_ = false;
// Pending brightness changes caused by SetBacklightsForcedOff().
// ApplyPendingBrightnessChange() applies the first pending change.
std::queue<double> pending_brightness_changes_;
// States returned by GetSwitchStates().
LidState lid_state_ = LidState::OPEN;
TabletMode tablet_mode_ = TabletMode::UNSUPPORTED;
......@@ -174,6 +212,9 @@ class CHROMEOS_EXPORT FakePowerManagerClient : public PowerManagerClient {
// If non-empty, called by SetPowerPolicy().
base::OnceClosure power_policy_quit_closure_;
// If non-empty, called by NotifyUserActivity().
base::RepeatingClosure user_activity_callback_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<FakePowerManagerClient> weak_ptr_factory_;
......
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