Skip to content

Commit

Permalink
personalization: set keyboard backlight color upon login
Browse files Browse the repository at this point in the history
Create KeyboardBacklightColorController to hold the logic of setting
the user's selected keyboard backlight color after login. Also observe
when the wallpaper extracted color changes to set the keyboard color
when appropriate.

The pref registration is moved from personalization_app_prefs to this
controller for logic isolation.

The color sequence from booting up would be:
1. Use the wallpaper extracted color when available.
2. After the user logs in, use their saved pref.

BUG=b/230519831
TEST=ash_unittests
--gtest_filter="*KeyboardBacklightColorControllerTest*"
TEST=unit_tests
--gtest_filter="*PersonalizationAppKeyboardBacklightProviderImplTest.*"

Cq-Include-Trybots: luci.chrome.try:linux-chromeos-chrome
Change-Id: I702163077ad54424b1411022d548e0af05f4c275
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3631712
Commit-Queue: Jason Thai <jasontt@chromium.org>
Reviewed-by: James Cook <jamescook@chromium.org>
Reviewed-by: Xiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1001666}
  • Loading branch information
Jason Thai authored and Chromium LUCI CQ committed May 10, 2022
1 parent 173a31e commit e367085
Show file tree
Hide file tree
Showing 13 changed files with 287 additions and 83 deletions.
3 changes: 3 additions & 0 deletions ash/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,8 @@ component("ash") {
"system/ime_menu/ime_list_view.h",
"system/ime_menu/ime_menu_tray.cc",
"system/ime_menu/ime_menu_tray.h",
"system/keyboard_brightness/keyboard_backlight_color_controller.cc",
"system/keyboard_brightness/keyboard_backlight_color_controller.h",
"system/keyboard_brightness/keyboard_backlight_toggle_controller.cc",
"system/keyboard_brightness/keyboard_backlight_toggle_controller.h",
"system/keyboard_brightness/keyboard_brightness_controller.cc",
Expand Down Expand Up @@ -2707,6 +2709,7 @@ test("ash_unittests") {
"system/human_presence/snooping_protection_notification_blocker_unittest.cc",
"system/ime/ime_feature_pod_controller_unittest.cc",
"system/ime_menu/ime_menu_tray_unittest.cc",
"system/keyboard_brightness/keyboard_backlight_color_controller_unittest.cc",
"system/locale/locale_feature_pod_controller_unittest.cc",
"system/machine_learning/user_settings_event_logger_unittest.cc",
"system/media/media_notification_provider_impl_unittest.cc",
Expand Down
2 changes: 2 additions & 0 deletions ash/ash_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "ash/system/caps_lock_notification_controller.h"
#include "ash/system/gesture_education/gesture_education_notification_controller.h"
#include "ash/system/human_presence/snooping_protection_controller.h"
#include "ash/system/keyboard_brightness/keyboard_backlight_color_controller.h"
#include "ash/system/media/media_tray.h"
#include "ash/system/message_center/message_center_controller.h"
#include "ash/system/network/cellular_setup_notifier.h"
Expand Down Expand Up @@ -91,6 +92,7 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry, bool for_test) {
LoginScreenController::RegisterProfilePrefs(registry, for_test);
LogoutButtonTray::RegisterProfilePrefs(registry);
LogoutConfirmationController::RegisterProfilePrefs(registry);
KeyboardBacklightColorController::RegisterProfilePrefs(registry);
KeyboardControllerImpl::RegisterProfilePrefs(registry);
MediaControllerImpl::RegisterProfilePrefs(registry);
MessageCenterController::RegisterProfilePrefs(registry);
Expand Down
9 changes: 9 additions & 0 deletions ash/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
#include "ash/system/geolocation/geolocation_controller.h"
#include "ash/system/human_presence/human_presence_orientation_controller.h"
#include "ash/system/human_presence/snooping_protection_controller.h"
#include "ash/system/keyboard_brightness/keyboard_backlight_color_controller.h"
#include "ash/system/keyboard_brightness/keyboard_brightness_controller.h"
#include "ash/system/keyboard_brightness_control_delegate.h"
#include "ash/system/locale/locale_update_controller_impl.h"
Expand Down Expand Up @@ -820,6 +821,7 @@ Shell::~Shell() {
display_configuration_controller_.reset();

// Needs to be destructed before `ime_controler_`.
keyboard_backlight_color_controller_.reset();
rgb_keyboard_manager_.reset();

// These members access Shell in their destructors.
Expand Down Expand Up @@ -1071,6 +1073,13 @@ void Shell::Init(

wallpaper_controller_ = WallpaperControllerImpl::Create(local_state_);

if (features::IsRgbKeyboardEnabled()) {
// Initialized after |wallpaper_controller_| because we will need to observe
// when the extracted wallpaper color changes.
keyboard_backlight_color_controller_ =
std::make_unique<KeyboardBacklightColorController>();
}

window_positioner_ = std::make_unique<WindowPositioner>();

native_cursor_manager_ = new NativeCursorManagerAsh;
Expand Down
6 changes: 6 additions & 0 deletions ash/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ class HumanPresenceOrientationController;
class ImeControllerImpl;
class WebAuthNDialogControllerImpl;
class KeyAccessibilityEnabler;
class KeyboardBacklightColorController;
class KeyboardBrightnessControlDelegate;
class KeyboardControllerImpl;
class LaserPointerController;
Expand Down Expand Up @@ -460,6 +461,9 @@ class ASH_EXPORT Shell : public SessionObserver,
KeyAccessibilityEnabler* key_accessibility_enabler() {
return key_accessibility_enabler_.get();
}
KeyboardBacklightColorController* keyboard_backlight_color_controller() {
return keyboard_backlight_color_controller_.get();
}
KeyboardBrightnessControlDelegate* keyboard_brightness_control_delegate() {
return keyboard_brightness_control_delegate_.get();
}
Expand Down Expand Up @@ -796,6 +800,8 @@ class ASH_EXPORT Shell : public SessionObserver,
std::unique_ptr<ImeControllerImpl> ime_controller_;
std::unique_ptr<chromeos::ImmersiveContext> immersive_context_;
std::unique_ptr<WebAuthNDialogControllerImpl> webauthn_dialog_controller_;
std::unique_ptr<KeyboardBacklightColorController>
keyboard_backlight_color_controller_;
std::unique_ptr<KeyboardBrightnessControlDelegate>
keyboard_brightness_control_delegate_;
std::unique_ptr<LocaleUpdateControllerImpl> locale_update_controller_;
Expand Down
116 changes: 116 additions & 0 deletions ash/system/keyboard_brightness/keyboard_backlight_color_controller.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright 2022 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/keyboard_brightness/keyboard_backlight_color_controller.h"

#include "ash/constants/ash_pref_names.h"
#include "ash/public/cpp/wallpaper/wallpaper_controller.h"
#include "ash/rgb_keyboard/rgb_keyboard_manager.h"
#include "ash/rgb_keyboard/rgb_keyboard_util.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/wallpaper/wallpaper_controller_impl.h"
#include "ash/webui/personalization_app/mojom/personalization_app.mojom.h"
#include "base/check_op.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/color_analysis.h"

namespace ash {

namespace {

PrefService* GetActivePrefService() {
return Shell::Get()->session_controller()->GetActivePrefService();
}

} // namespace

KeyboardBacklightColorController::KeyboardBacklightColorController() {
wallpaper_controller_observation_.Observe(WallpaperController::Get());
}

KeyboardBacklightColorController::~KeyboardBacklightColorController() = default;

// static
void KeyboardBacklightColorController::RegisterProfilePrefs(
PrefRegistrySimple* registry) {
registry->RegisterIntegerPref(
prefs::kPersonalizationKeyboardBacklightColor,
static_cast<int>(personalization_app::mojom::BacklightColor::kWallpaper));
}

void KeyboardBacklightColorController::SetBacklightColor(
personalization_app::mojom::BacklightColor backlight_color) {
auto* rgb_keyboard_manager = Shell::Get()->rgb_keyboard_manager();
DCHECK(rgb_keyboard_manager);
DVLOG(3) << __func__ << " backlight_color=" << backlight_color;
switch (backlight_color) {
case personalization_app::mojom::BacklightColor::kWallpaper: {
auto* wallpaper_controller = Shell::Get()->wallpaper_controller();
DCHECK(wallpaper_controller);
SkColor color = wallpaper_controller->GetProminentColor(
color_utils::ColorProfile(color_utils::LumaRange::NORMAL,
color_utils::SaturationRange::VIBRANT));
rgb_keyboard_manager->SetStaticBackgroundColor(
SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
break;
}
case personalization_app::mojom::BacklightColor::kWhite:
case personalization_app::mojom::BacklightColor::kRed:
case personalization_app::mojom::BacklightColor::kYellow:
case personalization_app::mojom::BacklightColor::kGreen:
case personalization_app::mojom::BacklightColor::kBlue:
case personalization_app::mojom::BacklightColor::kIndigo:
case personalization_app::mojom::BacklightColor::kPurple: {
SkColor color = ConvertBacklightColorToSkColor(backlight_color);
rgb_keyboard_manager->SetStaticBackgroundColor(
SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
break;
}
case personalization_app::mojom::BacklightColor::kRainbow:
rgb_keyboard_manager->SetRainbowMode();
break;
}

GetActivePrefService()->SetInteger(
prefs::kPersonalizationKeyboardBacklightColor,
static_cast<int>(backlight_color));
}

personalization_app::mojom::BacklightColor
KeyboardBacklightColorController::GetBacklightColor() {
return static_cast<personalization_app::mojom::BacklightColor>(
GetActivePrefService()->GetInteger(
prefs::kPersonalizationKeyboardBacklightColor));
}

void KeyboardBacklightColorController::OnActiveUserSessionChanged(
const AccountId& account_id) {
auto* session_controller = Shell::Get()->session_controller();
DCHECK(session_controller);
PrefService* pref_service =
session_controller->GetUserPrefServiceForUser(account_id);
DCHECK(pref_service);
auto backlight_color =
static_cast<personalization_app::mojom::BacklightColor>(
pref_service->GetInteger(
prefs::kPersonalizationKeyboardBacklightColor));
SetBacklightColor(backlight_color);
}

void KeyboardBacklightColorController::OnWallpaperColorsChanged() {
auto* wallpaper_controller = Shell::Get()->wallpaper_controller();
DCHECK(wallpaper_controller);
auto backlight_color =
static_cast<personalization_app::mojom::BacklightColor>(
GetActivePrefService()->GetInteger(
prefs::kPersonalizationKeyboardBacklightColor));
if (backlight_color != personalization_app::mojom::BacklightColor::kWallpaper)
return;
SetBacklightColor(personalization_app::mojom::BacklightColor::kWallpaper);
}

} // namespace ash
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2022 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_KEYBOARD_BRIGHTNESS_KEYBOARD_BACKLIGHT_COLOR_CONTROLLER_H_
#define ASH_SYSTEM_KEYBOARD_BRIGHTNESS_KEYBOARD_BACKLIGHT_COLOR_CONTROLLER_H_

#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/wallpaper/wallpaper_controller.h"
#include "ash/public/cpp/wallpaper/wallpaper_controller_observer.h"
#include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h"
#include "base/scoped_observation.h"

class PrefRegistrySimple;

namespace ash {

// Controller to manage keyboard backlight colors.
class ASH_EXPORT KeyboardBacklightColorController
: public SessionObserver,
public WallpaperControllerObserver {
public:
KeyboardBacklightColorController();

KeyboardBacklightColorController(const KeyboardBacklightColorController&) =
delete;
KeyboardBacklightColorController& operator=(
const KeyboardBacklightColorController&) = delete;

~KeyboardBacklightColorController() override;

static void RegisterProfilePrefs(PrefRegistrySimple* registry);

// Sets the keyboard backlight color.
void SetBacklightColor(
personalization_app::mojom::BacklightColor backlight_color);

// Returns the currently set backlight color.
personalization_app::mojom::BacklightColor GetBacklightColor();

// SessionObserver:
void OnActiveUserSessionChanged(const AccountId& account_id) override;

// WallpaperControllerObserver:
void OnWallpaperColorsChanged() override;

private:
ScopedSessionObserver scoped_session_observer_{this};

base::ScopedObservation<WallpaperController, WallpaperControllerObserver>
wallpaper_controller_observation_{this};
};

} // namespace ash

#endif // ASH_SYSTEM_KEYBOARD_BRIGHTNESS_KEYBOARD_BACKLIGHT_COLOR_CONTROLLER_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2022 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/keyboard_brightness/keyboard_backlight_color_controller.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/test/scoped_feature_list.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash {

namespace {
constexpr char kUser1[] = "user1@test.com";
const AccountId account_id_1 = AccountId::FromUserEmailGaiaId(kUser1, kUser1);

constexpr char kUser2[] = "user2@test.com";
const AccountId account_id_2 = AccountId::FromUserEmailGaiaId(kUser2, kUser2);
} // namespace

class KeyboardBacklightColorControllerTest : public AshTestBase {
public:
KeyboardBacklightColorControllerTest()
: scoped_feature_list_(features::kRgbKeyboard) {}

KeyboardBacklightColorControllerTest(
const KeyboardBacklightColorControllerTest&) = delete;
KeyboardBacklightColorControllerTest& operator=(
const KeyboardBacklightColorControllerTest&) = delete;

~KeyboardBacklightColorControllerTest() override = default;

// testing::Test:
void SetUp() override {
AshTestBase::SetUp();

controller_ = Shell::Get()->keyboard_backlight_color_controller();
}

protected:
KeyboardBacklightColorController* controller_ = nullptr;

private:
base::test::ScopedFeatureList scoped_feature_list_;
};

TEST_F(KeyboardBacklightColorControllerTest, SetBacklightColorUpdatesPref) {
controller_->SetBacklightColor(
personalization_app::mojom::BacklightColor::kBlue);

PrefService* prefs_service =
Shell::Get()->session_controller()->GetActivePrefService();
EXPECT_EQ(personalization_app::mojom::BacklightColor::kBlue,
static_cast<personalization_app::mojom::BacklightColor>(
prefs_service->GetInteger(
prefs::kPersonalizationKeyboardBacklightColor)));
}

TEST_F(KeyboardBacklightColorControllerTest, SetBacklightColorAfterSignin) {
// Verify the user starts with wallpaper-extracted color.
SimulateUserLogin(account_id_1);
EXPECT_EQ(personalization_app::mojom::BacklightColor::kWallpaper,
controller_->GetBacklightColor());
controller_->SetBacklightColor(
personalization_app::mojom::BacklightColor::kRainbow);
EXPECT_EQ(personalization_app::mojom::BacklightColor::kRainbow,
controller_->GetBacklightColor());

// Simulate login for user2.
SimulateUserLogin(account_id_2);
EXPECT_EQ(personalization_app::mojom::BacklightColor::kWallpaper,
controller_->GetBacklightColor());

SimulateUserLogin(account_id_1);
EXPECT_EQ(personalization_app::mojom::BacklightColor::kRainbow,
controller_->GetBacklightColor());
}

} // namespace ash

0 comments on commit e367085

Please sign in to comment.