// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/keyboard_brightness/keyboard_brightness_controller.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/login/login_screen_controller.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/system/keyboard_brightness_control_delegate.h"
#include "ash/system/power/power_status.h"
#include "ash/test/ash_test_base.h"
#include "base/metrics/histogram_functions.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "chromeos/dbus/power/fake_power_manager_client.h"
#include "components/user_manager/known_user.h"
namespace ash {
namespace {
constexpr char kUserEmail[] = "[email protected]";
constexpr char kUserEmailSecondary[] = "[email protected]";
constexpr double kInitialKeyboardBrightness = 40.0;
power_manager::PowerSupplyProperties BuildFakePowerSupplyProperties(
power_manager::PowerSupplyProperties::ExternalPower charger_state) {
power_manager::PowerSupplyProperties fake_power;
fake_power.set_external_power(charger_state);
fake_power.set_battery_percent(50);
return fake_power;
}
void SetBatteryPower() {
DCHECK(PowerStatus::IsInitialized());
PowerStatus::Get()->SetProtoForTesting(BuildFakePowerSupplyProperties(
power_manager::PowerSupplyProperties::DISCONNECTED));
}
void SetChargerPower() {
DCHECK(PowerStatus::IsInitialized());
PowerStatus::Get()->SetProtoForTesting(
BuildFakePowerSupplyProperties(power_manager::PowerSupplyProperties::AC));
}
} // namespace
class FakeKeyboardBrightnessControlDelegate
: public KeyboardBrightnessControlDelegate {
public:
FakeKeyboardBrightnessControlDelegate() = default;
~FakeKeyboardBrightnessControlDelegate() override = default;
// override methods:
void HandleKeyboardBrightnessDown() override {}
void HandleKeyboardBrightnessUp() override {}
void HandleToggleKeyboardBacklight() override {}
void HandleGetKeyboardBrightness(
base::OnceCallback<void(std::optional<double>)> callback) override {
std::move(callback).Run(keyboard_brightness_);
}
void HandleSetKeyboardBrightness(
double percent,
bool gradual,
KeyboardBrightnessChangeSource source) override {
keyboard_brightness_ = percent;
}
void HandleSetKeyboardAmbientLightSensorEnabled(
bool enabled,
KeyboardAmbientLightSensorEnabledChangeSource source) override {}
void HandleGetKeyboardAmbientLightSensorEnabled(
base::OnceCallback<void(std::optional<bool>)> callback) override {}
double keyboard_brightness() { return keyboard_brightness_; }
void OnReceiveHasKeyboardBacklight(
std::optional<bool> has_keyboard_backlight) {
if (has_keyboard_backlight.has_value()) {
base::UmaHistogramBoolean("ChromeOS.Keyboard.HasBacklight",
has_keyboard_backlight.value());
}
}
void OnReceiveHasAmbientLightSensor(std::optional<bool> has_sensor) {
if (has_sensor.has_value()) {
base::UmaHistogramBoolean(
"ChromeOS.Settings.Device.HasAmbientLightSensor", has_sensor.value());
}
}
private:
double keyboard_brightness_ = 0;
};
class KeyboardBrightnessControllerTest : public AshTestBase {
public:
KeyboardBrightnessControllerTest()
: AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
void SetUp() override {
AshTestBase::SetUp();
delegate_ = std::make_unique<FakeKeyboardBrightnessControlDelegate>();
histogram_tester_ = std::make_unique<base::HistogramTester>();
}
void TearDown() override {
AshTestBase::TearDown();
delegate_.reset();
}
KeyboardBrightnessControlDelegate* keyboard_brightness_control_delegate() {
return Shell::Get()->keyboard_brightness_control_delegate();
}
LoginDataDispatcher* login_data_dispatcher() {
return Shell::Get()->login_screen_controller()->data_dispatcher();
}
// Whether prefs::kKeyboardAmbientLightSensorEnabled has been set.
bool HasKeyboardAmbientLightSensorEnabledPrefValue(
const user_manager::KnownUser& known_user,
const AccountId& account_id) {
const base::Value* pref_value = known_user.FindPath(
account_id, prefs::kKeyboardAmbientLightSensorEnabled);
if (!pref_value) {
return false;
}
return pref_value->is_bool();
}
// Gets the KnownUser keyboard ALS enabled pref value. Only call this
// function if HasKeyboardAmbientLightSensorPrefValue is true.
bool GetKeyboardAmbientLightSensorEnabledPrefValue(
const user_manager::KnownUser& known_user,
const AccountId& account_id) {
return known_user
.FindPath(account_id, prefs::kKeyboardAmbientLightSensorEnabled)
->GetBool();
}
// Whether prefs::kKeyboardBrightnessPercent has been set.
bool HasKeyboardBrightnessPrefValue(const user_manager::KnownUser& known_user,
const AccountId& account_id) {
const base::Value* pref_value =
known_user.FindPath(account_id, prefs::kKeyboardBrightnessPercent);
if (!pref_value) {
return false;
}
return pref_value->is_double();
}
// Gets the KnownUser keyboard brightness percent pref value. Only call this
// function if HasKeyboardBrightnessPrefValue is true.
double GetKeyboardBrightnessPrefValue(
const user_manager::KnownUser& known_user,
const AccountId& account_id) {
return known_user.FindPath(account_id, prefs::kKeyboardBrightnessPercent)
->GetDouble();
}
// Return true if there is a KnownUser pref for the keyboard ambient light
// sensor disabled reason.
bool HasKeyboardAmbientLightSensorDisabledReasonPrefValue(
const user_manager::KnownUser& known_user,
const AccountId& account_id) {
const base::Value* pref_value = known_user.FindPath(
account_id, prefs::kKeyboardAmbientLightSensorDisabledReason);
if (!pref_value) {
return false;
}
return pref_value->is_int();
}
// Gets the KnownUser keyboard ambient light sensor disabled reason pref
// value. Only call this function if
// HasKeyboardAmbientLightSensorDisabledReasonPrefValue is true.
int GetKeyboardAmbientLightSensorDisabledReasonPrefValue(
const user_manager::KnownUser& known_user,
const AccountId& account_id) {
return known_user
.FindPath(account_id, prefs::kKeyboardAmbientLightSensorDisabledReason)
->GetInt();
}
void SetKeyboardAmbientLightSensorEnabled(
bool enabled,
power_manager::AmbientLightSensorChange_Cause cause) {
keyboard_brightness_control_delegate()
->HandleSetKeyboardAmbientLightSensorEnabled(
enabled,
KeyboardAmbientLightSensorEnabledChangeSource::kSettingsApp);
power_manager::AmbientLightSensorChange sensor_change;
sensor_change.set_sensor_enabled(enabled);
sensor_change.set_cause(cause);
power_manager_client()->SendKeyboardAmbientLightSensorEnabledChanged(
sensor_change);
}
void SetKeyboardBrightness(
double keyboard_brightness,
power_manager::BacklightBrightnessChange_Cause cause) {
keyboard_brightness_control_delegate()->HandleSetKeyboardBrightness(
keyboard_brightness, /*gradual=*/false,
KeyboardBrightnessChangeSource::kSettingsApp);
power_manager::BacklightBrightnessChange brightness_change;
brightness_change.set_percent(keyboard_brightness);
brightness_change.set_cause(cause);
power_manager_client()->set_keyboard_brightness_percent(
keyboard_brightness);
power_manager_client()->SendKeyboardBrightnessChanged(brightness_change);
}
// On the login screen, focus the given account.
void LoginScreenFocusAccount(const AccountId account_id) {
login_data_dispatcher()->NotifyFocusPod(account_id);
run_loop_.RunUntilIdle();
}
// Check if keyboard ambient light sensor status is equal to expected value.
void ExpectKeyboardAmbientLightSensorEnabled(bool expected_value) {
keyboard_brightness_control_delegate()
->HandleGetKeyboardAmbientLightSensorEnabled(base::BindLambdaForTesting(
[expected_value](std::optional<bool> sensor_enabled) {
EXPECT_EQ(sensor_enabled.value(), expected_value);
}));
}
// Check if keyboard brightness is equal to expected value.
void ExpectKeyboardBrightnessPercent(double expected_value) {
keyboard_brightness_control_delegate()->HandleGetKeyboardBrightness(
base::BindLambdaForTesting(
[expected_value](std::optional<double> keyboard_brightness) {
EXPECT_EQ(keyboard_brightness.value(), expected_value);
}));
}
void AdvanceClock(base::TimeDelta time) {
task_environment()->AdvanceClock(time);
}
protected:
base::RunLoop run_loop_;
std::unique_ptr<base::HistogramTester> histogram_tester_;
std::unique_ptr<FakeKeyboardBrightnessControlDelegate> delegate_;
base::test::ScopedFeatureList scoped_feature_list_;
};
TEST_F(KeyboardBrightnessControllerTest, RecordHasKeyboardBrightness) {
histogram_tester_->ExpectTotalCount("ChromeOS.Keyboard.HasBacklight", 0);
delegate_->OnReceiveHasKeyboardBacklight(std::optional<bool>(true));
histogram_tester_->ExpectTotalCount("ChromeOS.Keyboard.HasBacklight", 1);
}
TEST_F(KeyboardBrightnessControllerTest, RecordHasAmbientLightSensor) {
histogram_tester_->ExpectTotalCount(
"ChromeOS.Settings.Device.HasAmbientLightSensor", 0);
delegate_->OnReceiveHasAmbientLightSensor(std::optional<bool>(true));
histogram_tester_->ExpectTotalCount(
"ChromeOS.Settings.Device.HasAmbientLightSensor", 1);
}
TEST_F(KeyboardBrightnessControllerTest, SetKeyboardAmbientLightSensorEnabled) {
// Ambient light sensor is enabled by default.
EXPECT_TRUE(power_manager_client()->keyboard_ambient_light_sensor_enabled());
// Disable the ambient light sensor.
keyboard_brightness_control_delegate()
->HandleSetKeyboardAmbientLightSensorEnabled(
false, KeyboardAmbientLightSensorEnabledChangeSource::kSettingsApp);
// Verify that the ambient light sensor is now disabled.
EXPECT_FALSE(power_manager_client()->keyboard_ambient_light_sensor_enabled());
keyboard_brightness_control_delegate()
->HandleGetKeyboardAmbientLightSensorEnabled(base::BindOnce(
[](std::optional<bool> is_ambient_light_sensor_enabled) {
EXPECT_FALSE(is_ambient_light_sensor_enabled.value());
}));
// Re-enabled the ambient light sensor
keyboard_brightness_control_delegate()
->HandleSetKeyboardAmbientLightSensorEnabled(
true, KeyboardAmbientLightSensorEnabledChangeSource::kSettingsApp);
// Verify that the ambient light sensor is enabled.
EXPECT_TRUE(power_manager_client()->keyboard_ambient_light_sensor_enabled());
keyboard_brightness_control_delegate()
->HandleGetKeyboardAmbientLightSensorEnabled(base::BindOnce(
[](std::optional<bool> is_ambient_light_sensor_enabled) {
EXPECT_TRUE(is_ambient_light_sensor_enabled.value());
}));
}
TEST_F(KeyboardBrightnessControllerTest, SaveKeyboardALSPrefToKnownUser) {
// Set initial ALS status.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
// Clear user sessions and reset to the primary login screen.
ClearLogin();
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
// Create a KnownUser for this Local State.
user_manager::KnownUser known_user(local_state());
// On the login screen, focus the user.
LoginScreenFocusAccount(account_id);
EXPECT_FALSE(
HasKeyboardAmbientLightSensorEnabledPrefValue(known_user, account_id));
// Set the Keyboard ALS enabled to false for the user.
SetKeyboardAmbientLightSensorEnabled(
false, power_manager::AmbientLightSensorChange_Cause::
AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
// Expect pref value is saved, and the pref value is set to false.
EXPECT_TRUE(
HasKeyboardAmbientLightSensorEnabledPrefValue(known_user, account_id));
EXPECT_FALSE(
GetKeyboardAmbientLightSensorEnabledPrefValue(known_user, account_id));
}
TEST_F(KeyboardBrightnessControllerTest, SaveBrightnessPrefToKnownUserOnLogin) {
// Set initial brightness.
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Clear user sessions and reset to the primary login screen.
ClearLogin();
// Create a KnownUser for this Local State.
user_manager::KnownUser known_user(local_state());
// On the login screen, focus the user.
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
LoginScreenFocusAccount(account_id);
EXPECT_FALSE(
HasKeyboardAmbientLightSensorEnabledPrefValue(known_user, account_id));
// Simulate the brightness changing automatically due to inactivity.
// This should not be saved into Local State.
SetKeyboardBrightness(
0.0, power_manager::BacklightBrightnessChange_Cause_USER_INACTIVITY);
EXPECT_FALSE(HasKeyboardBrightnessPrefValue(known_user, account_id));
// Simulate the brightness changing automatically due to user activity.
// This should not be saved into Local State.
SetKeyboardBrightness(
60.0, power_manager::BacklightBrightnessChange_Cause_USER_ACTIVITY);
EXPECT_FALSE(HasKeyboardBrightnessPrefValue(known_user, account_id));
// Set the brightness to a new value via user action.
double brightness_change_percent = 12.0;
SetKeyboardBrightness(
brightness_change_percent,
power_manager::BacklightBrightnessChange_Cause_USER_REQUEST);
// Expect pref value is saved, and the pref value is set to
// brightness_change_percent.
EXPECT_TRUE(HasKeyboardBrightnessPrefValue(known_user, account_id));
EXPECT_EQ(GetKeyboardBrightnessPrefValue(known_user, account_id),
brightness_change_percent);
}
TEST_F(KeyboardBrightnessControllerTest,
SaveBrightnessPrefToKnownUserAfterLogin) {
// Set initial brightness.
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Clear user sessions and reset to the primary login screen.
ClearLogin();
// Create a KnownUser for this Local State.
user_manager::KnownUser known_user(local_state());
// On the login screen, focus the user.
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
LoginScreenFocusAccount(account_id);
EXPECT_FALSE(HasKeyboardBrightnessPrefValue(known_user, account_id));
// Simulate user login.
SimulateUserLogin(kUserEmail);
run_loop_.RunUntilIdle();
// After login, the brightness pref should have a value equal to the initial
// brightness level.
EXPECT_TRUE(HasKeyboardBrightnessPrefValue(known_user, account_id));
EXPECT_EQ(GetKeyboardBrightnessPrefValue(known_user, account_id),
kInitialKeyboardBrightness);
// Simulate the keyboard brightness changing automatically due to inactivity.
// This should not be saved into Local State.
SetKeyboardBrightness(
0.0, power_manager::BacklightBrightnessChange_Cause_USER_INACTIVITY);
EXPECT_EQ(GetKeyboardBrightnessPrefValue(known_user, account_id),
kInitialKeyboardBrightness);
// Change the brightness via user request (this time, after login).
double new_brightness_change_percent = 96.0;
SetKeyboardBrightness(
new_brightness_change_percent,
power_manager::BacklightBrightnessChange_Cause_USER_REQUEST);
// The Local State brightness pref should have the new brightness value
// stored.
EXPECT_TRUE(HasKeyboardBrightnessPrefValue(known_user, account_id));
EXPECT_EQ(GetKeyboardBrightnessPrefValue(known_user, account_id),
new_brightness_change_percent);
// Change the brightness via user request, from the Settings app.
double settings_brightness_change_percent = 22.2;
SetKeyboardBrightness(
settings_brightness_change_percent,
power_manager::
BacklightBrightnessChange_Cause_USER_REQUEST_FROM_SETTINGS_APP);
// The Local State brightness pref should have the new brightness value
// stored.
EXPECT_EQ(GetKeyboardBrightnessPrefValue(known_user, account_id),
settings_brightness_change_percent);
}
TEST_F(KeyboardBrightnessControllerTest, SavePrefToKnownUserMultipleUser) {
// Set initial brightness.
power_manager_client()->set_screen_brightness_percent(
kInitialKeyboardBrightness);
// Clear user sessions and reset to the primary login screen.
ClearLogin();
AccountId first_account = AccountId::FromUserEmail(kUserEmail);
AccountId second_account = AccountId::FromUserEmail(kUserEmailSecondary);
// On the login screen, focus the first user.
LoginScreenFocusAccount(first_account);
// Create a KnownUser for this Local State.
user_manager::KnownUser known_user(local_state());
EXPECT_FALSE(HasKeyboardBrightnessPrefValue(known_user, first_account));
EXPECT_FALSE(HasKeyboardBrightnessPrefValue(known_user, second_account));
// Set the brightness to a new value via user action.
double first_brightness_change_percent = 12.0;
SetKeyboardBrightness(
first_brightness_change_percent,
power_manager::BacklightBrightnessChange_Cause_USER_REQUEST);
// The brightness Local State pref should now be set, with the value of the
// current brightness, the second user should still not have a pref set.
EXPECT_EQ(GetKeyboardBrightnessPrefValue(known_user, first_account),
first_brightness_change_percent);
EXPECT_FALSE(HasKeyboardBrightnessPrefValue(known_user, second_account));
// On the login screen, focus the second user.
LoginScreenFocusAccount(second_account);
// Set the brightness to a new value via user action for the second user.
double second_brightness_change_percent = 99.9;
SetKeyboardBrightness(
second_brightness_change_percent,
power_manager::BacklightBrightnessChange_Cause_USER_REQUEST);
// The second user have the pref value set to
// second_brightness_change_percent.
EXPECT_EQ(GetKeyboardBrightnessPrefValue(known_user, second_account),
second_brightness_change_percent);
// The first user still have the old brightness percent value.
EXPECT_EQ(GetKeyboardBrightnessPrefValue(known_user, first_account),
first_brightness_change_percent);
}
TEST_F(KeyboardBrightnessControllerTest,
RestoreKeyboardBrightnessSettings_FlagEnabled) {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Set initial ALS status and brightness level.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Clear user sessions and reset to the primary login screen.
ClearLogin();
// On the login screen, focus the first user.
AccountId first_account = AccountId::FromUserEmail(kUserEmail);
LoginScreenFocusAccount(first_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(kInitialKeyboardBrightness);
// Then, focus the second user.
AccountId second_account = AccountId::FromUserEmail(kUserEmailSecondary);
LoginScreenFocusAccount(second_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(kInitialKeyboardBrightness);
// Switch back to the first user, then disable ALS by changing the brightness.
LoginScreenFocusAccount(first_account);
const double first_brightness_change_percent = 20.0;
keyboard_brightness_control_delegate()->HandleSetKeyboardBrightness(
first_brightness_change_percent, /*gradual=*/false,
KeyboardBrightnessChangeSource::kSettingsApp);
// ALS should be disabled for the first user.
run_loop_.RunUntilIdle();
ExpectKeyboardAmbientLightSensorEnabled(false);
ExpectKeyboardBrightnessPercent(first_brightness_change_percent);
// ALS should remain enabled for the second user, despite being disabled for
// the first user, Brightness should remain the same after switching to the
// second user.
LoginScreenFocusAccount(second_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(first_brightness_change_percent);
// ALS should be disabled for first user after switching back from second
// user.
LoginScreenFocusAccount(first_account);
ExpectKeyboardAmbientLightSensorEnabled(false);
ExpectKeyboardBrightnessPercent(first_brightness_change_percent);
// Simulate a reboot, which resets the value of the keyboard ambient light
// sensor and the keyboard brightness.
ClearLogin();
power_manager::SetAmbientLightSensorEnabledRequest request2;
request2.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request2);
power_manager_client()->set_screen_brightness_percent(
kInitialKeyboardBrightness);
// After reboot, ALS should be still be disabled for the first user, and
// keybard brightness is restored.
LoginScreenFocusAccount(first_account);
ExpectKeyboardAmbientLightSensorEnabled(false);
ExpectKeyboardBrightnessPercent(first_brightness_change_percent);
// After reboot, ALS should be still be enabled for second user, and keyboard
// brightness should be should be equal to the last value set (since
// auto-brightness is enabled).
LoginScreenFocusAccount(second_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(first_brightness_change_percent);
// Switch back to the first user, ALS should remain disabled.
LoginScreenFocusAccount(first_account);
ExpectKeyboardAmbientLightSensorEnabled(false);
ExpectKeyboardBrightnessPercent(first_brightness_change_percent);
}
TEST_F(KeyboardBrightnessControllerTest,
RestoreKeyboardBrightnessSettings_FlagDisabled) {
scoped_feature_list_.InitAndDisableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Set initial ALS status.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Clear user sessions and reset to the primary login screen.
ClearLogin();
// On the login screen, focus the first user.
AccountId first_account = AccountId::FromUserEmail(kUserEmail);
LoginScreenFocusAccount(first_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(kInitialKeyboardBrightness);
// Then, focus the second user.
AccountId second_account = AccountId::FromUserEmail(kUserEmailSecondary);
LoginScreenFocusAccount(second_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(kInitialKeyboardBrightness);
// Switch back to the first user, then disable ALS by changing the brightness.
LoginScreenFocusAccount(first_account);
const double first_brightness_change_percent = 20.0;
keyboard_brightness_control_delegate()->HandleSetKeyboardBrightness(
first_brightness_change_percent, /*gradual=*/false,
KeyboardBrightnessChangeSource::kSettingsApp);
// ALS should be disabled for the first user.
run_loop_.RunUntilIdle();
ExpectKeyboardAmbientLightSensorEnabled(false);
ExpectKeyboardBrightnessPercent(first_brightness_change_percent);
// ALS should be disabled for second user because the ALS value is not being
// restored from prefs.
LoginScreenFocusAccount(second_account);
ExpectKeyboardAmbientLightSensorEnabled(false);
ExpectKeyboardBrightnessPercent(first_brightness_change_percent);
// ALS should be disabled for first user after switching back from second
// user.
LoginScreenFocusAccount(first_account);
ExpectKeyboardAmbientLightSensorEnabled(false);
// Simulate a reboot, which resets the value of the ambient light sensor.
// the keyboard brightness.
ClearLogin();
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// After reboot, ALS should be enabled for the first user by default, the
// brightness level should be equal to the initial brightness for the first
// user.
LoginScreenFocusAccount(first_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(kInitialKeyboardBrightness);
// After reboot, ALS should be enabled for the second user by default, and
// brightness level is default level.
LoginScreenFocusAccount(second_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(kInitialKeyboardBrightness);
// Switch back to the first user, settings should remain the same.
LoginScreenFocusAccount(first_account);
ExpectKeyboardAmbientLightSensorEnabled(true);
ExpectKeyboardBrightnessPercent(kInitialKeyboardBrightness);
}
TEST_F(KeyboardBrightnessControllerTest, KeyboardALSDisabledReasonPref) {
// Set initial ALS status and brightness level.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// On the login screen, focus a user.
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
login_data_dispatcher()->NotifyFocusPod(account_id);
user_manager::KnownUser known_user(local_state());
// Confirm that no "disabled reason" pref exists for the given KnownUser.
EXPECT_FALSE(HasKeyboardAmbientLightSensorDisabledReasonPrefValue(
known_user, account_id));
// Disable the keyboard ambient light sensor.
SetKeyboardAmbientLightSensorEnabled(
false,
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
// There should now be a "disabled reason" pref stored in KnownUser.
EXPECT_TRUE(HasKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
EXPECT_EQ(
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP,
GetKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
// Re-enable the keyboard ambient light sensor.
SetKeyboardAmbientLightSensorEnabled(
true,
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
// After the keyboard ambient light sensor is re-enabled, the "disabled
// reason" pref should be deleted.
EXPECT_FALSE(HasKeyboardAmbientLightSensorDisabledReasonPrefValue(
known_user, account_id));
// Test with other causes.
SetKeyboardAmbientLightSensorEnabled(
false,
power_manager::AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST);
EXPECT_TRUE(HasKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
EXPECT_EQ(
power_manager::AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST,
GetKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
}
TEST_F(KeyboardBrightnessControllerTest, KeyboardAmbientLightEnabledUserPref) {
// Activate user session.
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
// Set the ambient light sensor to be enabled initially.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
run_loop_.RunUntilIdle();
// User pref is default to true.
EXPECT_TRUE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
// Disable the sensor via brightness change (not from settings app), pref
// should remain true.
SetKeyboardAmbientLightSensorEnabled(
false, power_manager::AmbientLightSensorChange_Cause::
AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST);
EXPECT_TRUE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
// Re-enable the sensor from settings app, pref should be true.
SetKeyboardAmbientLightSensorEnabled(
true, power_manager::AmbientLightSensorChange_Cause::
AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
EXPECT_TRUE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
// Disable the sensor again, this time, the request is from settings app, the
// pref should be updated to false.
SetKeyboardAmbientLightSensorEnabled(
false, power_manager::AmbientLightSensorChange_Cause::
AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
EXPECT_FALSE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
// Re-enable the sensor via user settings and verify the preference updates.
SetKeyboardAmbientLightSensorEnabled(
true, power_manager::AmbientLightSensorChange_Cause::
AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
EXPECT_TRUE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
}
TEST_F(KeyboardBrightnessControllerTest,
RestoreKeyboardALSSettingForNewUser_FlagEnabled) {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Set initial ALS and keyboard brightness.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Clear user sessions and reset to the primary login screen.
ClearLogin();
// On the login screen, select and login with an existing user.
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
login_data_dispatcher()->NotifyFocusPod(account_id);
LoginScreenFocusAccount(account_id);
SimulateUserLogin(kUserEmail);
// The ambient light sensor should be enabled by default.
EXPECT_TRUE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
ExpectKeyboardAmbientLightSensorEnabled(true);
// Set Keyboard ALS status to false.
SetKeyboardAmbientLightSensorEnabled(
false,
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
// The synced profile pref should have the correct value (false).
EXPECT_FALSE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
ExpectKeyboardAmbientLightSensorEnabled(false);
// Simulate a reboot, which resets the value of the ambient light sensor and
// the keyboard brightness.
ClearLogin();
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Simulate a login with a second user.
SimulateNewUserFirstLogin(kUserEmailSecondary);
// Verify default keyboard brightness settings.
EXPECT_TRUE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
ExpectKeyboardAmbientLightSensorEnabled(true);
// Manually set the user pref, which will be synced to the first user later.
Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled, false);
// Now, login the first user again, as if it's that user's first time
// logging in on this device.
SimulateNewUserFirstLogin(kUserEmail);
// The value of the synced profile pref for the keyboard ambient light sensor
// should be false, because on the "other device" that value was set to false.
EXPECT_FALSE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
ExpectKeyboardAmbientLightSensorEnabled(false);
}
TEST_F(KeyboardBrightnessControllerTest,
RestoreKeyboardALSSettingForNewUser_FlagDisabled) {
scoped_feature_list_.InitAndDisableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Set initial ALS and keyboard brightness.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Clear user sessions and reset to the primary login screen.
ClearLogin();
// On the login screen, select and login with an existing user.
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
login_data_dispatcher()->NotifyFocusPod(account_id);
LoginScreenFocusAccount(account_id);
SimulateUserLogin(kUserEmail);
// The ambient light sensor should be enabled by default.
EXPECT_TRUE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
ExpectKeyboardAmbientLightSensorEnabled(true);
// Set Keyboard ALS status to false.
SetKeyboardAmbientLightSensorEnabled(
false,
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
// The synced profile pref should have the correct value (false).
EXPECT_FALSE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
ExpectKeyboardAmbientLightSensorEnabled(false);
// Simulate a reboot, which resets the value of the ambient light sensor and
// the keyboard brightness.
ClearLogin();
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Simulate a login with a second user.
SimulateNewUserFirstLogin(kUserEmailSecondary);
// Verify default keyboard brightness settings.
EXPECT_TRUE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
ExpectKeyboardAmbientLightSensorEnabled(true);
// Manually set the user pref, which will be synced to the first user later.
Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled, false);
// Now, login the first user again, as if it's that user's first time
// logging in on this device.
SimulateNewUserFirstLogin(kUserEmail);
// The value of the synced profile pref for the keyboard ambient light sensor
// should be false, because on the "other device" that value was set to false.
EXPECT_FALSE(
Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
prefs::kKeyboardAmbientLightSensorLastEnabled));
// However, because the flag is disabled, the keyboard ambient light sensor
// preference will not be restored, and thus the keyboard ambient light sensor
// should be disabled.
ExpectKeyboardAmbientLightSensorEnabled(true);
}
TEST_F(KeyboardBrightnessControllerTest, SetKeyboardBrightness_Cause) {
// Keyboard brightness changes from Quick Settings should have cause
// "USER_REQUEST".
keyboard_brightness_control_delegate()->HandleSetKeyboardBrightness(
50, /*gradual=*/true, KeyboardBrightnessChangeSource::kQuickSettings);
EXPECT_EQ(power_manager_client()->requested_keyboard_brightness_cause(),
power_manager::SetBacklightBrightnessRequest_Cause_USER_REQUEST);
// Keyboard brightness changes from the Settings app should have cause
// "USER_REQUEST_FROM_SETTINGS_APP".
keyboard_brightness_control_delegate()->HandleSetKeyboardBrightness(
50, /*gradual=*/true, /*source=*/
KeyboardBrightnessChangeSource::kSettingsApp);
EXPECT_EQ(
power_manager_client()->requested_keyboard_brightness_cause(),
power_manager::
SetBacklightBrightnessRequest_Cause_USER_REQUEST_FROM_SETTINGS_APP);
}
TEST_F(KeyboardBrightnessControllerTest,
ReenableKeyboardAmbientLightSensor_Reboot_DisabledFromSettingsApp) {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Set initial ALS and keyboard brightness.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Log in
ClearLogin();
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
user_manager::KnownUser known_user(local_state());
SimulateUserLogin(kUserEmail);
// Set ALS to false, and set the disabled reason to be
// USER_REQUEST_SETTINGS_APP.
SetKeyboardAmbientLightSensorEnabled(
false,
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
known_user.SetPath(
account_id, prefs::kKeyboardAmbientLightSensorDisabledReason,
std::make_optional<base::Value>(
power_manager::
AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP));
// ALS is disabled.
ExpectKeyboardAmbientLightSensorEnabled(false);
EXPECT_EQ(false, GetKeyboardAmbientLightSensorEnabledPrefValue(known_user,
account_id));
// "disabled reason" pref stored in KnownUser should be
// USER_REQUEST_SETTINGS_APP.
EXPECT_TRUE(HasKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
EXPECT_EQ(
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP,
GetKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
// Simulate reboot, and log in again.
known_user.SetPath(account_id, prefs::kKeyboardBrightnessPercent,
std::make_optional<base::Value>(30.0));
login_data_dispatcher()->NotifyFocusPod(account_id);
// Expect ambient light sensor remain disabled, and brightness should be
// restored.
ExpectKeyboardAmbientLightSensorEnabled(false);
ExpectKeyboardBrightnessPercent(30.0);
// Simulate reboot, and log in the third time.
login_data_dispatcher()->NotifyFocusPod(account_id);
// ALS and brightness should remain the same as last reboot.
ExpectKeyboardAmbientLightSensorEnabled(false);
ExpectKeyboardBrightnessPercent(30.0);
}
TEST_F(KeyboardBrightnessControllerTest,
ReenableKeyboardAmbientLightSensor_Reboot_DisabledFromBrightnessKey) {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Set initial ALS and keyboard brightness.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Log in
ClearLogin();
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
user_manager::KnownUser known_user(local_state());
SimulateUserLogin(kUserEmail);
// Set ALS to false by brightness key, and set the disabled reason to be
// BRIGHTNESS_USER_REQUEST.
SetKeyboardAmbientLightSensorEnabled(
false,
power_manager::AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST);
known_user.SetPath(
account_id, prefs::kKeyboardAmbientLightSensorDisabledReason,
std::make_optional<base::Value>(
power_manager::
AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST));
// ALS is disabled.
ExpectKeyboardAmbientLightSensorEnabled(false);
EXPECT_EQ(false, GetKeyboardAmbientLightSensorEnabledPrefValue(known_user,
account_id));
// "disabled reason" pref stored in KnownUser should be
// USER_REQUEST_SETTINGS_APP.
EXPECT_TRUE(HasKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
EXPECT_EQ(
power_manager::AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST,
GetKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
// Simulate reboot, and log in again.
known_user.SetPath(account_id, prefs::kKeyboardBrightnessPercent,
std::make_optional<base::Value>(30.0));
login_data_dispatcher()->NotifyFocusPod(account_id);
// Expect ambient light sensor is re-enabled.
ExpectKeyboardAmbientLightSensorEnabled(true);
// Simulate reboot, and log in the third time.
login_data_dispatcher()->NotifyFocusPod(account_id);
// ALS and should remain the same as last reboot.
ExpectKeyboardAmbientLightSensorEnabled(true);
}
TEST_F(
KeyboardBrightnessControllerTest,
ReenableKeyboardAmbientLightSensor_AfterLocalMidnight_DisableFromSettingApp) {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Set initial ALS status and brightness level.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Log in
ClearLogin();
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
user_manager::KnownUser known_user(local_state());
SimulateUserLogin(kUserEmail);
// Set ALS to false, and set the disabled reason to be
// USER_REQUEST_SETTINGS_APP.
SetKeyboardAmbientLightSensorEnabled(
false,
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP);
known_user.SetPath(
account_id, prefs::kKeyboardAmbientLightSensorDisabledReason,
std::make_optional<base::Value>(
power_manager::
AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP));
// "disabled reason" pref stored in KnownUser should be
// USER_REQUEST_SETTINGS_APP.
EXPECT_TRUE(HasKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
EXPECT_EQ(
power_manager::AmbientLightSensorChange_Cause_USER_REQUEST_SETTINGS_APP,
GetKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
// Ambient light sensor is disabled.
ExpectKeyboardAmbientLightSensorEnabled(false);
// Simulate the passing of 1 day.
AdvanceClock(base::Days(1));
// Trigger suspend event.
KeyboardBrightnessController* keyboard_brightness_controller =
static_cast<KeyboardBrightnessController*>(
keyboard_brightness_control_delegate());
keyboard_brightness_controller->SuspendImminent(
power_manager::SuspendImminent::LID_CLOSED);
// Ambient light sensor should remain disabled.
ExpectKeyboardAmbientLightSensorEnabled(false);
}
TEST_F(
KeyboardBrightnessControllerTest,
ReenableKeyboardAmbientLightSensor_AfterLocalMidnight_DisableOutsideSettingsApp) {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Set initial ALS status and brightness level.
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_keyboard_brightness_percent(
kInitialKeyboardBrightness);
// Log in
ClearLogin();
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
user_manager::KnownUser known_user(local_state());
SimulateUserLogin(kUserEmail);
// Set ALS to false, and set the disabled reason to be
// BRIGHTNESS_USER_REQUEST.
SetKeyboardAmbientLightSensorEnabled(
false,
power_manager::AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST);
known_user.SetPath(
account_id, prefs::kKeyboardAmbientLightSensorDisabledReason,
std::make_optional<base::Value>(
power_manager::
AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST));
// "disabled reason" pref stored in KnownUser should be
// BRIGHTNESS_USER_REQUEST.
EXPECT_TRUE(HasKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
EXPECT_EQ(
power_manager::AmbientLightSensorChange_Cause_BRIGHTNESS_USER_REQUEST,
GetKeyboardAmbientLightSensorDisabledReasonPrefValue(known_user,
account_id));
// Amebient light sensor is disabled.
ExpectKeyboardAmbientLightSensorEnabled(false);
// Simulate the passing of 1 day.
AdvanceClock(base::Days(1));
// Trigger suspend event.
KeyboardBrightnessController* keyboard_brightness_controller =
static_cast<KeyboardBrightnessController*>(
keyboard_brightness_control_delegate());
keyboard_brightness_controller->SuspendImminent(
power_manager::SuspendImminent::LID_CLOSED);
// Ambient light sensor is re-enabled.
ExpectKeyboardAmbientLightSensorEnabled(true);
}
TEST_F(KeyboardBrightnessControllerTest,
RecordStartupKeyboardAmbientLightSensorStatus) {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableKeyboardBacklightControlInSettings);
power_manager::SetAmbientLightSensorEnabledRequest request;
request.set_sensor_enabled(true);
power_manager_client()->SetKeyboardAmbientLightSensorEnabled(request);
power_manager_client()->set_has_ambient_light_sensor(true);
base::RunLoop().RunUntilIdle();
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.Startup.AmbientLightSensorEnabled", 0);
// Log in.
ClearLogin();
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
LoginScreenFocusAccount(account_id);
histogram_tester_->ExpectBucketCount(
"ChromeOS.Keyboard.Startup.AmbientLightSensorEnabled", true, 1);
// Log in again, expect no extra metric is emitted.
ClearLogin();
LoginScreenFocusAccount(account_id);
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.Startup.AmbientLightSensorEnabled", 1);
}
TEST_F(KeyboardBrightnessControllerTest,
HistogramTest_DecreaseBrightnessOnLoginScreen) {
// Metric count should start at 0.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"DecreaseBrightness.BatteryPower",
0);
// Start on the login screen
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOGIN_PRIMARY);
// "Unplug" the device from charger
SetBatteryPower();
// Wait for a period of time, then send a brightness event
int seconds_to_wait = 11;
AdvanceClock(base::Seconds(seconds_to_wait));
keyboard_brightness_control_delegate()->HandleKeyboardBrightnessDown();
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"DecreaseBrightness.BatteryPower",
1);
histogram_tester_->ExpectTimeBucketCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"DecreaseBrightness.BatteryPower",
base::Seconds(seconds_to_wait), 1);
// Login
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
// Wait for a period of time, then send another brightness event
AdvanceClock(base::Seconds(5));
keyboard_brightness_control_delegate()->HandleKeyboardBrightnessDown();
// The number of events should not have changed, since we already recorded a
// metric on the login screen.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"DecreaseBrightness.BatteryPower",
1);
}
TEST_F(KeyboardBrightnessControllerTest, HistogramTest_LoginSecondary) {
// Metric count should start at 0.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"DecreaseBrightness.BatteryPower",
0);
// Start on the "secondary" login screen (i.e. another user is already
// logged-in, and another user is now logging in).
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOGIN_SECONDARY);
// "Unplug" the device from charger
SetBatteryPower();
// Wait for a period of time, then send a brightness event
int seconds_to_wait = 22;
AdvanceClock(base::Seconds(seconds_to_wait));
keyboard_brightness_control_delegate()->HandleKeyboardBrightnessDown();
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"DecreaseBrightness.BatteryPower",
1);
histogram_tester_->ExpectTimeBucketCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"DecreaseBrightness.BatteryPower",
base::Seconds(seconds_to_wait), 1);
// Login
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
// Wait for a period of time, then send another brightness event
AdvanceClock(base::Seconds(5));
keyboard_brightness_control_delegate()->HandleKeyboardBrightnessDown();
// The number of events should not have changed, since we already recorded a
// metric on the login screen.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"DecreaseBrightness.BatteryPower",
1);
}
TEST_F(KeyboardBrightnessControllerTest, HistogramTest_PowerSourceCharger) {
// Metric count should start at 0.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"IncreaseBrightness.ChargerPower",
0);
// Start on the login screen
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOGIN_PRIMARY);
// "Plug in" the charger
SetChargerPower();
// Wait for a period of time, then send a brightness event
int seconds_to_wait = 8;
AdvanceClock(base::Seconds(seconds_to_wait));
keyboard_brightness_control_delegate()->HandleKeyboardBrightnessUp();
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"IncreaseBrightness.ChargerPower",
1);
histogram_tester_->ExpectTimeBucketCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLoginScreen."
"IncreaseBrightness.ChargerPower",
base::Seconds(seconds_to_wait), 1);
}
TEST_F(KeyboardBrightnessControllerTest,
HistogramTest_BrightnessChangeAfterLogin) {
// Metric count should start at 0.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"SetBrightness.ChargerPower",
0);
// Start on the login screen
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOGIN_PRIMARY);
// "Plug in" the charger
SetChargerPower();
// Wait for a period of time, but don't change brightness.
AdvanceClock(base::Seconds(9));
// Login
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
// Wait for a period of time, then send another brightness event
int seconds_to_wait = 5;
AdvanceClock(base::Seconds(seconds_to_wait));
keyboard_brightness_control_delegate()->HandleSetKeyboardBrightness(
50, true, KeyboardBrightnessChangeSource::kSettingsApp);
// Expect a record with the number of seconds since login, not since the
// beginning of the login screen.
histogram_tester_->ExpectTimeBucketCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"SetBrightness.ChargerPower",
base::Seconds(seconds_to_wait), 1);
}
TEST_F(KeyboardBrightnessControllerTest,
HistogramTest_BrightnessChangeAfterLogin_LongDuration) {
// Metric count should start at 0.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"IncreaseBrightness.BatteryPower",
0);
// Start on the login screen
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOGIN_PRIMARY);
// "Unplug" the charger
SetBatteryPower();
// Wait for a period of time, but don't change brightness.
AdvanceClock(base::Seconds(20));
// Login
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
// Wait for a period of time, then send another brightness event
int minutes_to_wait = 35;
AdvanceClock(base::Minutes(minutes_to_wait));
keyboard_brightness_control_delegate()->HandleKeyboardBrightnessUp();
// Expect a record with the number of minutes since login, not since the
// beginning of the login screen.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"IncreaseBrightness.BatteryPower",
1);
histogram_tester_->ExpectTimeBucketCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"IncreaseBrightness.BatteryPower",
base::Minutes(minutes_to_wait), 1);
}
TEST_F(KeyboardBrightnessControllerTest,
HistogramTest_BrightnessChangeAfterLogin_DurationGreaterThanOneHour) {
// Start on the login screen
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOGIN_PRIMARY);
// "Unplug" the charger
SetBatteryPower();
// Wait for a period of time, but don't change brightness.
AdvanceClock(base::Seconds(1));
// Login
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::ACTIVE);
// Wait for > 1 hour, then send a brightness event.
AdvanceClock(base::Hours(1) + base::Minutes(5));
keyboard_brightness_control_delegate()->HandleKeyboardBrightnessUp();
// Since the brightness event occurred >1 hour after login, don't record it.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"IncreaseBrightness.BatteryPower",
0);
}
TEST_F(KeyboardBrightnessControllerTest,
HistogramTest_SetBrightnessAfterSystemRestoration) {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableKeyboardBacklightControlInSettings);
// Start on the login screen
GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOGIN_PRIMARY);
SetBatteryPower();
// Metrics count should start at 0, both OnLogin and AfterLogin.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLogin."
"SetBrightness.BatteryPower",
0);
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"SetBrightness.BatteryPower",
0);
// Log in
ClearLogin();
AccountId account_id = AccountId::FromUserEmail(kUserEmail);
user_manager::KnownUser known_user(local_state());
SimulateUserLogin(kUserEmail);
// Set keyboard brightness.
known_user.SetPath(account_id, prefs::kKeyboardBrightnessPercent,
std::make_optional<base::Value>(30.0));
// Simulate reboot, brightness should be restored.
login_data_dispatcher()->NotifyFocusPod(account_id);
// Verify that system restoring brightness is not recorded.
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.OnLogin."
"SetBrightness.BatteryPower",
0);
histogram_tester_->ExpectTotalCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"SetBrightness.BatteryPower",
0);
// Wait and then simulate a user-initiated brightness change.
int seconds_to_wait = 5;
AdvanceClock(base::Seconds(seconds_to_wait));
keyboard_brightness_control_delegate()->HandleSetKeyboardBrightness(
50, true, KeyboardBrightnessChangeSource::kSettingsApp);
// Verify that the user-initiated brightness change is recorded.
histogram_tester_->ExpectTimeBucketCount(
"ChromeOS.Keyboard.TimeUntilFirstBrightnessChange.AfterLogin."
"SetBrightness.BatteryPower",
base::Seconds(seconds_to_wait), 1);
}
} // namespace ash