diff --git a/android/java/org/chromium/chrome/browser/settings/AppearancePreferences.java b/android/java/org/chromium/chrome/browser/settings/AppearancePreferences.java index cc67a2ff2a9..09c40960d9d 100644 --- a/android/java/org/chromium/chrome/browser/settings/AppearancePreferences.java +++ b/android/java/org/chromium/chrome/browser/settings/AppearancePreferences.java @@ -7,7 +7,6 @@ package org.chromium.chrome.browser.settings; import static org.chromium.chrome.browser.settings.MainSettings.PREF_UI_THEME; -import android.content.SharedPreferences; import android.os.Bundle; import androidx.preference.Preference; @@ -161,7 +160,8 @@ public class AppearancePreferences extends BravePreferenceFragment ((ChromeSwitchPreference) enableSpeedreader) .setChecked( UserPrefs.get(ProfileManager.getLastUsedRegularProfile()) - .getBoolean(BravePref.SPEEDREADER_PREF_ENABLED)); + .getBoolean( + BravePref.SPEEDREADER_PREF_ENABLED_FOR_ALL_SITES)); } } @@ -250,21 +250,17 @@ public class AppearancePreferences extends BravePreferenceFragment String key = preference.getKey(); boolean shouldRelaunch = false; if (BravePreferenceKeys.BRAVE_BOTTOM_TOOLBAR_ENABLED_KEY.equals(key)) { - SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); Boolean originalStatus = BottomToolbarConfiguration.isBraveBottomControlsEnabled(); updatePreferenceSummary( BravePreferenceKeys.BRAVE_BOTTOM_TOOLBAR_ENABLED_KEY, !originalStatus ? R.string.text_on : R.string.text_off); - prefs.edit() - .putBoolean( - BravePreferenceKeys.BRAVE_BOTTOM_TOOLBAR_ENABLED_KEY, !originalStatus) - .apply(); + ChromeSharedPreferences.getInstance() + .writeBoolean( + BravePreferenceKeys.BRAVE_BOTTOM_TOOLBAR_ENABLED_KEY, !originalStatus); shouldRelaunch = true; } else if (PREF_SHOW_BRAVE_REWARDS_ICON.equals(key)) { - SharedPreferences sharedPreferences = ContextUtils.getAppSharedPreferences(); - SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit(); - sharedPreferencesEditor.putBoolean(PREF_SHOW_BRAVE_REWARDS_ICON, !(boolean) newValue); - sharedPreferencesEditor.apply(); + ChromeSharedPreferences.getInstance() + .writeBoolean(PREF_SHOW_BRAVE_REWARDS_ICON, !(boolean) newValue); shouldRelaunch = true; } else if (PREF_ADS_SWITCH.equals(key)) { setPrefAdsInBackgroundEnabled((boolean) newValue); @@ -281,7 +277,8 @@ public class AppearancePreferences extends BravePreferenceFragment .writeBoolean(BravePreferenceKeys.BRAVE_TAB_GROUPS_ENABLED, (boolean) newValue); } else if (PREF_BRAVE_ENABLE_SPEEDREADER.equals(key)) { UserPrefs.get(ProfileManager.getLastUsedRegularProfile()) - .setBoolean(BravePref.SPEEDREADER_PREF_ENABLED, (boolean) newValue); + .setBoolean( + BravePref.SPEEDREADER_PREF_ENABLED_FOR_ALL_SITES, (boolean) newValue); shouldRelaunch = true; } else if (PREF_ENABLE_MULTI_WINDOWS.equals(key)) { if (!(boolean) newValue) { @@ -324,16 +321,12 @@ public class AppearancePreferences extends BravePreferenceFragment /** Returns the user preference for whether the brave ads in background is enabled. */ public static boolean getPrefAdsInBackgroundEnabled() { - SharedPreferences sharedPreferences = ContextUtils.getAppSharedPreferences(); - return sharedPreferences.getBoolean(PREF_ADS_SWITCH, false); + return ChromeSharedPreferences.getInstance().readBoolean(PREF_ADS_SWITCH, false); } /** Sets the user preference for whether the brave ads in background is enabled. */ public void setPrefAdsInBackgroundEnabled(boolean enabled) { - SharedPreferences sharedPreferences = ContextUtils.getAppSharedPreferences(); - SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit(); - sharedPreferencesEditor.putBoolean(PREF_ADS_SWITCH, enabled); - sharedPreferencesEditor.apply(); + ChromeSharedPreferences.getInstance().writeBoolean(PREF_ADS_SWITCH, enabled); } private void updatePreferenceIcon(String preferenceString, int drawable) { diff --git a/android/java/org/chromium/chrome/browser/speedreader/BraveSpeedReaderManager.java b/android/java/org/chromium/chrome/browser/speedreader/BraveSpeedReaderManager.java index 4bc990b47b6..b5a6686d598 100644 --- a/android/java/org/chromium/chrome/browser/speedreader/BraveSpeedReaderManager.java +++ b/android/java/org/chromium/chrome/browser/speedreader/BraveSpeedReaderManager.java @@ -169,7 +169,7 @@ public class BraveSpeedReaderManager extends EmptyTabObserver implements UserDat boolean isPrefEnabled = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()) - .getBoolean(BravePref.SPEEDREADER_PREF_ENABLED); + .getBoolean(BravePref.SPEEDREADER_PREF_FEATURE_ENABLED); return isPrefEnabled; } } diff --git a/android/java/org/chromium/chrome/browser/tabbed_mode/BraveTabbedAppMenuPropertiesDelegate.java b/android/java/org/chromium/chrome/browser/tabbed_mode/BraveTabbedAppMenuPropertiesDelegate.java index 5df52a29108..07ebf132083 100644 --- a/android/java/org/chromium/chrome/browser/tabbed_mode/BraveTabbedAppMenuPropertiesDelegate.java +++ b/android/java/org/chromium/chrome/browser/tabbed_mode/BraveTabbedAppMenuPropertiesDelegate.java @@ -321,7 +321,7 @@ public class BraveTabbedAppMenuPropertiesDelegate extends TabbedAppMenuPropertie } if (ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_SPEEDREADER) && UserPrefs.get(assumeNonNull(mTabModelSelector.getCurrentModel().getProfile())) - .getBoolean(BravePref.SPEEDREADER_PREF_ENABLED)) { + .getBoolean(BravePref.SPEEDREADER_PREF_FEATURE_ENABLED)) { final Tab currentTab = mActivityTabProvider.get(); if (currentTab != null && BraveSpeedReaderUtils.tabSupportsDistillation(currentTab)) { addMenuItemAfter( diff --git a/app/brave_settings_strings.grdp b/app/brave_settings_strings.grdp index eb5889362a4..c4f45910376 100644 --- a/app/brave_settings_strings.grdp +++ b/app/brave_settings_strings.grdp @@ -246,10 +246,19 @@ Show tab search button - + Speedreader - + + Speedreader + + + Enable the Speedreader feature + + + Automatically use Speedreader when possible + + Articles automatically load in reader mode, saving you time diff --git a/browser/brave_profile_prefs.cc b/browser/brave_profile_prefs.cc index ad5d2824801..df643276190 100644 --- a/browser/brave_profile_prefs.cc +++ b/browser/brave_profile_prefs.cc @@ -86,6 +86,7 @@ #endif #if BUILDFLAG(ENABLE_SPEEDREADER) +#include "brave/components/speedreader/speedreader_pref_migration.h" #include "brave/components/speedreader/speedreader_service.h" #endif @@ -320,6 +321,11 @@ void RegisterProfilePrefsForMigration( #if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) registry->RegisterBooleanPref(kWebTorrentEnabled, false); #endif + + // Added 2025-08 - Speedreader preference migration +#if BUILDFLAG(ENABLE_SPEEDREADER) + speedreader::RegisterProfilePrefsForMigration(registry); +#endif } void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc index 4e73024ae96..e61a3f46675 100644 --- a/browser/extensions/api/settings_private/brave_prefs_util.cc +++ b/browser/extensions/api/settings_private/brave_prefs_util.cc @@ -166,7 +166,9 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() { settings_api::PrefType::kNumber; #endif #if BUILDFLAG(ENABLE_SPEEDREADER) - (*s_brave_allowlist)[speedreader::kSpeedreaderPrefEnabled] = + (*s_brave_allowlist)[speedreader::kSpeedreaderPrefFeatureEnabled] = + settings_api::PrefType::kBoolean; + (*s_brave_allowlist)[speedreader::kSpeedreaderPrefEnabledForAllSites] = settings_api::PrefType::kBoolean; #endif // De-AMP feature diff --git a/browser/perf/brave_perf_features_processor.cc b/browser/perf/brave_perf_features_processor.cc index e2de33c6519..8db5c796b13 100644 --- a/browser/perf/brave_perf_features_processor.cc +++ b/browser/perf/brave_perf_features_processor.cc @@ -75,8 +75,11 @@ void MaybeEnableBraveFeatureForPerfTesting(Profile* profile) { profile->GetPrefs()->SetBoolean(brave_news::prefs::kBraveNewsOptedIn, true); #if BUILDFLAG(ENABLE_SPEEDREADER) - // Speedreader - profile->GetPrefs()->SetBoolean(speedreader::kSpeedreaderPrefEnabled, true); + // Speedreader - enable both the feature toggle and all-sites setting + profile->GetPrefs()->SetBoolean(speedreader::kSpeedreaderPrefFeatureEnabled, + true); + profile->GetPrefs()->SetBoolean( + speedreader::kSpeedreaderPrefEnabledForAllSites, true); #endif profile->GetPrefs()->SetTime(ai_chat::prefs::kLastAcceptedDisclaimer, diff --git a/browser/resources/settings/brave_content_page/speedreader.html b/browser/resources/settings/brave_content_page/speedreader.html index 53d0617a291..466b86e4f03 100644 --- a/browser/resources/settings/brave_content_page/speedreader.html +++ b/browser/resources/settings/brave_content_page/speedreader.html @@ -5,9 +5,19 @@ You can obtain one at https://mozilla.org/MPL/2.0/. --> + + diff --git a/browser/ui/views/speedreader/speedreader_icon_view.cc b/browser/ui/views/speedreader/speedreader_icon_view.cc index 12ac74a419e..be2d2c7109f 100644 --- a/browser/ui/views/speedreader/speedreader_icon_view.cc +++ b/browser/ui/views/speedreader/speedreader_icon_view.cc @@ -8,6 +8,7 @@ #include #include "brave/app/brave_command_ids.h" +#include "brave/browser/speedreader/speedreader_service_factory.h" #include "brave/browser/speedreader/speedreader_tab_helper.h" #include "brave/browser/ui/color/brave_color_id.h" #include "brave/components/speedreader/common/features.h" @@ -39,6 +40,18 @@ SpeedreaderIconView::SpeedreaderIconView( SpeedreaderIconView::~SpeedreaderIconView() = default; void SpeedreaderIconView::UpdateImpl() { + // Check if Speedreader feature is enabled + auto* web_contents = GetWebContents(); + if (web_contents) { + auto* speedreader_service = + speedreader::SpeedreaderServiceFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + if (!speedreader_service || !speedreader_service->IsFeatureEnabled()) { + SetVisible(false); + return; + } + } + const auto state = GetDistillState(); if (!speedreader::DistillStates::IsDistilled(state) && !speedreader::DistillStates::IsDistillable(state)) { diff --git a/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc b/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc index 220a3a8a9e1..487e97911b2 100644 --- a/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc +++ b/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc @@ -283,8 +283,14 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source, {"autofillInPrivateSettingDesc", IDS_SETTINGS_BRAVE_AUTOFILL_PRIVATE_WINDOWS_DESC}, {"mruCyclingSettingLabel", IDS_SETTINGS_BRAVE_MRU_CYCLING_LABEL}, - {"speedreaderSettingLabel", IDS_SETTINGS_SPEEDREADER_LABEL}, - {"speedreaderSettingSubLabel", IDS_SETTINGS_SPEEDREADER_SUB_LABEL}, + {"speedreaderSettingLabel", IDS_SETTINGS_SPEEDREADER_SETTING_LABEL}, + {"speedreaderFeatureLabel", IDS_SETTINGS_SPEEDREADER_FEATURE_LABEL}, + {"speedreaderFeatureSubLabel", + IDS_SETTINGS_SPEEDREADER_FEATURE_SUB_LABEL}, + {"speedreaderEnabledForAllSitesLabel", + IDS_SETTINGS_SPEEDREADER_ENABLED_FOR_ALL_SITES_LABEL}, + {"speedreaderEnabledForAllSitesSubLabel", + IDS_SETTINGS_SPEEDREADER_ENABLED_FOR_ALL_SITES_SUB_LABEL}, {"deAmpSettingLabel", IDS_SETTINGS_DE_AMP_LABEL}, {"deAmpSettingSubLabel", IDS_SETTINGS_DE_AMP_SUB_LABEL}, {"debounceSettingLabel", IDS_SETTINGS_DEBOUNCE_LABEL}, diff --git a/chromium_src/chrome/browser/prefs/DEPS b/chromium_src/chrome/browser/prefs/DEPS index a4fac2cc2de..bd50aa306c6 100644 --- a/chromium_src/chrome/browser/prefs/DEPS +++ b/chromium_src/chrome/browser/prefs/DEPS @@ -20,6 +20,8 @@ include_rules = [ "+brave/components/omnibox/browser/brave_omnibox_prefs.h", "+brave/components/p3a/metric_log_store.h", "+brave/components/p3a/rotation_scheduler.h", + "+brave/components/speedreader/common/buildflags/buildflags.h", + "+brave/components/speedreader/speedreader_pref_migration.h", "+brave/components/tor/buildflags/buildflags.h", "+brave/components/brave_vpn/common/brave_vpn_utils.h", "+brave/components/tor/pref_names.h", diff --git a/chromium_src/chrome/browser/prefs/browser_prefs.cc b/chromium_src/chrome/browser/prefs/browser_prefs.cc index 714d380457b..72398a8df8a 100644 --- a/chromium_src/chrome/browser/prefs/browser_prefs.cc +++ b/chromium_src/chrome/browser/prefs/browser_prefs.cc @@ -34,6 +34,7 @@ #include "brave/components/omnibox/browser/brave_omnibox_prefs.h" #include "brave/components/p3a/metric_log_store.h" #include "brave/components/p3a/rotation_scheduler.h" +#include "brave/components/speedreader/common/buildflags/buildflags.h" #include "brave/components/tor/buildflags/buildflags.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/channel_info.h" @@ -84,6 +85,10 @@ #include "brave/components/sidebar/browser/pref_names.h" #endif +#if BUILDFLAG(ENABLE_SPEEDREADER) +#include "brave/components/speedreader/speedreader_pref_migration.h" +#endif + // This method should be periodically pruned of year+ old migrations. void MigrateObsoleteProfilePrefs(PrefService* profile_prefs, const base::FilePath& profile_path) { @@ -211,6 +216,11 @@ void MigrateObsoleteProfilePrefs(PrefService* profile_prefs, profile_prefs->ClearPref(kWebTorrentEnabled); #endif + // Added 2025-08 - Speedreader preference migration +#if BUILDFLAG(ENABLE_SPEEDREADER) + speedreader::MigrateObsoleteProfilePrefs(profile_prefs); +#endif + // END_MIGRATE_OBSOLETE_PROFILE_PREFS } diff --git a/components/resources/speedreader_strings.grdp b/components/resources/speedreader_strings.grdp index f0347947be6..a19d91d5e0a 100644 --- a/components/resources/speedreader_strings.grdp +++ b/components/resources/speedreader_strings.grdp @@ -7,11 +7,11 @@ Turn off Speedreader Turn on Speedreader - Always use Speedreader for this site + Always use Speedreader for this site Toggle to turn on/off Speedreader for this website. - Always use Speedreader for all sites + Automatically use Speedreader when possible on all sites Toggle to turn on/off Speedreader for all websites. diff --git a/components/speedreader/BUILD.gn b/components/speedreader/BUILD.gn index 964dee6cbf2..ef7ac3c890e 100644 --- a/components/speedreader/BUILD.gn +++ b/components/speedreader/BUILD.gn @@ -24,6 +24,8 @@ static_library("speedreader") { "speedreader_extended_info_handler.h", "speedreader_metrics.cc", "speedreader_metrics.h", + "speedreader_pref_migration.cc", + "speedreader_pref_migration.h", "speedreader_pref_names.h", "speedreader_rewriter_service.cc", "speedreader_rewriter_service.h", diff --git a/components/speedreader/speedreader_pref_migration.cc b/components/speedreader/speedreader_pref_migration.cc new file mode 100644 index 00000000000..5d820c50ddb --- /dev/null +++ b/components/speedreader/speedreader_pref_migration.cc @@ -0,0 +1,34 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/speedreader/speedreader_pref_migration.h" + +#include "brave/components/speedreader/speedreader_pref_names.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" + +namespace speedreader { + +void RegisterProfilePrefsForMigration(PrefRegistrySimple* registry) { + // Legacy preference - keep for migration purposes only + registry->RegisterBooleanPref(kSpeedreaderPrefEnabledDeprecated, false); +} + +void MigrateObsoleteProfilePrefs(PrefService* prefs) { + // Check if the deprecated pref has been explicitly set by a user + if (prefs->HasPrefPath(kSpeedreaderPrefEnabledDeprecated)) { + bool old_value = prefs->GetBoolean(kSpeedreaderPrefEnabledDeprecated); + + // The old "enabled" pref controlled whether speedreader was enabled for + // all sites. Migrate only the all-sites preference - let the feature + // toggle use its default value (enabled). + prefs->SetBoolean(kSpeedreaderPrefEnabledForAllSites, old_value); + + // Clear the deprecated preference + prefs->ClearPref(kSpeedreaderPrefEnabledDeprecated); + } +} + +} // namespace speedreader diff --git a/components/speedreader/speedreader_pref_migration.h b/components/speedreader/speedreader_pref_migration.h new file mode 100644 index 00000000000..f18c7719b3f --- /dev/null +++ b/components/speedreader/speedreader_pref_migration.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_PREF_MIGRATION_H_ +#define BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_PREF_MIGRATION_H_ + +class PrefService; + +class PrefRegistrySimple; + +namespace speedreader { + +void RegisterProfilePrefsForMigration(PrefRegistrySimple* registry); +void MigrateObsoleteProfilePrefs(PrefService* prefs); + +} // namespace speedreader + +#endif // BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_PREF_MIGRATION_H_ diff --git a/components/speedreader/speedreader_pref_names.h b/components/speedreader/speedreader_pref_names.h index 8c4c76d6916..39373129735 100644 --- a/components/speedreader/speedreader_pref_names.h +++ b/components/speedreader/speedreader_pref_names.h @@ -8,9 +8,11 @@ namespace speedreader { -// Is Speedreader currently enabled +// Deprecated - migrated to kSpeedreaderPrefFeatureEnabled and +// kSpeedreaderPrefEnabledForAllSites (08/2025) // java_cpp_string.py doesn't work when the variable is constexpr -inline constexpr char kSpeedreaderPrefEnabled[] = "brave.speedreader.enabled"; +inline constexpr char kSpeedreaderPrefEnabledDeprecated[] = + "brave.speedreader.enabled"; // Set if Speedreader was enabled at least once inline constexpr char kSpeedreaderPrefEverEnabled[] = @@ -50,6 +52,16 @@ inline constexpr char kSpeedreaderPageViewsStoragePref[] = inline constexpr char kSpeedreaderDisabledByPolicy[] = "brave.speedreader.disabled_by_policy"; +// Top-level feature toggle for Speedreader (named feature_enabled to +// distinguish from the legacy "enabled" pref which actually controls all-sites +// behavior) +inline constexpr char kSpeedreaderPrefFeatureEnabled[] = + "brave.speedreader.feature_enabled"; + +// Whether Speedreader should be enabled for all sites +inline constexpr char kSpeedreaderPrefEnabledForAllSites[] = + "brave.speedreader.enabled_for_all_sites"; + } // namespace speedreader #endif // BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_PREF_NAMES_H_ diff --git a/components/speedreader/speedreader_service.cc b/components/speedreader/speedreader_service.cc index 4599bc40e87..16fd4e16e4e 100644 --- a/components/speedreader/speedreader_service.cc +++ b/components/speedreader/speedreader_service.cc @@ -14,6 +14,7 @@ #include "base/strings/string_number_conversions.h" #include "brave/components/speedreader/common/features.h" #include "brave/components/speedreader/common/speedreader_toolbar.mojom.h" +#include "brave/components/speedreader/speedreader_pref_migration.h" #include "brave/components/speedreader/speedreader_pref_names.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings_pattern.h" @@ -62,17 +63,20 @@ SpeedreaderService::~SpeedreaderService() = default; // static void SpeedreaderService::RegisterProfilePrefs(PrefRegistrySimple* registry) { - bool enabled_by_deault = false; + bool enabled_by_default = false; #if DCHECK_IS_ON() // Enable speedreader by default if the data collector command line key is // specified. constexpr const char kCollectSwitch[] = "speedreader-collect-test-data"; - enabled_by_deault = + enabled_by_default = base::CommandLine::ForCurrentProcess()->HasSwitch(kCollectSwitch); #endif - registry->RegisterBooleanPref(kSpeedreaderPrefEnabled, enabled_by_deault); + registry->RegisterBooleanPref(kSpeedreaderPrefFeatureEnabled, true); + registry->RegisterBooleanPref(kSpeedreaderPrefEnabledForAllSites, + enabled_by_default); + registry->RegisterBooleanPref(kSpeedreaderPrefEverEnabled, false); registry->RegisterListPref(kSpeedreaderPrefToggleCount); registry->RegisterIntegerPref(kSpeedreaderPrefPromptCount, 0); @@ -103,10 +107,17 @@ void SpeedreaderService::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } -bool SpeedreaderService::IsEnabledForAllSites() { +bool SpeedreaderService::IsFeatureEnabled() { bool disabled_by_policy = speedreader::IsDisabledByPolicy(prefs_); - bool enabled_pref = prefs_->GetBoolean(kSpeedreaderPrefEnabled); - return !disabled_by_policy && enabled_pref; + bool feature_enabled = prefs_->GetBoolean(kSpeedreaderPrefFeatureEnabled); + return !disabled_by_policy && feature_enabled; +} + +bool SpeedreaderService::IsEnabledForAllSites() { + if (!IsFeatureEnabled()) { + return false; + } + return prefs_->GetBoolean(kSpeedreaderPrefEnabledForAllSites); } ContentSetting SpeedreaderService::GetEnabledForSiteSetting(const GURL& url) { @@ -175,7 +186,7 @@ void SpeedreaderService::EnableForAllSites(bool enabled) { if (IsEnabledForAllSites() == enabled) { return; } - prefs_->SetBoolean(kSpeedreaderPrefEnabled, enabled); + prefs_->SetBoolean(kSpeedreaderPrefEnabledForAllSites, enabled); for (auto& o : observers_) { o.OnAllSitesEnableSettingChanged(enabled); diff --git a/components/speedreader/speedreader_service.h b/components/speedreader/speedreader_service.h index fe00bd096ce..f2ad5f6f4af 100644 --- a/components/speedreader/speedreader_service.h +++ b/components/speedreader/speedreader_service.h @@ -60,6 +60,9 @@ class SpeedreaderService : public KeyedService { void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + // Returns |true| if the Speedreader feature is enabled globally. + bool IsFeatureEnabled(); + // Returns |true| if Speedreader is turned on for all sites. bool IsEnabledForAllSites(); diff --git a/components/speedreader/speedreader_service_unittest.cc b/components/speedreader/speedreader_service_unittest.cc index adfeb5e975f..52ded6d4a6f 100644 --- a/components/speedreader/speedreader_service_unittest.cc +++ b/components/speedreader/speedreader_service_unittest.cc @@ -6,6 +6,7 @@ #include "brave/components/speedreader/speedreader_service.h" #include "base/test/task_environment.h" +#include "brave/components/speedreader/speedreader_pref_migration.h" #include "brave/components/speedreader/speedreader_pref_names.h" #include "build/build_config.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -98,4 +99,111 @@ TEST_F(SpeedreaderPolicyTest, PolicyWorksWithDefaultsWrite) { EXPECT_TRUE(IsDisabledByPolicy(&pref_service_)); } +class SpeedreaderPrefMigrationTest : public testing::Test { + public: + SpeedreaderPrefMigrationTest() { + SpeedreaderService::RegisterProfilePrefs(pref_service_.registry()); + RegisterProfilePrefsForMigration(pref_service_.registry()); + } + + protected: + sync_preferences::TestingPrefServiceSyncable pref_service_; +}; + +TEST_F(SpeedreaderPrefMigrationTest, MigratesEnabledPrefToNewStructure) { + // Set up the old preference structure - user had speedreader enabled + pref_service_.SetBoolean(kSpeedreaderPrefEnabledDeprecated, true); + + // Verify initial state + EXPECT_TRUE(pref_service_.HasPrefPath(kSpeedreaderPrefEnabledDeprecated)); + EXPECT_TRUE(pref_service_.GetBoolean(kSpeedreaderPrefEnabledDeprecated)); + EXPECT_TRUE(pref_service_.GetBoolean( + kSpeedreaderPrefFeatureEnabled)); // Default is true + EXPECT_FALSE(pref_service_.GetBoolean( + kSpeedreaderPrefEnabledForAllSites)); // Default is false + + // Run migration + MigrateObsoleteProfilePrefs(&pref_service_); + + // Verify migration results + EXPECT_FALSE( + pref_service_.HasPrefPath(kSpeedreaderPrefEnabledDeprecated)); // Cleared + EXPECT_TRUE(pref_service_.GetBoolean( + kSpeedreaderPrefFeatureEnabled)); // Still default (true) + EXPECT_TRUE(pref_service_.GetBoolean( + kSpeedreaderPrefEnabledForAllSites)); // Migrated to true +} + +TEST_F(SpeedreaderPrefMigrationTest, MigratesDisabledPrefToNewStructure) { + // Set up the old preference structure - user had speedreader disabled + pref_service_.SetBoolean(kSpeedreaderPrefEnabledDeprecated, false); + + // Verify initial state + EXPECT_TRUE(pref_service_.HasPrefPath(kSpeedreaderPrefEnabledDeprecated)); + EXPECT_FALSE(pref_service_.GetBoolean(kSpeedreaderPrefEnabledDeprecated)); + EXPECT_TRUE(pref_service_.GetBoolean( + kSpeedreaderPrefFeatureEnabled)); // Default is true + EXPECT_FALSE(pref_service_.GetBoolean( + kSpeedreaderPrefEnabledForAllSites)); // Default is false + + // Run migration + MigrateObsoleteProfilePrefs(&pref_service_); + + // Verify migration results + EXPECT_FALSE( + pref_service_.HasPrefPath(kSpeedreaderPrefEnabledDeprecated)); // Cleared + EXPECT_TRUE(pref_service_.GetBoolean( + kSpeedreaderPrefFeatureEnabled)); // Still default (true) + EXPECT_FALSE(pref_service_.GetBoolean( + kSpeedreaderPrefEnabledForAllSites)); // Migrated to false +} + +TEST_F(SpeedreaderPrefMigrationTest, HandlesNewInstallationWithDefaults) { + // Simulate new installation - deprecated pref path doesn't exist + EXPECT_FALSE(pref_service_.HasPrefPath(kSpeedreaderPrefEnabledDeprecated)); + + // Verify initial defaults + EXPECT_TRUE(pref_service_.GetBoolean( + kSpeedreaderPrefFeatureEnabled)); // Default is true + EXPECT_FALSE(pref_service_.GetBoolean( + kSpeedreaderPrefEnabledForAllSites)); // Default is false + + // Run migration + MigrateObsoleteProfilePrefs(&pref_service_); + + // Verify migration does nothing for new installations + EXPECT_FALSE(pref_service_.HasPrefPath(kSpeedreaderPrefEnabledDeprecated)); + EXPECT_TRUE(pref_service_.GetBoolean( + kSpeedreaderPrefFeatureEnabled)); // Still default + EXPECT_FALSE(pref_service_.GetBoolean( + kSpeedreaderPrefEnabledForAllSites)); // Still default +} + +TEST_F(SpeedreaderPrefMigrationTest, MigrationIdempotent) { + // Set up the old preference structure + pref_service_.SetBoolean(kSpeedreaderPrefEnabledDeprecated, true); + + // Verify the deprecated pref path exists + EXPECT_TRUE(pref_service_.HasPrefPath(kSpeedreaderPrefEnabledDeprecated)); + + // Run migration first time + MigrateObsoleteProfilePrefs(&pref_service_); + + // Verify migration worked and deprecated pref is cleared + EXPECT_FALSE(pref_service_.HasPrefPath(kSpeedreaderPrefEnabledDeprecated)); + EXPECT_TRUE(pref_service_.GetBoolean(kSpeedreaderPrefFeatureEnabled)); + EXPECT_TRUE(pref_service_.GetBoolean(kSpeedreaderPrefEnabledForAllSites)); + + // Manually change preferences to test idempotency + pref_service_.SetBoolean(kSpeedreaderPrefFeatureEnabled, false); + pref_service_.SetBoolean(kSpeedreaderPrefEnabledForAllSites, false); + + // Run migration again - should do nothing since deprecated pref is gone + MigrateObsoleteProfilePrefs(&pref_service_); + + // Verify values weren't changed by second migration + EXPECT_FALSE(pref_service_.GetBoolean(kSpeedreaderPrefFeatureEnabled)); + EXPECT_FALSE(pref_service_.GetBoolean(kSpeedreaderPrefEnabledForAllSites)); +} + } // namespace speedreader