-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GM3][Panorama] Connect Color Scheme Mode Selector to ThemeService
* Create page handler for CustomizeColorSchemeMode that can set the color scheme and get the color scheme whenever theme is changed. There is also a method for initializing to force a SetColorSchemeMode to be sent to the client. * Create unit tests for the page handler. * Connect the component to the page handler. * Create browser tests for the component. Context: This is for a UI button that allows the user to set light/dark mode for the browser (or system mode to follow the OS setting). The handler is calling a ThemeService method that sets a pref and notifies observers that there has been a theme change and another one that gets the current value of that same pref. Bug: 1445804 Change-Id: Iaeda2f4c25167b967bf2c2fd009835b663c1c613 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4582248 Reviewed-by: John Lee <johntlee@chromium.org> Reviewed-by: Tibor Goldschwendt <tiborg@chromium.org> Commit-Queue: Riley Tatum <rtatum@google.com> Reviewed-by: Alex Gough <ajgo@chromium.org> Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com> Cr-Commit-Position: refs/heads/main@{#1153700}
- Loading branch information
Riley Tatum
authored and
Chromium LUCI CQ
committed
Jun 6, 2023
1 parent
a39f599
commit 41f429d
Showing
16 changed files
with
493 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
chrome/browser/ui/webui/cr_components/customize_color_scheme_mode/OWNERS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
file://chrome/browser/ui/webui/new_tab_page/OWNERS |
49 changes: 49 additions & 0 deletions
49
...ui/webui/cr_components/customize_color_scheme_mode/customize_color_scheme_mode_handler.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/ui/webui/cr_components/customize_color_scheme_mode/customize_color_scheme_mode_handler.h" | ||
|
||
#include "chrome/browser/profiles/profile.h" | ||
#include "chrome/browser/themes/theme_service.h" | ||
#include "chrome/browser/themes/theme_service_factory.h" | ||
#include "ui/webui/resources/cr_components/customize_color_scheme_mode/customize_color_scheme_mode.mojom.h" | ||
|
||
CustomizeColorSchemeModeHandler::CustomizeColorSchemeModeHandler( | ||
mojo::PendingRemote< | ||
customize_color_scheme_mode::mojom::CustomizeColorSchemeModeClient> | ||
pending_client, | ||
mojo::PendingReceiver< | ||
customize_color_scheme_mode::mojom::CustomizeColorSchemeModeHandler> | ||
pending_handler, | ||
Profile* profile) | ||
: remote_client_(std::move(pending_client)), | ||
receiver_(this, std::move(pending_handler)), | ||
theme_service_(ThemeServiceFactory::GetForProfile(profile)) { | ||
CHECK(theme_service_); | ||
theme_service_->AddObserver(this); | ||
} | ||
|
||
CustomizeColorSchemeModeHandler::~CustomizeColorSchemeModeHandler() { | ||
theme_service_->RemoveObserver(this); | ||
} | ||
|
||
void CustomizeColorSchemeModeHandler::SetColorSchemeMode( | ||
customize_color_scheme_mode::mojom::ColorSchemeMode colorMode) { | ||
theme_service_->SetBrowserColorScheme( | ||
static_cast<ThemeService::BrowserColorScheme>(colorMode)); | ||
} | ||
|
||
void CustomizeColorSchemeModeHandler::InitializeColorSchemeMode() { | ||
CustomizeColorSchemeModeHandler::UpdateColorSchemeMode(); | ||
} | ||
|
||
void CustomizeColorSchemeModeHandler::OnThemeChanged() { | ||
CustomizeColorSchemeModeHandler::UpdateColorSchemeMode(); | ||
} | ||
|
||
void CustomizeColorSchemeModeHandler::UpdateColorSchemeMode() { | ||
remote_client_->SetColorSchemeMode( | ||
static_cast<customize_color_scheme_mode::mojom::ColorSchemeMode>( | ||
theme_service_->GetBrowserColorScheme())); | ||
} |
53 changes: 53 additions & 0 deletions
53
.../ui/webui/cr_components/customize_color_scheme_mode/customize_color_scheme_mode_handler.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_UI_WEBUI_CR_COMPONENTS_CUSTOMIZE_COLOR_SCHEME_MODE_CUSTOMIZE_COLOR_SCHEME_MODE_HANDLER_H_ | ||
#define CHROME_BROWSER_UI_WEBUI_CR_COMPONENTS_CUSTOMIZE_COLOR_SCHEME_MODE_CUSTOMIZE_COLOR_SCHEME_MODE_HANDLER_H_ | ||
|
||
#include "base/memory/raw_ptr.h" | ||
#include "chrome/browser/themes/theme_service_observer.h" | ||
#include "mojo/public/cpp/bindings/receiver.h" | ||
#include "mojo/public/cpp/bindings/remote.h" | ||
#include "ui/webui/resources/cr_components/customize_color_scheme_mode/customize_color_scheme_mode.mojom.h" | ||
|
||
class Profile; | ||
class ThemeService; | ||
|
||
class CustomizeColorSchemeModeHandler | ||
: public customize_color_scheme_mode::mojom:: | ||
CustomizeColorSchemeModeHandler, | ||
public ThemeServiceObserver { | ||
public: | ||
explicit CustomizeColorSchemeModeHandler( | ||
mojo::PendingRemote< | ||
customize_color_scheme_mode::mojom::CustomizeColorSchemeModeClient> | ||
pending_client, | ||
mojo::PendingReceiver< | ||
customize_color_scheme_mode::mojom::CustomizeColorSchemeModeHandler> | ||
pending_handler, | ||
Profile* profile); | ||
~CustomizeColorSchemeModeHandler() override; | ||
|
||
// customize_color_scheme_mode::mojom::CustomizeColorSchemeModeHandler: | ||
void SetColorSchemeMode( | ||
customize_color_scheme_mode::mojom::ColorSchemeMode colorMode) override; | ||
void InitializeColorSchemeMode() override; | ||
|
||
// ThemeServiceObserver: | ||
void OnThemeChanged() override; | ||
|
||
private: | ||
void UpdateColorSchemeMode(); | ||
|
||
mojo::Remote< | ||
customize_color_scheme_mode::mojom::CustomizeColorSchemeModeClient> | ||
remote_client_; | ||
mojo::Receiver< | ||
customize_color_scheme_mode::mojom::CustomizeColorSchemeModeHandler> | ||
receiver_; | ||
|
||
const raw_ptr<ThemeService> theme_service_; | ||
}; | ||
|
||
#endif // CHROME_BROWSER_UI_WEBUI_CR_COMPONENTS_CUSTOMIZE_COLOR_SCHEME_MODE_CUSTOMIZE_COLOR_SCHEME_MODE_HANDLER_H_ |
161 changes: 161 additions & 0 deletions
161
...cr_components/customize_color_scheme_mode/customize_color_scheme_mode_handler_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/ui/webui/cr_components/customize_color_scheme_mode/customize_color_scheme_mode_handler.h" | ||
|
||
#include "base/memory/raw_ptr.h" | ||
#include "chrome/browser/themes/theme_service.h" | ||
#include "chrome/browser/themes/theme_service_factory.h" | ||
#include "chrome/test/base/testing_profile.h" | ||
#include "components/keyed_service/core/keyed_service.h" | ||
#include "content/public/browser/web_contents.h" | ||
#include "content/public/test/browser_task_environment.h" | ||
#include "content/public/test/test_web_contents_factory.h" | ||
#include "mojo/public/cpp/bindings/pending_receiver.h" | ||
#include "mojo/public/cpp/bindings/pending_remote.h" | ||
#include "testing/gmock/include/gmock/gmock.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
#include "ui/webui/resources/cr_components/customize_color_scheme_mode/customize_color_scheme_mode.mojom.h" | ||
|
||
namespace content { | ||
class BrowserContext; | ||
} // namespace content | ||
|
||
namespace { | ||
|
||
using testing::_; | ||
|
||
class MockClient : public customize_color_scheme_mode::mojom:: | ||
CustomizeColorSchemeModeClient { | ||
public: | ||
MockClient() = default; | ||
~MockClient() override = default; | ||
|
||
mojo::PendingRemote< | ||
customize_color_scheme_mode::mojom::CustomizeColorSchemeModeClient> | ||
BindAndGetRemote() { | ||
DCHECK(!receiver_.is_bound()); | ||
return receiver_.BindNewPipeAndPassRemote(); | ||
} | ||
|
||
void FlushForTesting() { receiver_.FlushForTesting(); } | ||
|
||
MOCK_METHOD(void, | ||
SetColorSchemeMode, | ||
(customize_color_scheme_mode::mojom::ColorSchemeMode)); | ||
|
||
mojo::Receiver< | ||
customize_color_scheme_mode::mojom::CustomizeColorSchemeModeClient> | ||
receiver_{this}; | ||
}; | ||
|
||
class MockThemeService : public ThemeService { | ||
public: | ||
MockThemeService() : ThemeService(nullptr, theme_helper_) { set_ready(); } | ||
MOCK_CONST_METHOD0(GetBrowserColorScheme, ThemeService::BrowserColorScheme()); | ||
MOCK_METHOD1(SetBrowserColorScheme, void(ThemeService::BrowserColorScheme)); | ||
MOCK_METHOD1(AddObserver, void(ThemeServiceObserver*)); | ||
|
||
private: | ||
ThemeHelper theme_helper_; | ||
}; | ||
|
||
std::unique_ptr<TestingProfile> MakeTestingProfile() { | ||
TestingProfile::Builder profile_builder; | ||
profile_builder.AddTestingFactory( | ||
ThemeServiceFactory::GetInstance(), | ||
base::BindRepeating([](content::BrowserContext* context) | ||
-> std::unique_ptr<KeyedService> { | ||
return std::make_unique<testing::NiceMock<MockThemeService>>(); | ||
})); | ||
auto profile = profile_builder.Build(); | ||
return profile; | ||
} | ||
} // namespace | ||
|
||
class CustomizeColorSchemeModeHandlerTest : public testing::Test { | ||
public: | ||
CustomizeColorSchemeModeHandlerTest() | ||
: profile_(MakeTestingProfile()), | ||
mock_theme_service_(static_cast<MockThemeService*>( | ||
ThemeServiceFactory::GetForProfile(profile_.get()))) {} | ||
|
||
void SetUp() override { | ||
EXPECT_CALL(mock_theme_service(), AddObserver).Times(1); | ||
handler_ = std::make_unique<CustomizeColorSchemeModeHandler>( | ||
mock_client_.BindAndGetRemote(), | ||
mojo::PendingReceiver<customize_color_scheme_mode::mojom:: | ||
CustomizeColorSchemeModeHandler>(), | ||
profile_.get()); | ||
mock_client_.FlushForTesting(); | ||
} | ||
|
||
TestingProfile& profile() { return *profile_; } | ||
CustomizeColorSchemeModeHandler& handler() { return *handler_; } | ||
MockThemeService& mock_theme_service() { return *mock_theme_service_; } | ||
|
||
protected: | ||
testing::NiceMock<MockClient> mock_client_; | ||
// NOTE: The initialization order of these members matters. | ||
content::BrowserTaskEnvironment task_environment_; | ||
std::unique_ptr<TestingProfile> profile_; | ||
raw_ptr<MockThemeService> mock_theme_service_; | ||
std::unique_ptr<CustomizeColorSchemeModeHandler> handler_; | ||
}; | ||
|
||
TEST_F(CustomizeColorSchemeModeHandlerTest, InitializeColorSchemeMode) { | ||
ON_CALL(mock_theme_service(), GetBrowserColorScheme) | ||
.WillByDefault(testing::Return(ThemeService::BrowserColorScheme::kLight)); | ||
|
||
customize_color_scheme_mode::mojom::ColorSchemeMode color_scheme_mode; | ||
EXPECT_CALL(mock_client_, SetColorSchemeMode) | ||
.Times(1) | ||
.WillOnce(testing::Invoke( | ||
[&color_scheme_mode]( | ||
customize_color_scheme_mode::mojom::ColorSchemeMode arg) { | ||
color_scheme_mode = std::move(arg); | ||
})); | ||
|
||
handler().InitializeColorSchemeMode(); | ||
mock_client_.FlushForTesting(); | ||
|
||
EXPECT_EQ(color_scheme_mode, | ||
customize_color_scheme_mode::mojom::ColorSchemeMode::kLight); | ||
} | ||
|
||
TEST_F(CustomizeColorSchemeModeHandlerTest, OnThemeChanged) { | ||
ON_CALL(mock_theme_service(), GetBrowserColorScheme) | ||
.WillByDefault(testing::Return(ThemeService::BrowserColorScheme::kLight)); | ||
|
||
customize_color_scheme_mode::mojom::ColorSchemeMode color_scheme_mode; | ||
EXPECT_CALL(mock_client_, SetColorSchemeMode) | ||
.Times(1) | ||
.WillOnce(testing::Invoke( | ||
[&color_scheme_mode]( | ||
customize_color_scheme_mode::mojom::ColorSchemeMode arg) { | ||
color_scheme_mode = std::move(arg); | ||
})); | ||
|
||
handler().OnThemeChanged(); | ||
mock_client_.FlushForTesting(); | ||
|
||
EXPECT_EQ(color_scheme_mode, | ||
customize_color_scheme_mode::mojom::ColorSchemeMode::kLight); | ||
} | ||
|
||
TEST_F(CustomizeColorSchemeModeHandlerTest, SetColorSchemeMode) { | ||
ThemeService::BrowserColorScheme color_scheme_mode; | ||
EXPECT_CALL(mock_theme_service(), SetBrowserColorScheme) | ||
.Times(1) | ||
.WillOnce(testing::Invoke( | ||
[&color_scheme_mode](ThemeService::BrowserColorScheme arg) { | ||
color_scheme_mode = std::move(arg); | ||
})); | ||
|
||
handler().SetColorSchemeMode( | ||
customize_color_scheme_mode::mojom::ColorSchemeMode::kLight); | ||
mock_client_.FlushForTesting(); | ||
|
||
EXPECT_EQ(color_scheme_mode, ThemeService::BrowserColorScheme::kLight); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
chrome/test/data/webui/cr_components/customize_color_scheme_mode_test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import 'chrome://webui-test/mojo_webui_test_support.js'; | ||
|
||
import {CustomizeColorSchemeModeBrowserProxy} from 'chrome://resources/cr_components/customize_color_scheme_mode/browser_proxy.js'; | ||
import {ColorSchemeModeOption, colorSchemeModeOptions, CustomizeColorSchemeModeElement} from 'chrome://resources/cr_components/customize_color_scheme_mode/customize_color_scheme_mode.js'; | ||
import {ColorSchemeMode, CustomizeColorSchemeModeClientCallbackRouter, CustomizeColorSchemeModeClientRemote, CustomizeColorSchemeModeHandlerRemote} from 'chrome://resources/cr_components/customize_color_scheme_mode/customize_color_scheme_mode.mojom-webui.js'; | ||
import {assertEquals} from 'chrome://webui-test/chai_assert.js'; | ||
import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; | ||
import {TestMock} from 'chrome://webui-test/test_mock.js'; | ||
|
||
suite('CrComponentsCustomizeColorSchemeModeTest', () => { | ||
let handler: TestMock<CustomizeColorSchemeModeHandlerRemote>& | ||
CustomizeColorSchemeModeHandlerRemote; | ||
let callbackRouter: CustomizeColorSchemeModeClientRemote; | ||
|
||
setup(() => { | ||
document.body.innerHTML = window.trustedTypes!.emptyHTML; | ||
handler = TestMock.fromClass(CustomizeColorSchemeModeHandlerRemote); | ||
CustomizeColorSchemeModeBrowserProxy.setInstance( | ||
handler, new CustomizeColorSchemeModeClientCallbackRouter()); | ||
callbackRouter = CustomizeColorSchemeModeBrowserProxy.getInstance() | ||
.callbackRouter.$.bindNewPipeAndPassRemote(); | ||
}); | ||
|
||
async function initializeElement(colorSchemeMode: ColorSchemeMode): | ||
Promise<CustomizeColorSchemeModeElement> { | ||
const element = new CustomizeColorSchemeModeElement(); | ||
callbackRouter.setColorSchemeMode(colorSchemeMode); | ||
document.body.appendChild(element); | ||
await waitAfterNextRender(element); | ||
return element; | ||
} | ||
|
||
colorSchemeModeOptions.forEach((mode: ColorSchemeModeOption) => { | ||
test(`Set ${mode.name} on initialization`, async () => { | ||
// Arrange. | ||
const element = await initializeElement(mode.value); | ||
|
||
// Assert. | ||
// Check that the correct option is checked and the other aren't. | ||
colorSchemeModeOptions.forEach((innerMode: ColorSchemeModeOption) => { | ||
const checked = innerMode.id === mode.id; | ||
assertEquals( | ||
element.shadowRoot! | ||
.querySelector(`cr-segmented-button-option[name="${ | ||
innerMode.id}"]`)!.hasAttribute('checked'), | ||
checked); | ||
}); | ||
}); | ||
|
||
test(`Click ${mode.name} sets scheme mode`, async () => { | ||
// Arrange. | ||
const element = await initializeElement(mode.value); | ||
|
||
// Action. | ||
const option = | ||
element.shadowRoot!.querySelector( | ||
`cr-segmented-button-option[name="${mode.id}"]`)! as HTMLElement; | ||
option.click(); | ||
|
||
// Assert. | ||
assertEquals(1, handler.getCallCount('setColorSchemeMode')); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.