blob: 3eff1f396633dc89e21dd50bacff8de5fe84446f [file] [log] [blame]
// Copyright 2022 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/accessibility/page_colors.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "ui/native_theme/native_theme.h"
PageColors::PageColors(PrefService* profile_prefs)
: profile_prefs_(profile_prefs) {
theme_observation_.Observe(ui::NativeTheme::GetInstanceForNativeUi());
}
PageColors::~PageColors() = default;
// static
void PageColors::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterIntegerPref(
prefs::kPageColors,
/*default_value=*/ui::NativeTheme::PageColors::kOff);
registry->RegisterBooleanPref(prefs::kApplyPageColorsOnlyOnIncreasedContrast,
/*default_value=*/false);
registry->RegisterListPref(prefs::kPageColorsBlockList);
#if BUILDFLAG(IS_WIN)
registry->RegisterBooleanPref(prefs::kIsDefaultPageColorsOnHighContrast,
/*default_value=*/true);
#endif // BUILDFLAG(IS_WIN)
}
void PageColors::Init() {
pref_change_registrar_.Init(profile_prefs_);
pref_change_registrar_.Add(
prefs::kPageColors, base::BindRepeating(&PageColors::OnPageColorsChanged,
weak_factory_.GetWeakPtr()));
pref_change_registrar_.Add(
prefs::kApplyPageColorsOnlyOnIncreasedContrast,
base::BindRepeating(&PageColors::OnPageColorsChanged,
weak_factory_.GetWeakPtr()));
#if BUILDFLAG(IS_WIN)
profile_prefs_->SetBoolean(prefs::kApplyPageColorsOnlyOnIncreasedContrast,
true);
#endif // BUILDFLAG(IS_WIN)
OnPreferredContrastChanged();
}
void PageColors::OnPageColorsChanged() {
auto* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
ui::NativeTheme::PageColors previous_page_colors =
native_theme->GetPageColors();
ui::NativeTheme::PageColors current_page_colors = CalculatePageColors();
if (previous_page_colors == current_page_colors)
return;
#if BUILDFLAG(IS_WIN)
if (native_theme->UserHasContrastPreference()) {
// When a user turns page colors 'Off' while high contrast is enabled at the
// OS level, the default of Page Colors changes from 'HighContrast' to
// 'Off'.
profile_prefs_->SetBoolean(
prefs::kIsDefaultPageColorsOnHighContrast,
current_page_colors != ui::NativeTheme::PageColors::kOff);
}
#endif // BUILDFLAG(IS_WIN)
native_theme->set_page_colors(current_page_colors);
native_theme->NotifyOnNativeThemeUpdated();
}
ui::NativeTheme::PageColors PageColors::CalculatePageColors() {
auto* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
ui::NativeTheme::PageColors page_colors =
static_cast<ui::NativeTheme::PageColors>(
profile_prefs_->GetInteger(prefs::kPageColors));
// Validating the page colors variable.
DCHECK_GE(page_colors, ui::NativeTheme::PageColors::kOff);
DCHECK_LE(page_colors, ui::NativeTheme::PageColors::kMaxValue);
bool only_on_increased_contrast = profile_prefs_->GetBoolean(
prefs::kApplyPageColorsOnlyOnIncreasedContrast);
ui::NativeTheme::PageColors used_page_colors = page_colors;
// The used value of Page Colors should be 'Off' if
// kApplyPageColorsOnlyOnIncreasedContrast is true and the OS is not in an
// increased contrast mode.
if (only_on_increased_contrast &&
!native_theme->UserHasContrastPreference()) {
used_page_colors = ui::NativeTheme::PageColors::kOff;
}
return used_page_colors;
}
void PageColors::OnPreferredContrastChanged() {
#if BUILDFLAG(IS_WIN)
ui::NativeTheme::PageColors page_colors =
static_cast<ui::NativeTheme::PageColors>(
profile_prefs_->GetInteger(prefs::kPageColors));
// Validating the page colors variable.
DCHECK_GE(page_colors, ui::NativeTheme::PageColors::kOff);
DCHECK_LE(page_colors, ui::NativeTheme::PageColors::kMaxValue);
auto* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
if (native_theme->UserHasContrastPreference()) {
// If increased contrast just got turned on and page colors is 'Off', the
// used value of Page Colors should be set to the default value which is
// either 'Off' or 'High Contrast'.
if (page_colors == ui::NativeTheme::PageColors::kOff) {
ui::NativeTheme::PageColors default_page_colors_on_high_contrast =
profile_prefs_->GetBoolean(prefs::kIsDefaultPageColorsOnHighContrast)
? ui::NativeTheme::PageColors::kHighContrast
: ui::NativeTheme::PageColors::kOff;
profile_prefs_->SetInteger(prefs::kPageColors,
default_page_colors_on_high_contrast);
}
} else {
// If increased contrast just got turned off and page colors was 'High
// Contrast', the used value of Page Colors should be 'Off'.
if (page_colors == ui::NativeTheme::PageColors::kHighContrast)
profile_prefs_->SetInteger(prefs::kPageColors,
ui::NativeTheme::PageColors::kOff);
}
#endif // BUILDFLAG(IS_WIN)
OnPageColorsChanged();
}