| 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 da41c57c2008cba6287bb1f4b89684c8a79e956e..a746e7b02b297d01f0ce284f10b832aab7b9e3f8 100644
|
| --- a/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc
|
| +++ b/components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc
|
| @@ -9,6 +9,8 @@
|
| #include <utility>
|
|
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/metrics/histogram_macros.h"
|
| +#include "base/strings/string_split.h"
|
| #include "base/time/clock.h"
|
| #include "components/ntp_snippets/features.h"
|
| #include "components/ntp_snippets/pref_names.h"
|
| @@ -65,6 +67,13 @@ static_assert(
|
| arraysize(kFetchingIntervalParamNameActiveSuggestionsConsumer),
|
| "Fill in all the info for fetching intervals.");
|
|
|
| +const char* kTriggerTypeNames[] = {"persistent_scheduler_wake_up", "ntp_opened",
|
| + "browser_foregrounded",
|
| + "browser_cold_start"};
|
| +
|
| +const char* kTriggerTypesParamName = "scheduler_trigger_types";
|
| +const char* kTriggerTypesParamValueForEmptyList = "-";
|
| +
|
| base::TimeDelta GetDesiredFetchingInterval(
|
| FetchingInterval interval,
|
| UserClassifier::UserClass user_class) {
|
| @@ -125,6 +134,17 @@ bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::is_empty() const {
|
| interval_soft_on_usage_event.is_zero();
|
| }
|
|
|
| +// These values are written to logs. New enum values can be added, but existing
|
| +// enums must never be renumbered or deleted and reused. When adding new
|
| +// entries, also update the array |kTriggerTypeNames| above.
|
| +enum class SchedulingRemoteSuggestionsProvider::TriggerType {
|
| + PERSISTENT_SCHEDULER_WAKE_UP = 0,
|
| + NTP_OPENED = 1,
|
| + BROWSER_FOREGROUNDED = 2,
|
| + BROWSER_COLD_START = 3,
|
| + COUNT
|
| +};
|
| +
|
| SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider(
|
| Observer* observer,
|
| std::unique_ptr<RemoteSuggestionsProvider> provider,
|
| @@ -139,7 +159,8 @@ SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider(
|
| background_fetch_in_progress_(false),
|
| user_classifier_(user_classifier),
|
| pref_service_(pref_service),
|
| - clock_(std::move(clock)) {
|
| + clock_(std::move(clock)),
|
| + enabled_triggers_(GetEnabledTriggerTypes()) {
|
| DCHECK(user_classifier);
|
| DCHECK(pref_service);
|
|
|
| @@ -173,31 +194,35 @@ void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
|
| }
|
|
|
| void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() {
|
| - if (BackgroundFetchesDisabled()) {
|
| - return;
|
| - }
|
| -
|
| - RefetchInTheBackground(/*callback=*/nullptr);
|
| + RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP);
|
| }
|
|
|
| void SchedulingRemoteSuggestionsProvider::OnBrowserForegrounded() {
|
| // TODO(jkrcal): Consider that this is called whenever we open or return to an
|
| // Activity. Therefore, keep work light for fast start up calls.
|
| - // TODO(jkrcal): Implement.
|
| + if (!ShouldRefetchInTheBackgroundNow()) {
|
| + return;
|
| + }
|
| +
|
| + RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_FOREGROUNDED);
|
| }
|
|
|
| void SchedulingRemoteSuggestionsProvider::OnBrowserColdStart() {
|
| // TODO(fhorschig|jkrcal): Consider that work here must be kept light for fast
|
| // cold start ups.
|
| - // TODO(jkrcal): Implement.
|
| + if (!ShouldRefetchInTheBackgroundNow()) {
|
| + return;
|
| + }
|
| +
|
| + RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_COLD_START);
|
| }
|
|
|
| void SchedulingRemoteSuggestionsProvider::OnNTPOpened() {
|
| - if (BackgroundFetchesDisabled() || !ShouldRefetchInTheBackgroundNow()) {
|
| + if (!ShouldRefetchInTheBackgroundNow()) {
|
| return;
|
| }
|
|
|
| - RefetchInTheBackground(/*callback=*/nullptr);
|
| + RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED);
|
| }
|
|
|
| void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback(
|
| @@ -376,8 +401,17 @@ void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() {
|
| schedule_.interval_soft_on_usage_event.ToInternalValue());
|
| }
|
|
|
| -bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled() const {
|
| - return schedule_.is_empty();
|
| +void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled(
|
| + SchedulingRemoteSuggestionsProvider::TriggerType trigger) {
|
| + if (BackgroundFetchesDisabled(trigger)) {
|
| + return;
|
| + }
|
| +
|
| + UMA_HISTOGRAM_ENUMERATION(
|
| + "NewTabPage.ContentSuggestions.BackgroundFetchTrigger",
|
| + static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT));
|
| +
|
| + RefetchInTheBackground(/*callback=*/nullptr);
|
| }
|
|
|
| bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow() {
|
| @@ -388,6 +422,18 @@ bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow() {
|
| return first_allowed_fetch_time <= clock_->Now();
|
| }
|
|
|
| +bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled(
|
| + SchedulingRemoteSuggestionsProvider::TriggerType trigger) const {
|
| + if (schedule_.is_empty()) {
|
| + return true; // Background fetches are disabled in general.
|
| + }
|
| +
|
| + if (enabled_triggers_.count(trigger) == 0) {
|
| + return true; // Background fetches for |trigger| are not enabled.
|
| + }
|
| + return false;
|
| +}
|
| +
|
| void SchedulingRemoteSuggestionsProvider::FetchFinished(
|
| const FetchDoneCallback& callback,
|
| Status fetch_status,
|
| @@ -423,4 +469,49 @@ void SchedulingRemoteSuggestionsProvider::OnFetchCompleted(
|
| ApplyPersistentFetchingSchedule();
|
| }
|
|
|
| +std::set<SchedulingRemoteSuggestionsProvider::TriggerType>
|
| +SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() {
|
| + static_assert(static_cast<unsigned int>(TriggerType::COUNT) ==
|
| + arraysize(kTriggerTypeNames),
|
| + "Fill in names for trigger types.");
|
| +
|
| + std::string param_value = variations::GetVariationParamValueByFeature(
|
| + ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName);
|
| + if (param_value == kTriggerTypesParamValueForEmptyList) {
|
| + return std::set<TriggerType>();
|
| + }
|
| +
|
| + std::vector<std::string> tokens = base::SplitString(
|
| + param_value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
| + if (tokens.empty()) {
|
| + return GetDefaultEnabledTriggerTypes();
|
| + }
|
| +
|
| + std::set<TriggerType> enabled_types;
|
| + for (const auto& token : tokens) {
|
| + auto it = std::find(std::begin(kTriggerTypeNames),
|
| + std::end(kTriggerTypeNames), token);
|
| + if (it == std::end(kTriggerTypeNames)) {
|
| + DLOG(WARNING) << "Failed to parse variation param "
|
| + << kTriggerTypesParamName << " with string value "
|
| + << param_value
|
| + << " into a comma-separated list of keywords. "
|
| + << "Unknown token " << token
|
| + << " found. Falling back to default value.";
|
| + return GetDefaultEnabledTriggerTypes();
|
| + }
|
| +
|
| + // Add the enabled type represented by |token| into the result set.
|
| + enabled_types.insert(
|
| + static_cast<TriggerType>(it - std::begin(kTriggerTypeNames)));
|
| + }
|
| + return enabled_types;
|
| +}
|
| +
|
| +std::set<SchedulingRemoteSuggestionsProvider::TriggerType>
|
| +SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() {
|
| + return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED,
|
| + TriggerType::BROWSER_FOREGROUNDED};
|
| +}
|
| +
|
| } // namespace ntp_snippets
|
|
|