Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(992)

Unified Diff: components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc

Issue 2611523004: [Background fetching] Background fetching when opening an NTP. (Closed)
Patch Set: Tim's comments Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/ntp_snippets/remote/scheduling_remote_suggestions_provider.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc
diff --git a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc
index 7387410d8cc7b624f27103882229b4c152fd2094..86ffb023f706fdaa4eba8d15fd4d1021223961b6 100644
--- a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc
+++ b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc
@@ -4,6 +4,7 @@
#include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider.h"
+#include <random>
#include <string>
#include <utility>
@@ -21,28 +22,57 @@ namespace ntp_snippets {
namespace {
+enum class FetchingInterval {
+ PERSISTENT_FALLBACK,
+ PERSISTENT_WIFI,
+ SOFT_ON_USAGE_EVENT,
+ COUNT
+};
+
// Default values for fetching intervals, fallback and wifi.
-const double kDefaultFetchingIntervalRareNtpUser[] = {48.0, 24.0};
-const double kDefaultFetchingIntervalActiveNtpUser[] = {24.0, 6.0};
-const double kDefaultFetchingIntervalActiveSuggestionsConsumer[] = {24.0, 6.0};
+const double kDefaultFetchingIntervalRareNtpUser[] = {48.0, 24.0, 12.0};
+const double kDefaultFetchingIntervalActiveNtpUser[] = {24.0, 6.0, 2.0};
+const double kDefaultFetchingIntervalActiveSuggestionsConsumer[] = {24.0, 6.0,
+ 2.0};
// Variation parameters than can the default fetching intervals.
const char* kFetchingIntervalParamNameRareNtpUser[] = {
"fetching_interval_hours-fallback-rare_ntp_user",
- "fetching_interval_hours-wifi-rare_ntp_user"};
+ "fetching_interval_hours-wifi-rare_ntp_user",
+ "soft_fetching_interval_hours-active-rare_ntp_user"};
const char* kFetchingIntervalParamNameActiveNtpUser[] = {
"fetching_interval_hours-fallback-active_ntp_user",
- "fetching_interval_hours-wifi-active_ntp_user"};
+ "fetching_interval_hours-wifi-active_ntp_user",
+ "soft_fetching_interval_hours-active-active_ntp_user"};
const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = {
"fetching_interval_hours-fallback-active_suggestions_consumer",
- "fetching_interval_hours-wifi-active_suggestions_consumer"};
-
-base::TimeDelta GetDesiredUpdateInterval(
- bool is_wifi,
+ "fetching_interval_hours-wifi-active_suggestions_consumer",
+ "soft_fetching_interval_hours-active-active_suggestions_consumer"};
+
+static_assert(
+ static_cast<unsigned int>(FetchingInterval::COUNT) ==
+ arraysize(kDefaultFetchingIntervalRareNtpUser) &&
+ static_cast<unsigned int>(FetchingInterval::COUNT) ==
+ arraysize(kDefaultFetchingIntervalActiveNtpUser) &&
+ static_cast<unsigned int>(FetchingInterval::COUNT) ==
+ arraysize(kDefaultFetchingIntervalActiveSuggestionsConsumer) &&
+ static_cast<unsigned int>(FetchingInterval::COUNT) ==
+ arraysize(kFetchingIntervalParamNameRareNtpUser) &&
+ static_cast<unsigned int>(FetchingInterval::COUNT) ==
+ arraysize(kFetchingIntervalParamNameActiveNtpUser) &&
+ static_cast<unsigned int>(FetchingInterval::COUNT) ==
+ arraysize(kFetchingIntervalParamNameActiveSuggestionsConsumer),
+ "Fill in all the info for fetching intervals.");
+
+base::TimeDelta GetDesiredFetchingInterval(
+ FetchingInterval interval,
UserClassifier::UserClass user_class) {
double default_value_hours = 0.0;
- const int index = is_wifi ? 1 : 0;
+ DCHECK(interval != FetchingInterval::COUNT);
+ const unsigned int index = static_cast<unsigned int>(interval);
+ DCHECK(index < arraysize(kDefaultFetchingIntervalRareNtpUser));
+
const char* param_name = nullptr;
switch (user_class) {
case UserClassifier::UserClass::RARE_NTP_USER:
@@ -70,17 +100,19 @@ base::TimeDelta GetDesiredUpdateInterval(
} // namespace
struct SchedulingRemoteSuggestionsProvider::FetchingSchedule {
- base::TimeDelta interval_wifi;
- base::TimeDelta interval_fallback;
+ base::TimeDelta interval_persistent_wifi;
+ base::TimeDelta interval_persistent_fallback;
+ base::TimeDelta interval_soft_on_usage_event;
static FetchingSchedule Empty() {
- return FetchingSchedule{base::TimeDelta(),
+ return FetchingSchedule{base::TimeDelta(), base::TimeDelta(),
base::TimeDelta()};
}
bool operator==(const FetchingSchedule& other) const {
- return interval_wifi == other.interval_wifi &&
- interval_fallback == other.interval_fallback;
+ return interval_persistent_wifi == other.interval_persistent_wifi &&
+ interval_persistent_fallback == other.interval_persistent_fallback &&
+ interval_soft_on_usage_event == other.interval_soft_on_usage_event;
}
bool operator!=(const FetchingSchedule& other) const {
@@ -88,7 +120,9 @@ struct SchedulingRemoteSuggestionsProvider::FetchingSchedule {
}
bool is_empty() const {
- return interval_wifi.is_zero() && interval_fallback.is_zero();
+ return interval_persistent_wifi.is_zero() &&
+ interval_persistent_fallback.is_zero() &&
+ interval_soft_on_usage_event.is_zero();
}
};
@@ -120,9 +154,12 @@ SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() =
// static
void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
PrefRegistrySimple* registry) {
- registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0);
- registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback,
+ registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0);
+ registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback,
+ 0);
+ registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
0);
+ registry->RegisterInt64Pref(prefs::kSnippetLastBackgroundFetchAttempt, 0);
}
void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
@@ -132,10 +169,7 @@ void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
}
void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() {
- provider_->RefetchInTheBackground(
- base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>(
- base::Bind(&SchedulingRemoteSuggestionsProvider::OnFetchCompleted,
- base::Unretained(this))));
+ RefetchInTheBackground(/*callback=*/nullptr);
}
void SchedulingRemoteSuggestionsProvider::OnBrowserStartup() {
@@ -143,17 +177,33 @@ void SchedulingRemoteSuggestionsProvider::OnBrowserStartup() {
}
void SchedulingRemoteSuggestionsProvider::OnNTPOpened() {
- // TODO(jkrcal): Implement.
+ if (!ShouldRefetchInTheBackgroundNow()) {
+ return;
+ }
+ RefetchInTheBackground(/*callback=*/nullptr);
}
void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback(
- std::unique_ptr<ProviderStatusCallback> callback) {
+ std::unique_ptr<ProviderStatusCallback> callback) {
provider_->SetProviderStatusCallback(std::move(callback));
}
void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground(
std::unique_ptr<FetchStatusCallback> callback) {
- provider_->RefetchInTheBackground(std::move(callback));
+ if (background_fetch_in_progress_) {
+ if (callback) {
+ callback->Run(
+ Status(StatusCode::TEMPORARY_ERROR, "Background fetch in progress"));
+ }
+ return;
+ }
+
+ RemoteSuggestionsProvider::FetchStatusCallback wrapper_callback = base::Bind(
+ &SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundFinished,
+ base::Unretained(this), base::Passed(&callback));
+ provider_->RefetchInTheBackground(
+ base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>(
+ std::move(wrapper_callback)));
}
const NTPSnippetsFetcher* SchedulingRemoteSuggestionsProvider::
@@ -237,41 +287,43 @@ void SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged(
}
void SchedulingRemoteSuggestionsProvider::StartScheduling() {
- // The scheduler only exists on Android so far, it's null on other platforms.
- if (!persistent_scheduler_) {
- return;
- }
-
FetchingSchedule last_schedule = GetLastFetchingSchedule();
FetchingSchedule schedule = GetDesiredFetchingSchedule();
// Reset the schedule only if the parameters have changed.
if (last_schedule != schedule) {
- ApplyFetchingSchedule(schedule);
+ ApplyFetchingSchedule(schedule, /*also_apply_persistent_schedule=*/true);
}
}
void SchedulingRemoteSuggestionsProvider::StopScheduling() {
- // The scheduler only exists on Android so far, it's null on other platforms.
- if (!persistent_scheduler_) {
- return;
- }
-
// Do not unschedule if already switched off
FetchingSchedule last_schedule = GetLastFetchingSchedule();
if (last_schedule.is_empty()) {
return;
}
- persistent_scheduler_->Unschedule();
+ pref_service_->ClearPref(prefs::kSnippetLastBackgroundFetchAttempt);
+
+ // The scheduler only exists on Android so far, it's null on other platforms.
+ if (persistent_scheduler_) {
+ persistent_scheduler_->Unschedule();
+ }
StoreLastFetchingSchedule(FetchingSchedule::Empty());
}
void SchedulingRemoteSuggestionsProvider::ApplyFetchingSchedule(
- const FetchingSchedule& schedule) {
- persistent_scheduler_->Schedule(schedule.interval_wifi,
- schedule.interval_fallback);
+ const FetchingSchedule& schedule,
+ bool also_apply_persistent_schedule) {
+ pref_service_->SetInt64(prefs::kSnippetLastBackgroundFetchAttempt,
tschumann 2017/01/03 18:54:25 from an offline discussion: We also call this on S
jkrcal 2017/01/04 10:06:30 Fixed, in the end.
+ base::Time::Now().ToInternalValue());
+
+ // The scheduler only exists on Android so far, it's null on other platforms.
+ if (persistent_scheduler_ && also_apply_persistent_schedule) {
+ persistent_scheduler_->Schedule(schedule.interval_persistent_wifi,
+ schedule.interval_persistent_fallback);
+ }
StoreLastFetchingSchedule(schedule);
}
@@ -281,58 +333,88 @@ SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const {
UserClassifier::UserClass user_class = user_classifier_->GetUserClass();
FetchingSchedule schedule;
- schedule.interval_wifi =
- GetDesiredUpdateInterval(/*is_wifi=*/true, user_class);
- schedule.interval_fallback =
- GetDesiredUpdateInterval(/*is_wifi=*/false, user_class);
+ schedule.interval_persistent_wifi =
+ GetDesiredFetchingInterval(FetchingInterval::PERSISTENT_WIFI, user_class);
+ schedule.interval_persistent_fallback = GetDesiredFetchingInterval(
+ FetchingInterval::PERSISTENT_FALLBACK, user_class);
+ schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval(
+ FetchingInterval::SOFT_ON_USAGE_EVENT, user_class);
+
return schedule;
}
SchedulingRemoteSuggestionsProvider::FetchingSchedule
SchedulingRemoteSuggestionsProvider::GetLastFetchingSchedule() const {
FetchingSchedule schedule;
- schedule.interval_wifi = base::TimeDelta::FromInternalValue(
- pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi));
- schedule.interval_fallback =
+ schedule.interval_persistent_wifi = base::TimeDelta::FromInternalValue(
+ pref_service_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi));
+ schedule.interval_persistent_fallback =
base::TimeDelta::FromInternalValue(pref_service_->GetInt64(
- prefs::kSnippetBackgroundFetchingIntervalFallback));
+ prefs::kSnippetPersistentFetchingIntervalFallback));
+ schedule.interval_soft_on_usage_event = base::TimeDelta::FromInternalValue(
+ pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnUsageEvent));
+
return schedule;
}
void SchedulingRemoteSuggestionsProvider::StoreLastFetchingSchedule(
const FetchingSchedule& schedule) {
+ pref_service_->SetInt64(prefs::kSnippetPersistentFetchingIntervalWifi,
+ schedule.interval_persistent_wifi.ToInternalValue());
pref_service_->SetInt64(
- prefs::kSnippetBackgroundFetchingIntervalWifi,
- schedule.interval_wifi.ToInternalValue());
+ prefs::kSnippetPersistentFetchingIntervalFallback,
+ schedule.interval_persistent_fallback.ToInternalValue());
pref_service_->SetInt64(
- prefs::kSnippetBackgroundFetchingIntervalFallback,
- schedule.interval_fallback.ToInternalValue());
+ prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
+ schedule.interval_soft_on_usage_event.ToInternalValue());
+}
+
+bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow() {
+ if (!pref_service_->HasPrefPath(prefs::kSnippetLastBackgroundFetchAttempt)) {
+ // Soft background fetches are switched off.
+ return false;
+ }
+
+ FetchingSchedule schedule = GetLastFetchingSchedule();
+
+ base::Time first_allowed_fetch_time =
+ base::Time::FromInternalValue(
+ pref_service_->GetInt64(prefs::kSnippetLastBackgroundFetchAttempt)) +
+ schedule.interval_soft_on_usage_event;
+ return first_allowed_fetch_time <= base::Time::Now();
}
void SchedulingRemoteSuggestionsProvider::FetchFinished(
const FetchDoneCallback& callback,
- Status status_code,
+ Status fetch_status,
std::vector<ContentSuggestion> suggestions) {
- OnFetchCompleted(status_code);
- callback.Run(status_code, std::move(suggestions));
+ // Reschedule after a fetch. The persistent schedule is applied only after a
+ // successful fetch. After a failed fetch, we want to keep the previous
+ // persistent schedule intact so that we eventually get a persistent fallback
+ // fetch (if the wifi persistent fetches keep failing).
+ ApplyFetchingSchedule(GetLastFetchingSchedule(),
+ /*also_apply_persistent_schedule=*/fetch_status.code ==
+ StatusCode::SUCCESS);
+
+ callback.Run(fetch_status, std::move(suggestions));
}
-void SchedulingRemoteSuggestionsProvider::OnFetchCompleted(
+void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundFinished(
+ std::unique_ptr<FetchStatusCallback> callback,
Status fetch_status) {
- // The scheduler only exists on Android so far, it's null on other platforms.
- if (!persistent_scheduler_) {
- return;
+ background_fetch_in_progress_ = false;
+
+ // Reschedule after a fetch. The persistent schedule is applied only after a
+ // successful fetch. After a failed fetch, we want to keep the previous
+ // persistent schedule intact so that we eventually get a persistent fallback
+ // fetch (if the wifi persistent fetches keep failing).
+ ApplyFetchingSchedule(GetLastFetchingSchedule(),
+ /*also_apply_persistent_schedule=*/fetch_status.code ==
+ StatusCode::SUCCESS);
+
+ if (callback) {
+ callback->Run(fetch_status);
}
-
- if (fetch_status.code != StatusCode::SUCCESS) {
- return;
- }
-
- // Reschedule after a successful fetch. This resets all currently scheduled
- // fetches, to make sure the fallback interval triggers only if no wifi fetch
- // succeeded, and also that we don't do a background fetch immediately after
- // a user-initiated one.
- ApplyFetchingSchedule(GetLastFetchingSchedule());
}
} // namespace ntp_snippets
« no previous file with comments | « components/ntp_snippets/remote/scheduling_remote_suggestions_provider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698