Commit 14c3f87b authored by David Roger's avatar David Roger Committed by Commit Bot

[signin] Re-add missing call to ProfileMetrics::LogNumberOfProfiles

The logic to execute a task on a timer, persisted across Chrome
restarts, already existed in account_fetcher_service.
This CL extracts it in a new class, and reuses it in ProfileInfoCache.

The metric is not loaded exactly at the same time it was before:
it used to be logged for each profile, but now it's logged per Chrome
run. This makes more sense given the nature of the metric.

Fixed: 1060096
Change-Id: I5b8c709f088709934b8ad54fa9a46fac091923cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096743
Commit-Queue: David Roger <droger@chromium.org>
Reviewed-by: default avatarMonica Basta <msalama@chromium.org>
Cr-Commit-Position: refs/heads/master@{#749621}
parent b32c2fcc
...@@ -127,6 +127,10 @@ class ProfileAttributesStorage ...@@ -127,6 +127,10 @@ class ProfileAttributesStorage
// ProfileAttributesEntry. // ProfileAttributesEntry.
void NotifyOnProfileAvatarChanged(const base::FilePath& profile_path) const; void NotifyOnProfileAvatarChanged(const base::FilePath& profile_path) const;
// Disables the periodic reporting of profile metrics, as this is causing
// tests to time out.
virtual void DisableProfileMetricsForTesting() {}
protected: protected:
FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest, EntriesInAttributesStorage); FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest, EntriesInAttributesStorage);
FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest, FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest,
......
...@@ -46,6 +46,7 @@ const char kGAIAPictureFileNameKey[] = "gaia_picture_file_name"; ...@@ -46,6 +46,7 @@ const char kGAIAPictureFileNameKey[] = "gaia_picture_file_name";
const char kLastDownloadedGAIAPictureUrlWithSizeKey[] = const char kLastDownloadedGAIAPictureUrlWithSizeKey[] =
"last_downloaded_gaia_picture_url_with_size"; "last_downloaded_gaia_picture_url_with_size";
const char kAccountIdKey[] = "account_id_key"; const char kAccountIdKey[] = "account_id_key";
const char kProfileCountLastUpdatePref[] = "profile.profile_counts_reported";
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
const char kLegacyProfileNameMigrated[] = "legacy.profile.name.migrated"; const char kLegacyProfileNameMigrated[] = "legacy.profile.name.migrated";
bool migration_enabled_for_testing = false; bool migration_enabled_for_testing = false;
...@@ -121,12 +122,16 @@ ProfileInfoCache::ProfileInfoCache(PrefService* prefs, ...@@ -121,12 +122,16 @@ ProfileInfoCache::ProfileInfoCache(PrefService* prefs,
MigrateLegacyProfileNamesAndRecomputeIfNeeded(); MigrateLegacyProfileNamesAndRecomputeIfNeeded();
prefs_->SetBoolean(kLegacyProfileNameMigrated, true); prefs_->SetBoolean(kLegacyProfileNameMigrated, true);
} }
#endif //! defined(OS_ANDROID) && !defined(OS_CHROMEOS)
}
ProfileInfoCache::~ProfileInfoCache() { repeating_timer_ = std::make_unique<signin::PersistentRepeatingTimer>(
prefs_, kProfileCountLastUpdatePref, base::TimeDelta::FromHours(24),
base::Bind(&ProfileMetrics::LogNumberOfProfiles, this));
repeating_timer_->Start();
#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
} }
ProfileInfoCache::~ProfileInfoCache() = default;
void ProfileInfoCache::AddProfileToCache(const base::FilePath& profile_path, void ProfileInfoCache::AddProfileToCache(const base::FilePath& profile_path,
const base::string16& name, const base::string16& name,
const std::string& gaia_id, const std::string& gaia_id,
...@@ -187,6 +192,12 @@ void ProfileInfoCache::AddProfileToCache(const base::FilePath& profile_path, ...@@ -187,6 +192,12 @@ void ProfileInfoCache::AddProfileToCache(const base::FilePath& profile_path,
observer.OnProfileAdded(profile_path); observer.OnProfileAdded(profile_path);
} }
void ProfileInfoCache::DisableProfileMetricsForTesting() {
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
repeating_timer_.reset();
#endif
}
void ProfileInfoCache::NotifyIfProfileNamesHaveChanged() { void ProfileInfoCache::NotifyIfProfileNamesHaveChanged() {
std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes(); std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
for (ProfileAttributesEntry* entry : entries) { for (ProfileAttributesEntry* entry : entries) {
...@@ -473,6 +484,7 @@ const base::FilePath& ProfileInfoCache::GetUserDataDir() const { ...@@ -473,6 +484,7 @@ const base::FilePath& ProfileInfoCache::GetUserDataDir() const {
// static // static
void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) { void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterDictionaryPref(prefs::kProfileInfoCache); registry->RegisterDictionaryPref(prefs::kProfileInfoCache);
registry->RegisterTimePref(kProfileCountLastUpdatePref, base::Time());
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
registry->RegisterBooleanPref(kLegacyProfileNameMigrated, false); registry->RegisterBooleanPref(kLegacyProfileNameMigrated, false);
#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_info_cache_observer.h" #include "chrome/browser/profiles/profile_info_cache_observer.h"
#include "chrome/browser/profiles/profile_info_interface.h" #include "chrome/browser/profiles/profile_info_interface.h"
#include "components/signin/public/base/persistent_repeating_timer.h"
namespace gfx { namespace gfx {
class Image; class Image;
...@@ -120,6 +121,7 @@ class ProfileInfoCache : public ProfileInfoInterface, ...@@ -120,6 +121,7 @@ class ProfileInfoCache : public ProfileInfoInterface,
bool GetProfileAttributesWithPath(const base::FilePath& path, bool GetProfileAttributesWithPath(const base::FilePath& path,
ProfileAttributesEntry** entry) override; ProfileAttributesEntry** entry) override;
void DisableProfileMetricsForTesting() override;
void NotifyProfileAuthInfoChanged(const base::FilePath& profile_path); void NotifyProfileAuthInfoChanged(const base::FilePath& profile_path);
void NotifyIfProfileNamesHaveChanged(); void NotifyIfProfileNamesHaveChanged();
...@@ -177,6 +179,8 @@ class ProfileInfoCache : public ProfileInfoInterface, ...@@ -177,6 +179,8 @@ class ProfileInfoCache : public ProfileInfoInterface,
// recomputed to "Person 1" and "Person 2". // recomputed to "Person 1" and "Person 2".
void MigrateLegacyProfileNamesAndRecomputeIfNeeded(); void MigrateLegacyProfileNamesAndRecomputeIfNeeded();
static void SetLegacyProfileMigrationForTesting(bool value); static void SetLegacyProfileMigrationForTesting(bool value);
std::unique_ptr<signin::PersistentRepeatingTimer> repeating_timer_;
#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
std::vector<std::string> keys_; std::vector<std::string> keys_;
......
...@@ -156,22 +156,21 @@ enum ProfileAvatar { ...@@ -156,22 +156,21 @@ enum ProfileAvatar {
NUM_PROFILE_AVATAR_METRICS NUM_PROFILE_AVATAR_METRICS
}; };
bool ProfileMetrics::CountProfileInformation(ProfileManager* manager, void ProfileMetrics::CountProfileInformation(ProfileAttributesStorage* storage,
profile_metrics::Counts* counts) { profile_metrics::Counts* counts) {
ProfileAttributesStorage& storage = manager->GetProfileAttributesStorage(); size_t number_of_profiles = storage->GetNumberOfProfiles();
size_t number_of_profiles = storage.GetNumberOfProfiles();
counts->total = number_of_profiles; counts->total = number_of_profiles;
// Ignore other metrics if we have no profiles. // Ignore other metrics if we have no profiles.
if (!number_of_profiles) if (!number_of_profiles)
return false; return;
// Maximum age for "active" profile is 4 weeks. // Maximum age for "active" profile is 4 weeks.
base::Time oldest = base::Time::Now() - base::Time oldest = base::Time::Now() -
base::TimeDelta::FromDays(kMaximumDaysOfDisuse); base::TimeDelta::FromDays(kMaximumDaysOfDisuse);
std::vector<ProfileAttributesEntry*> entries = std::vector<ProfileAttributesEntry*> entries =
storage.GetAllProfilesAttributes(); storage->GetAllProfilesAttributes();
for (ProfileAttributesEntry* entry : entries) { for (ProfileAttributesEntry* entry : entries) {
if (!HasProfileBeenActiveSince(entry, oldest)) { if (!HasProfileBeenActiveSince(entry, oldest)) {
counts->unused++; counts->unused++;
...@@ -190,7 +189,6 @@ bool ProfileMetrics::CountProfileInformation(ProfileManager* manager, ...@@ -190,7 +189,6 @@ bool ProfileMetrics::CountProfileInformation(ProfileManager* manager,
} }
} }
} }
return true;
} }
profile_metrics::BrowserProfileType ProfileMetrics::GetBrowserProfileType( profile_metrics::BrowserProfileType ProfileMetrics::GetBrowserProfileType(
...@@ -221,9 +219,9 @@ void ProfileMetrics::LogNumberOfProfileSwitches() { ...@@ -221,9 +219,9 @@ void ProfileMetrics::LogNumberOfProfileSwitches() {
} }
#endif #endif
void ProfileMetrics::LogNumberOfProfiles(ProfileManager* manager) { void ProfileMetrics::LogNumberOfProfiles(ProfileAttributesStorage* storage) {
profile_metrics::Counts counts; profile_metrics::Counts counts;
CountProfileInformation(manager, &counts); CountProfileInformation(storage, &counts);
profile_metrics::LogProfileMetricsCounts(counts); profile_metrics::LogProfileMetricsCounts(counts);
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "build/build_config.h" #include "build/build_config.h"
class Profile; class Profile;
class ProfileAttributesStorage;
class ProfileManager; class ProfileManager;
namespace base { namespace base {
...@@ -151,8 +152,8 @@ class ProfileMetrics { ...@@ -151,8 +152,8 @@ class ProfileMetrics {
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
// Count and return summary information about the profiles currently in the // Count and return summary information about the profiles currently in the
// |manager|. This information is returned in the output variable |counts|. // |storage|. This information is returned in the output variable |counts|.
static bool CountProfileInformation(ProfileManager* manager, static void CountProfileInformation(ProfileAttributesStorage* storage,
profile_metrics::Counts* counts); profile_metrics::Counts* counts);
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
...@@ -163,7 +164,7 @@ class ProfileMetrics { ...@@ -163,7 +164,7 @@ class ProfileMetrics {
static profile_metrics::BrowserProfileType GetBrowserProfileType( static profile_metrics::BrowserProfileType GetBrowserProfileType(
Profile* profile); Profile* profile);
static void LogNumberOfProfiles(ProfileManager* manager); static void LogNumberOfProfiles(ProfileAttributesStorage* storage);
static void LogProfileAddNewUser(ProfileAdd metric); static void LogProfileAddNewUser(ProfileAdd metric);
static void LogProfileAvatarSelection(size_t icon_index); static void LogProfileAvatarSelection(size_t icon_index);
static void LogProfileDeleteUser(ProfileDelete metric); static void LogProfileDeleteUser(ProfileDelete metric);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "base/values.h" #include "base/values.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/prefs/browser_prefs.h" #include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/safe_browsing/incident_reporting/incident.h" #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h"
#include "chrome/browser/safe_browsing/incident_reporting/incident_report_uploader.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_report_uploader.h"
...@@ -212,6 +213,10 @@ class IncidentReportingServiceTest : public testing::Test { ...@@ -212,6 +213,10 @@ class IncidentReportingServiceTest : public testing::Test {
registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER)); registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));
#endif #endif
ASSERT_TRUE(profile_manager_.SetUp()); ASSERT_TRUE(profile_manager_.SetUp());
// Disable profile metrics reporting, otherwise the calls to
// FastForwardUntilNoTasksRemain() never return.
profile_manager_.profile_attributes_storage()
->DisableProfileMetricsForTesting();
} }
void CreateIncidentReportingService() { void CreateIncidentReportingService() {
......
...@@ -150,8 +150,9 @@ TEST_F(SigninGlobalErrorTest, AuthStatusEnumerateAllErrors) { ...@@ -150,8 +150,9 @@ TEST_F(SigninGlobalErrorTest, AuthStatusEnumerateAllErrors) {
EXPECT_FALSE(global_error()->GetBubbleViewAcceptButtonLabel().empty()); EXPECT_FALSE(global_error()->GetBubbleViewAcceptButtonLabel().empty());
EXPECT_TRUE(global_error()->GetBubbleViewCancelButtonLabel().empty()); EXPECT_TRUE(global_error()->GetBubbleViewCancelButtonLabel().empty());
ProfileMetrics::LogNumberOfProfiles( ProfileMetrics::LogNumberOfProfiles(&testing_profile_manager()
testing_profile_manager()->profile_manager()); ->profile_manager()
->GetProfileAttributesStorage());
if (entry.is_error) { if (entry.is_error) {
histogram_tester.ExpectBucketCount("Signin.AuthError", entry.error_state, histogram_tester.ExpectBucketCount("Signin.AuthError", entry.error_state,
......
...@@ -75,8 +75,11 @@ void AccountFetcherService::Initialize( ...@@ -75,8 +75,11 @@ void AccountFetcherService::Initialize(
DCHECK(image_decoder); DCHECK(image_decoder);
DCHECK(!image_decoder_); DCHECK(!image_decoder_);
image_decoder_ = std::move(image_decoder); image_decoder_ = std::move(image_decoder);
last_updated_ = signin_client_->GetPrefs()->GetTime( repeating_timer_ = std::make_unique<signin::PersistentRepeatingTimer>(
AccountFetcherService::kLastUpdatePref); signin_client_->GetPrefs(), AccountFetcherService::kLastUpdatePref,
kRefreshFromTokenServiceDelay,
base::Bind(&AccountFetcherService::RefreshAllAccountInfo,
base::Unretained(this), false));
// Tokens may have already been loaded and we will not receive a // Tokens may have already been loaded and we will not receive a
// notification-on-registration for |token_service_->AddObserver(this)| few // notification-on-registration for |token_service_->AddObserver(this)| few
...@@ -162,7 +165,7 @@ void AccountFetcherService::MaybeEnableNetworkFetches() { ...@@ -162,7 +165,7 @@ void AccountFetcherService::MaybeEnableNetworkFetches() {
return; return;
if (!network_fetches_enabled_) { if (!network_fetches_enabled_) {
network_fetches_enabled_ = true; network_fetches_enabled_ = true;
ScheduleNextRefresh(); repeating_timer_->Start();
} }
RefreshAllAccountInfo(true); RefreshAllAccountInfo(true);
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
...@@ -170,29 +173,6 @@ void AccountFetcherService::MaybeEnableNetworkFetches() { ...@@ -170,29 +173,6 @@ void AccountFetcherService::MaybeEnableNetworkFetches() {
#endif #endif
} }
void AccountFetcherService::RefreshAllAccountsAndScheduleNext() {
DCHECK(network_fetches_enabled_);
RefreshAllAccountInfo(false);
last_updated_ = base::Time::Now();
signin_client_->GetPrefs()->SetTime(AccountFetcherService::kLastUpdatePref,
last_updated_);
ScheduleNextRefresh();
}
void AccountFetcherService::ScheduleNextRefresh() {
DCHECK(!timer_.IsRunning());
DCHECK(network_fetches_enabled_);
const base::TimeDelta time_since_update = base::Time::Now() - last_updated_;
if (time_since_update > kRefreshFromTokenServiceDelay) {
RefreshAllAccountsAndScheduleNext();
} else {
timer_.Start(FROM_HERE, kRefreshFromTokenServiceDelay - time_since_update,
this,
&AccountFetcherService::RefreshAllAccountsAndScheduleNext);
}
}
// Starts fetching user information. This is called periodically to refresh. // Starts fetching user information. This is called periodically to refresh.
void AccountFetcherService::StartFetchingUserInfo( void AccountFetcherService::StartFetchingUserInfo(
const CoreAccountId& account_id) { const CoreAccountId& account_id) {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h" #include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h"
#include "components/signin/public/base/persistent_repeating_timer.h"
class AccountInfoFetcher; class AccountInfoFetcher;
class AccountTrackerService; class AccountTrackerService;
...@@ -100,8 +101,6 @@ class AccountFetcherService : public ProfileOAuth2TokenServiceObserver { ...@@ -100,8 +101,6 @@ class AccountFetcherService : public ProfileOAuth2TokenServiceObserver {
friend class AccountInfoFetcher; friend class AccountInfoFetcher;
void RefreshAllAccountInfo(bool only_fetch_if_invalid); void RefreshAllAccountInfo(bool only_fetch_if_invalid);
void RefreshAllAccountsAndScheduleNext();
void ScheduleNextRefresh();
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Called on all account state changes. Decides whether to fetch new child // Called on all account state changes. Decides whether to fetch new child
...@@ -150,8 +149,7 @@ class AccountFetcherService : public ProfileOAuth2TokenServiceObserver { ...@@ -150,8 +149,7 @@ class AccountFetcherService : public ProfileOAuth2TokenServiceObserver {
bool refresh_tokens_loaded_ = false; bool refresh_tokens_loaded_ = false;
bool shutdown_called_ = false; bool shutdown_called_ = false;
bool enable_account_removal_for_test_ = false; bool enable_account_removal_for_test_ = false;
base::Time last_updated_; std::unique_ptr<signin::PersistentRepeatingTimer> repeating_timer_;
base::OneShotTimer timer_;
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
CoreAccountId child_request_account_id_; CoreAccountId child_request_account_id_;
......
...@@ -27,6 +27,8 @@ static_library("base") { ...@@ -27,6 +27,8 @@ static_library("base") {
"device_id_helper.h", "device_id_helper.h",
"multilogin_parameters.cc", "multilogin_parameters.cc",
"multilogin_parameters.h", "multilogin_parameters.h",
"persistent_repeating_timer.cc",
"persistent_repeating_timer.h",
"signin_client.cc", "signin_client.cc",
"signin_client.h", "signin_client.h",
"signin_metrics.cc", "signin_metrics.cc",
...@@ -87,6 +89,7 @@ source_set("unit_tests") { ...@@ -87,6 +89,7 @@ source_set("unit_tests") {
sources = [ sources = [
"avatar_icon_util_unittest.cc", "avatar_icon_util_unittest.cc",
"device_id_helper_unittest.cc", "device_id_helper_unittest.cc",
"persistent_repeating_timer_unittest.cc",
"signin_metrics_unittest.cc", "signin_metrics_unittest.cc",
] ]
...@@ -94,6 +97,7 @@ source_set("unit_tests") { ...@@ -94,6 +97,7 @@ source_set("unit_tests") {
":base", ":base",
"//base", "//base",
"//base/test:test_support", "//base/test:test_support",
"//components/prefs:test_support",
"//components/sync_preferences:test_support", "//components/sync_preferences:test_support",
"//testing/gtest", "//testing/gtest",
"//url", "//url",
......
// Copyright 2020 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 "components/signin/public/base/persistent_repeating_timer.h"
#include "base/callback.h"
#include "components/prefs/pref_service.h"
namespace signin {
PersistentRepeatingTimer::PersistentRepeatingTimer(
PrefService* prefs,
const char* timer_last_update_pref_name,
base::TimeDelta delay,
base::RepeatingClosure task)
: prefs_(prefs),
last_fired_pref_name_(timer_last_update_pref_name),
delay_(delay),
user_task_(task) {}
PersistentRepeatingTimer::~PersistentRepeatingTimer() = default;
void PersistentRepeatingTimer::Start() {
if (timer_.IsRunning())
return; // Already started.
const base::TimeDelta time_since_update = base::Time::Now() - GetLastFired();
if (time_since_update >= delay_) {
OnTimerFired();
} else {
timer_.Start(FROM_HERE, delay_ - time_since_update,
base::Bind(&PersistentRepeatingTimer::OnTimerFired,
base::Unretained(this)));
}
DCHECK(timer_.IsRunning());
}
base::Time PersistentRepeatingTimer::GetLastFired() {
return prefs_->GetTime(last_fired_pref_name_);
}
void PersistentRepeatingTimer::SetLastFiredNow() {
prefs_->SetTime(last_fired_pref_name_, base::Time::Now());
}
void PersistentRepeatingTimer::OnTimerFired() {
DCHECK(!timer_.IsRunning());
SetLastFiredNow();
user_task_.Run();
Start();
}
} // namespace signin
// Copyright 2020 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 COMPONENTS_SIGNIN_PUBLIC_BASE_PERSISTENT_REPEATING_TIMER_H_
#define COMPONENTS_SIGNIN_PUBLIC_BASE_PERSISTENT_REPEATING_TIMER_H_
#include <string>
#include "base/callback_forward.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
class PrefService;
namespace signin {
// This class fires a task repeatedly, across application restarts. The timer
// stores the date of the last invocation in a preference, which is persisted
// to disk.
class PersistentRepeatingTimer {
public:
// The timer is not started at creation.
PersistentRepeatingTimer(PrefService* prefs,
const char* timer_last_update_pref_name,
base::TimeDelta delay,
base::RepeatingClosure task);
~PersistentRepeatingTimer();
// Starts the timer. Calling Start() when the timer is running has no effect.
void Start();
private:
// Reads the date of the last event from the pref.
base::Time GetLastFired();
// Updates the pref with the current time.
void SetLastFiredNow();
// Called when |timer_| fires.
void OnTimerFired();
PrefService* prefs_;
std::string last_fired_pref_name_;
base::TimeDelta delay_;
base::RepeatingClosure user_task_;
base::RetainingOneShotTimer timer_;
};
} // namespace signin
#endif // COMPONENTS_SIGNIN_PUBLIC_BASE_PERSISTENT_REPEATING_TIMER_H_
// Copyright 2020 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 "components/signin/public/base/persistent_repeating_timer.h"
#include "base/test/task_environment.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace signin {
namespace {
const char kLastUpdatedTimePref[] = "test.last_updated_time";
constexpr base::TimeDelta kTestDelay = base::TimeDelta::FromHours(2);
} // namespace
class PersistentRepeatingTimerTest : public ::testing::Test {
public:
PersistentRepeatingTimerTest() {
pref_service_.registry()->RegisterTimePref(kLastUpdatedTimePref,
base::Time());
}
void RunTask() { ++call_count_; }
void CheckCallCount(int call_count) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(call_count, call_count_);
}
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
TestingPrefServiceSimple pref_service_;
int call_count_ = 0;
};
// Checks that the missing pref is treated like an old one.
TEST_F(PersistentRepeatingTimerTest, MissingPref) {
PersistentRepeatingTimer timer(
&pref_service_, kLastUpdatedTimePref, kTestDelay,
base::Bind(&PersistentRepeatingTimerTest::RunTask,
base::Unretained(this)));
CheckCallCount(0);
// The task is run immediately on start.
timer.Start();
CheckCallCount(1);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
CheckCallCount(1);
// And after the delay.
task_environment_.FastForwardBy(kTestDelay);
CheckCallCount(2);
}
// Checks that spurious calls to Start() have no effect.
TEST_F(PersistentRepeatingTimerTest, MultipleStarts) {
PersistentRepeatingTimer timer(
&pref_service_, kLastUpdatedTimePref, kTestDelay,
base::Bind(&PersistentRepeatingTimerTest::RunTask,
base::Unretained(this)));
CheckCallCount(0);
// The task is run immediately on start.
timer.Start();
CheckCallCount(1);
timer.Start();
CheckCallCount(1);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
CheckCallCount(1);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
timer.Start();
CheckCallCount(1);
// And after the delay.
task_environment_.FastForwardBy(kTestDelay);
CheckCallCount(2);
timer.Start();
CheckCallCount(2);
}
TEST_F(PersistentRepeatingTimerTest, RecentPref) {
pref_service_.SetTime(kLastUpdatedTimePref,
base::Time::Now() - base::TimeDelta::FromHours(1));
PersistentRepeatingTimer timer(
&pref_service_, kLastUpdatedTimePref, kTestDelay,
base::Bind(&PersistentRepeatingTimerTest::RunTask,
base::Unretained(this)));
CheckCallCount(0);
// The task is NOT run immediately on start.
timer.Start();
CheckCallCount(0);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
CheckCallCount(0);
// It is run after te delay.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
CheckCallCount(1);
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
CheckCallCount(1);
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
CheckCallCount(2);
}
TEST_F(PersistentRepeatingTimerTest, OldPref) {
pref_service_.SetTime(kLastUpdatedTimePref,
base::Time::Now() - base::TimeDelta::FromHours(10));
PersistentRepeatingTimer timer(
&pref_service_, kLastUpdatedTimePref, kTestDelay,
base::Bind(&PersistentRepeatingTimerTest::RunTask,
base::Unretained(this)));
CheckCallCount(0);
// The task is run immediately on start.
timer.Start();
CheckCallCount(1);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
CheckCallCount(1);
// And after the delay.
task_environment_.FastForwardBy(kTestDelay);
CheckCallCount(2);
}
} // namespace signin
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment