From: uazo Date: Mon, 31 Jan 2022 12:49:39 +0000 Subject: History number of days privacy setting Adds a new option in the privacy settings that allows the selection of the days to keep in the browsing history. Selecting the "Never" item activates the kSavingBrowserHistoryDisabled flag and immediately deletes all the history. Some parts authored by csagan5. License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html --- .../java/res/xml/privacy_preferences.xml | 6 ++ .../privacy/settings/PrivacySettings.java | 63 +++++++++++++++++++ .../history/history_service_factory.cc | 2 + chrome/browser/profiles/profile_impl.cc | 1 + .../strings/android_chrome_strings.grd | 12 ++++ .../preference_spinner_single_line.xml | 26 ++++++-- .../java/res/layout/preference_spinner.xml | 7 +++ .../layout/preference_spinner_single_line.xml | 7 +++ .../settings/SpinnerPreference.java | 7 +++ .../core/browser/expire_history_backend.cc | 13 +++- .../core/browser/expire_history_backend.h | 2 + .../history/core/browser/history_backend.cc | 15 ++++- .../history/core/browser/history_backend.h | 2 + .../history/core/browser/history_service.cc | 33 ++++++++++ .../history/core/browser/history_service.h | 8 +++ components/history/core/common/pref_names.cc | 4 ++ components/history/core/common/pref_names.h | 1 + 17 files changed, 201 insertions(+), 8 deletions(-) diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml --- a/chrome/android/java/res/xml/privacy_preferences.xml +++ b/chrome/android/java/res/xml/privacy_preferences.xml @@ -43,6 +43,12 @@ found in the LICENSE file. android:title="@string/settings_incognito_tab_lock_title" android:summary="@string/settings_incognito_tab_lock_summary_android_setting_off" android:persistent="false"/> + options = new ArrayList<>(); + options.add(new TimeFrequencySpinnerOption(0, + getActivity().getString(R.string.history_expire_days_no_history))); + options.add(new TimeFrequencySpinnerOption(1)); + options.add(new TimeFrequencySpinnerOption(7)); + options.add(new TimeFrequencySpinnerOption(15)); + options.add(new TimeFrequencySpinnerOption(30)); + options.add(new TimeFrequencySpinnerOption(60)); + options.add(new TimeFrequencySpinnerOption(90)); + options.add(new TimeFrequencySpinnerOption(0xFFFF, + getActivity().getString(R.string.history_expire_days_keep_forever))); + TimeFrequencySpinnerOption[] spinnerOptions = options.toArray(new TimeFrequencySpinnerOption[0]); + + int selectedTimeFrequency = UserPrefs.get(getProfile()) + .getInteger(Pref.EXPIRE_DAYS_THRESHOLD); + int spinnerOptionIndex = -1; + for (int i = 0; i < spinnerOptions.length; ++i) { + if (spinnerOptions[i].getDays() == selectedTimeFrequency) { + spinnerOptionIndex = i; + break; + } + } + + SpinnerPreference spinner = (SpinnerPreference) findPreference(PREF_HISTORY_EXPIRE_DAYS_THRESHOLD); + spinner.setOptions(spinnerOptions, spinnerOptionIndex); + spinner.setSummary(getResources().getString(R.string.history_expire_days_threshold_summary)); + spinner.setOnPreferenceChangeListener((preference, newValue) -> { + UserPrefs.get(getProfile()) + .setInteger(Pref.EXPIRE_DAYS_THRESHOLD, + ((TimeFrequencySpinnerOption) newValue).getDays()); + return true; + }); + Preference thirdPartyCookies = findPreference(PREF_THIRD_PARTY_COOKIES); if (showTrackingProtectionUI()) { @@ -411,6 +451,29 @@ public class PrivacySettings || ChromeFeatureList.isEnabled(ChromeFeatureList.TRACKING_PROTECTION_3PCD); } + class TimeFrequencySpinnerOption { + private int mDays; + private String mDescription; + + public TimeFrequencySpinnerOption(int days) { + this(days, Integer.toString(days)); + } + + public TimeFrequencySpinnerOption(int days, String description) { + mDays = days; + mDescription = description; + } + + public int getDays() { + return mDays; + } + + @Override + public String toString() { + return mDescription; + } + } + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.clear(); diff --git a/chrome/browser/history/history_service_factory.cc b/chrome/browser/history/history_service_factory.cc --- a/chrome/browser/history/history_service_factory.cc +++ b/chrome/browser/history/history_service_factory.cc @@ -29,6 +29,8 @@ std::unique_ptr BuildHistoryService( context->GetPath(), chrome::GetChannel()))) { return nullptr; } + Profile* profile = Profile::FromBrowserContext(context); + history_service->InitFromPreferences(profile->GetPrefs()); return history_service; } diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -368,6 +368,7 @@ std::unique_ptr Profile::CreateProfile(const base::FilePath& path, void ProfileImpl::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref(prefs::kSavingBrowserHistoryDisabled, false); + registry->RegisterIntegerPref(prefs::kExpireDaysThreshold, 90); registry->RegisterBooleanPref(prefs::kAllowDeletingBrowserHistory, true); registry->RegisterBooleanPref(policy::policy_prefs::kForceGoogleSafeSearch, false); diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd @@ -1416,6 +1416,18 @@ Your Google account may have other forms of browsing history like searches and a Browsing history + + Expire history days threshold + + + No history + + + Forever + + + Number of days to keep navigation history + Cookies and site data diff --git a/components/browser_ui/settings/android/java/res/layout-sw360dp/preference_spinner_single_line.xml b/components/browser_ui/settings/android/java/res/layout-sw360dp/preference_spinner_single_line.xml --- a/components/browser_ui/settings/android/java/res/layout-sw360dp/preference_spinner_single_line.xml +++ b/components/browser_ui/settings/android/java/res/layout-sw360dp/preference_spinner_single_line.xml @@ -13,19 +13,33 @@ found in the LICENSE file. android:layout_height="wrap_content" android:orientation="horizontal" android:paddingEnd="@dimen/pref_spinner_padding_end" - android:paddingTop="12dp" + android:paddingTop="0dp" android:paddingBottom="6dp"> - + android:paddingBottom="12dp"> + + + + + + + + + + PostTask( + FROM_HERE, base::BindOnce(&HistoryBackend::DeleteAllHistory, this)); + } +} + void HistoryBackend::OnMemoryPressure( base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { // TODO(sebmarchand): Check if MEMORY_PRESSURE_LEVEL_MODERATE should also be diff --git a/components/history/core/browser/history_backend.h b/components/history/core/browser/history_backend.h --- a/components/history/core/browser/history_backend.h +++ b/components/history/core/browser/history_backend.h @@ -221,6 +221,8 @@ class HistoryBackend : public base::RefCountedThreadSafe, void Init(bool force_fail, const HistoryDatabaseParams& history_database_params); + void SetExpireDaysThreshold(int days); + // Notification that the history system is shutting down. This will break // the refs owned by the delegate and any pending transaction, so it will // actually be deleted. diff --git a/components/history/core/browser/history_service.cc b/components/history/core/browser/history_service.cc --- a/components/history/core/browser/history_service.cc +++ b/components/history/core/browser/history_service.cc @@ -37,6 +37,9 @@ #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/history/core/common/pref_names.h" #include "components/history/core/browser/download_row.h" #include "components/history/core/browser/features.h" #include "components/history/core/browser/history_backend.h" @@ -1340,6 +1343,9 @@ void HistoryService::Cleanup() { return; } + active_user_pref_change_registrar_.reset(); + active_user_pref_service_ = nullptr; + NotifyHistoryServiceBeingDeleted(); weak_ptr_factory_.InvalidateWeakPtrs(); @@ -1416,6 +1422,33 @@ bool HistoryService::Init( return true; } +void HistoryService::InitFromPreferences(PrefService* prefs) { + DCHECK(prefs); + + active_user_pref_service_ = prefs; + OnUserPrefChanged(); + + active_user_pref_change_registrar_ = std::make_unique(); + active_user_pref_change_registrar_->Init(prefs); + active_user_pref_change_registrar_->Add( + prefs::kExpireDaysThreshold, + base::BindRepeating( + &HistoryService::OnUserPrefChanged, + base::Unretained(this))); +} + +void HistoryService::OnUserPrefChanged() { + DCHECK(active_user_pref_service_); + + int kExpireDaysThreshold = + active_user_pref_service_->GetInteger(prefs::kExpireDaysThreshold); + // disable history saving when the 0 magic value is used + // the current history records are truncated elsewhere + active_user_pref_service_->SetBoolean(prefs::kSavingBrowserHistoryDisabled, + (kExpireDaysThreshold == 0)); + history_backend_->SetExpireDaysThreshold(kExpireDaysThreshold); +} + void HistoryService::ScheduleAutocomplete( base::OnceCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); diff --git a/components/history/core/browser/history_service.h b/components/history/core/browser/history_service.h --- a/components/history/core/browser/history_service.h +++ b/components/history/core/browser/history_service.h @@ -34,6 +34,8 @@ #include "build/build_config.h" #include "components/favicon_base/favicon_callback.h" #include "components/favicon_base/favicon_usage_data.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/pref_change_registrar.h" #include "components/history/core/browser/history_types.h" #include "components/history/core/browser/keyword_id.h" #include "components/history/core/browser/url_row.h" @@ -114,6 +116,8 @@ class HistoryService : public KeyedService, return Init(false, history_database_params); } + void InitFromPreferences(PrefService* prefs); + // Triggers the backend to load if it hasn't already, and then returns whether // it's finished loading. // Note: Virtual needed for mocking. @@ -1138,6 +1142,10 @@ class HistoryService : public KeyedService, raw_ptr local_device_info_provider_ = nullptr; + void OnUserPrefChanged(); + raw_ptr active_user_pref_service_ = nullptr; + std::unique_ptr active_user_pref_change_registrar_; + // All vended weak pointers are invalidated in Cleanup(). base::WeakPtrFactory weak_ptr_factory_{this}; }; diff --git a/components/history/core/common/pref_names.cc b/components/history/core/common/pref_names.cc --- a/components/history/core/common/pref_names.cc +++ b/components/history/core/common/pref_names.cc @@ -9,6 +9,10 @@ namespace prefs { // Boolean controlling whether history saving is disabled. const char kSavingBrowserHistoryDisabled[] = "history.saving_disabled"; +// The number of days old a history entry can be before it is considered "old" +// and is deleted. +const char kExpireDaysThreshold[] = "history.expire_days_threshold"; + // Boolean controlling whether deleting browsing and download history is // permitted. const char kAllowDeletingBrowserHistory[] = "history.deleting_enabled"; diff --git a/components/history/core/common/pref_names.h b/components/history/core/common/pref_names.h --- a/components/history/core/common/pref_names.h +++ b/components/history/core/common/pref_names.h @@ -12,6 +12,7 @@ namespace prefs { extern const char kSavingBrowserHistoryDisabled[]; +extern const char kExpireDaysThreshold[]; extern const char kAllowDeletingBrowserHistory[]; } // namespace prefs -- 2.25.1