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

Side by Side Diff: components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc

Issue 2611523004: [Background fetching] Background fetching when opening an NTP. (Closed)
Patch Set: Rebase Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h" 5 #include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h"
6 6
7 #include <random>
7 #include <string> 8 #include <string>
8 #include <utility> 9 #include <utility>
9 10
10 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/time/clock.h"
11 #include "components/ntp_snippets/features.h" 13 #include "components/ntp_snippets/features.h"
12 #include "components/ntp_snippets/pref_names.h" 14 #include "components/ntp_snippets/pref_names.h"
13 #include "components/ntp_snippets/remote/persistent_scheduler.h" 15 #include "components/ntp_snippets/remote/persistent_scheduler.h"
14 #include "components/ntp_snippets/status.h" 16 #include "components/ntp_snippets/status.h"
15 #include "components/ntp_snippets/user_classifier.h" 17 #include "components/ntp_snippets/user_classifier.h"
16 #include "components/prefs/pref_registry_simple.h" 18 #include "components/prefs/pref_registry_simple.h"
17 #include "components/prefs/pref_service.h" 19 #include "components/prefs/pref_service.h"
18 #include "components/variations/variations_associated_data.h" 20 #include "components/variations/variations_associated_data.h"
19 21
20 namespace ntp_snippets { 22 namespace ntp_snippets {
21 23
22 namespace { 24 namespace {
23 25
26 enum class FetchingInterval {
27 PERSISTENT_FALLBACK,
28 PERSISTENT_WIFI,
29 SOFT_ON_USAGE_EVENT,
30 COUNT
31 };
32
24 // Default values for fetching intervals, fallback and wifi. 33 // Default values for fetching intervals, fallback and wifi.
25 const double kDefaultFetchingIntervalRareNtpUser[] = {48.0, 24.0}; 34 const double kDefaultFetchingIntervalRareNtpUser[] = {48.0, 24.0, 12.0};
26 const double kDefaultFetchingIntervalActiveNtpUser[] = {24.0, 6.0}; 35 const double kDefaultFetchingIntervalActiveNtpUser[] = {24.0, 6.0, 2.0};
27 const double kDefaultFetchingIntervalActiveSuggestionsConsumer[] = {24.0, 6.0}; 36 const double kDefaultFetchingIntervalActiveSuggestionsConsumer[] = {24.0, 6.0,
37 2.0};
28 38
29 // Variation parameters than can the default fetching intervals. 39 // Variation parameters than can the default fetching intervals.
30 const char* kFetchingIntervalParamNameRareNtpUser[] = { 40 const char* kFetchingIntervalParamNameRareNtpUser[] = {
31 "fetching_interval_hours-fallback-rare_ntp_user", 41 "fetching_interval_hours-fallback-rare_ntp_user",
32 "fetching_interval_hours-wifi-rare_ntp_user"}; 42 "fetching_interval_hours-wifi-rare_ntp_user",
43 "soft_fetching_interval_hours-active-rare_ntp_user"};
33 const char* kFetchingIntervalParamNameActiveNtpUser[] = { 44 const char* kFetchingIntervalParamNameActiveNtpUser[] = {
34 "fetching_interval_hours-fallback-active_ntp_user", 45 "fetching_interval_hours-fallback-active_ntp_user",
35 "fetching_interval_hours-wifi-active_ntp_user"}; 46 "fetching_interval_hours-wifi-active_ntp_user",
47 "soft_fetching_interval_hours-active-active_ntp_user"};
36 const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = { 48 const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = {
37 "fetching_interval_hours-fallback-active_suggestions_consumer", 49 "fetching_interval_hours-fallback-active_suggestions_consumer",
38 "fetching_interval_hours-wifi-active_suggestions_consumer"}; 50 "fetching_interval_hours-wifi-active_suggestions_consumer",
51 "soft_fetching_interval_hours-active-active_suggestions_consumer"};
39 52
40 base::TimeDelta GetDesiredUpdateInterval( 53 static_assert(
41 bool is_wifi, 54 static_cast<unsigned int>(FetchingInterval::COUNT) ==
55 arraysize(kDefaultFetchingIntervalRareNtpUser) &&
56 static_cast<unsigned int>(FetchingInterval::COUNT) ==
57 arraysize(kDefaultFetchingIntervalActiveNtpUser) &&
58 static_cast<unsigned int>(FetchingInterval::COUNT) ==
59 arraysize(kDefaultFetchingIntervalActiveSuggestionsConsumer) &&
60 static_cast<unsigned int>(FetchingInterval::COUNT) ==
61 arraysize(kFetchingIntervalParamNameRareNtpUser) &&
62 static_cast<unsigned int>(FetchingInterval::COUNT) ==
63 arraysize(kFetchingIntervalParamNameActiveNtpUser) &&
64 static_cast<unsigned int>(FetchingInterval::COUNT) ==
65 arraysize(kFetchingIntervalParamNameActiveSuggestionsConsumer),
66 "Fill in all the info for fetching intervals.");
67
68 base::TimeDelta GetDesiredFetchingInterval(
69 FetchingInterval interval,
42 UserClassifier::UserClass user_class) { 70 UserClassifier::UserClass user_class) {
43 double default_value_hours = 0.0; 71 double default_value_hours = 0.0;
44 72
45 const int index = is_wifi ? 1 : 0; 73 DCHECK(interval != FetchingInterval::COUNT);
74 const unsigned int index = static_cast<unsigned int>(interval);
75 DCHECK(index < arraysize(kDefaultFetchingIntervalRareNtpUser));
76
46 const char* param_name = nullptr; 77 const char* param_name = nullptr;
47 switch (user_class) { 78 switch (user_class) {
48 case UserClassifier::UserClass::RARE_NTP_USER: 79 case UserClassifier::UserClass::RARE_NTP_USER:
49 default_value_hours = kDefaultFetchingIntervalRareNtpUser[index]; 80 default_value_hours = kDefaultFetchingIntervalRareNtpUser[index];
50 param_name = kFetchingIntervalParamNameRareNtpUser[index]; 81 param_name = kFetchingIntervalParamNameRareNtpUser[index];
51 break; 82 break;
52 case UserClassifier::UserClass::ACTIVE_NTP_USER: 83 case UserClassifier::UserClass::ACTIVE_NTP_USER:
53 default_value_hours = kDefaultFetchingIntervalActiveNtpUser[index]; 84 default_value_hours = kDefaultFetchingIntervalActiveNtpUser[index];
54 param_name = kFetchingIntervalParamNameActiveNtpUser[index]; 85 param_name = kFetchingIntervalParamNameActiveNtpUser[index];
55 break; 86 break;
56 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: 87 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER:
57 default_value_hours = 88 default_value_hours =
58 kDefaultFetchingIntervalActiveSuggestionsConsumer[index]; 89 kDefaultFetchingIntervalActiveSuggestionsConsumer[index];
59 param_name = kFetchingIntervalParamNameActiveSuggestionsConsumer[index]; 90 param_name = kFetchingIntervalParamNameActiveSuggestionsConsumer[index];
60 break; 91 break;
61 } 92 }
62 93
63 double value_hours = variations::GetVariationParamByFeatureAsDouble( 94 double value_hours = variations::GetVariationParamByFeatureAsDouble(
64 ntp_snippets::kArticleSuggestionsFeature, param_name, 95 ntp_snippets::kArticleSuggestionsFeature, param_name,
65 default_value_hours); 96 default_value_hours);
66 97
67 return base::TimeDelta::FromSecondsD(value_hours * 3600.0); 98 return base::TimeDelta::FromSecondsD(value_hours * 3600.0);
68 } 99 }
69 100
70 } // namespace 101 } // namespace
71 102
72 struct SchedulingRemoteSuggestionsProvider::FetchingSchedule { 103 // static
73 base::TimeDelta interval_wifi; 104 SchedulingRemoteSuggestionsProvider::FetchingSchedule
74 base::TimeDelta interval_fallback; 105 SchedulingRemoteSuggestionsProvider::FetchingSchedule::Empty() {
106 return FetchingSchedule{base::TimeDelta(), base::TimeDelta(),
107 base::TimeDelta()};
108 }
75 109
76 static FetchingSchedule Empty() { 110 bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::operator==(
77 return FetchingSchedule{base::TimeDelta(), 111 const FetchingSchedule& other) const {
78 base::TimeDelta()}; 112 return interval_persistent_wifi == other.interval_persistent_wifi &&
79 } 113 interval_persistent_fallback == other.interval_persistent_fallback &&
114 interval_soft_on_usage_event == other.interval_soft_on_usage_event;
115 }
80 116
81 bool operator==(const FetchingSchedule& other) const { 117 bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::operator!=(
82 return interval_wifi == other.interval_wifi && 118 const FetchingSchedule& other) const {
83 interval_fallback == other.interval_fallback; 119 return !operator==(other);
84 } 120 }
85 121
86 bool operator!=(const FetchingSchedule& other) const { 122 bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::is_empty() const {
87 return !operator==(other); 123 return interval_persistent_wifi.is_zero() &&
88 } 124 interval_persistent_fallback.is_zero() &&
89 125 interval_soft_on_usage_event.is_zero();
90 bool is_empty() const { 126 }
91 return interval_wifi.is_zero() && interval_fallback.is_zero();
92 }
93 };
94 127
95 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider( 128 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider(
96 Observer* observer, 129 Observer* observer,
97 std::unique_ptr<RemoteSuggestionsProvider> provider, 130 std::unique_ptr<RemoteSuggestionsProvider> provider,
98 PersistentScheduler* persistent_scheduler, 131 PersistentScheduler* persistent_scheduler,
99 const UserClassifier* user_classifier, 132 const UserClassifier* user_classifier,
100 PrefService* pref_service) 133 PrefService* pref_service,
134 std::unique_ptr<base::Clock> clock)
101 : RemoteSuggestionsProvider(observer), 135 : RemoteSuggestionsProvider(observer),
102 RemoteSuggestionsScheduler(), 136 RemoteSuggestionsScheduler(),
103 provider_(std::move(provider)), 137 provider_(std::move(provider)),
104 persistent_scheduler_(persistent_scheduler), 138 persistent_scheduler_(persistent_scheduler),
139 background_fetch_in_progress_(false),
105 user_classifier_(user_classifier), 140 user_classifier_(user_classifier),
106 pref_service_(pref_service) { 141 pref_service_(pref_service),
142 clock_(std::move(clock)) {
107 DCHECK(user_classifier); 143 DCHECK(user_classifier);
108 DCHECK(pref_service); 144 DCHECK(pref_service);
109 145
146 LoadLastFetchingSchedule();
147
110 provider_->SetProviderStatusCallback( 148 provider_->SetProviderStatusCallback(
111 base::MakeUnique<RemoteSuggestionsProvider::ProviderStatusCallback>( 149 base::MakeUnique<RemoteSuggestionsProvider::ProviderStatusCallback>(
112 base::BindRepeating( 150 base::BindRepeating(
113 &SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged, 151 &SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged,
114 base::Unretained(this)))); 152 base::Unretained(this))));
115 } 153 }
116 154
117 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = 155 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() =
118 default; 156 default;
119 157
120 // static 158 // static
121 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( 159 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
122 PrefRegistrySimple* registry) { 160 PrefRegistrySimple* registry) {
123 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0); 161 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0);
124 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback, 162 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback,
125 0); 163 0);
164 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
165 0);
166 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0);
126 } 167 }
127 168
128 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() { 169 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
129 // Force the reschedule by stopping and starting it again. 170 // Force the reschedule by stopping and starting it again.
130 StopScheduling(); 171 StopScheduling();
131 StartScheduling(); 172 StartScheduling();
132 } 173 }
133 174
134 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() { 175 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() {
135 provider_->RefetchInTheBackground( 176 if (BackgroundFetchesDisabled()) {
136 base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>( 177 return;
137 base::Bind(&SchedulingRemoteSuggestionsProvider::OnFetchCompleted, 178 }
138 base::Unretained(this)))); 179
180 RefetchInTheBackground(/*callback=*/nullptr);
139 } 181 }
140 182
141 void SchedulingRemoteSuggestionsProvider::OnBrowserStartup() { 183 void SchedulingRemoteSuggestionsProvider::OnBrowserStartup() {
142 // TODO(jkrcal): Implement. 184 // TODO(jkrcal): Implement.
143 } 185 }
144 186
145 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() { 187 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() {
146 // TODO(jkrcal): Implement. 188 if (BackgroundFetchesDisabled() || !ShouldRefetchInTheBackgroundNow()) {
189 return;
190 }
191
192 RefetchInTheBackground(/*callback=*/nullptr);
147 } 193 }
148 194
149 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback( 195 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback(
150 std::unique_ptr<ProviderStatusCallback> callback) { 196 std::unique_ptr<ProviderStatusCallback> callback) {
151 provider_->SetProviderStatusCallback(std::move(callback)); 197 provider_->SetProviderStatusCallback(std::move(callback));
152 } 198 }
153 199
154 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground( 200 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground(
155 std::unique_ptr<FetchStatusCallback> callback) { 201 std::unique_ptr<FetchStatusCallback> callback) {
156 provider_->RefetchInTheBackground(std::move(callback)); 202 if (background_fetch_in_progress_) {
203 if (callback) {
204 callback->Run(
205 Status(StatusCode::TEMPORARY_ERROR, "Background fetch in progress"));
206 }
207 return;
208 }
209
210 background_fetch_in_progress_ = true;
211 RemoteSuggestionsProvider::FetchStatusCallback wrapper_callback = base::Bind(
212 &SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundFinished,
213 base::Unretained(this), base::Passed(&callback));
214 provider_->RefetchInTheBackground(
215 base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>(
216 std::move(wrapper_callback)));
157 } 217 }
158 218
159 const NTPSnippetsFetcher* SchedulingRemoteSuggestionsProvider:: 219 const NTPSnippetsFetcher* SchedulingRemoteSuggestionsProvider::
160 snippets_fetcher_for_testing_and_debugging() const { 220 snippets_fetcher_for_testing_and_debugging() const {
161 return provider_->snippets_fetcher_for_testing_and_debugging(); 221 return provider_->snippets_fetcher_for_testing_and_debugging();
162 } 222 }
163 223
164 CategoryStatus SchedulingRemoteSuggestionsProvider::GetCategoryStatus( 224 CategoryStatus SchedulingRemoteSuggestionsProvider::GetCategoryStatus(
165 Category category) { 225 Category category) {
166 return provider_->GetCategoryStatus(category); 226 return provider_->GetCategoryStatus(category);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 StartScheduling(); 290 StartScheduling();
231 return; 291 return;
232 case RemoteSuggestionsProvider::ProviderStatus::INACTIVE: 292 case RemoteSuggestionsProvider::ProviderStatus::INACTIVE:
233 StopScheduling(); 293 StopScheduling();
234 return; 294 return;
235 } 295 }
236 NOTREACHED(); 296 NOTREACHED();
237 } 297 }
238 298
239 void SchedulingRemoteSuggestionsProvider::StartScheduling() { 299 void SchedulingRemoteSuggestionsProvider::StartScheduling() {
240 // The scheduler only exists on Android so far, it's null on other platforms. 300 FetchingSchedule new_schedule = GetDesiredFetchingSchedule();
241 if (!persistent_scheduler_) { 301
302 if (schedule_ == new_schedule) {
303 // Do not schedule if nothing has changed;
242 return; 304 return;
243 } 305 }
244 306
245 FetchingSchedule last_schedule = GetLastFetchingSchedule(); 307 schedule_ = new_schedule;
246 FetchingSchedule schedule = GetDesiredFetchingSchedule(); 308 StoreFetchingSchedule();
309 ApplyPersistentFetchingSchedule();
310 }
247 311
248 // Reset the schedule only if the parameters have changed. 312 void SchedulingRemoteSuggestionsProvider::StopScheduling() {
249 if (last_schedule != schedule) { 313 if (schedule_.is_empty()) {
250 ApplyFetchingSchedule(schedule); 314 // Do not unschedule if already switched off.
315 return;
316 }
317
318 schedule_ = FetchingSchedule::Empty();
319 StoreFetchingSchedule();
320 ApplyPersistentFetchingSchedule();
321 }
322
323 void SchedulingRemoteSuggestionsProvider::ApplyPersistentFetchingSchedule() {
324 // The scheduler only exists on Android so far, it's null on other platforms.
325 if (persistent_scheduler_) {
326 if (schedule_.is_empty()) {
327 persistent_scheduler_->Unschedule();
328 } else {
329 persistent_scheduler_->Schedule(schedule_.interval_persistent_wifi,
330 schedule_.interval_persistent_fallback);
331 }
251 } 332 }
252 } 333 }
253 334
254 void SchedulingRemoteSuggestionsProvider::StopScheduling() {
255 // The scheduler only exists on Android so far, it's null on other platforms.
256 if (!persistent_scheduler_) {
257 return;
258 }
259
260 // Do not unschedule if already switched off
261 FetchingSchedule last_schedule = GetLastFetchingSchedule();
262 if (last_schedule.is_empty()) {
263 return;
264 }
265
266 persistent_scheduler_->Unschedule();
267
268 StoreLastFetchingSchedule(FetchingSchedule::Empty());
269 }
270
271 void SchedulingRemoteSuggestionsProvider::ApplyFetchingSchedule(
272 const FetchingSchedule& schedule) {
273 persistent_scheduler_->Schedule(schedule.interval_wifi,
274 schedule.interval_fallback);
275
276 StoreLastFetchingSchedule(schedule);
277 }
278
279 SchedulingRemoteSuggestionsProvider::FetchingSchedule 335 SchedulingRemoteSuggestionsProvider::FetchingSchedule
280 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const { 336 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const {
281 UserClassifier::UserClass user_class = user_classifier_->GetUserClass(); 337 UserClassifier::UserClass user_class = user_classifier_->GetUserClass();
282 338
283 FetchingSchedule schedule; 339 FetchingSchedule schedule;
284 schedule.interval_wifi = 340 schedule.interval_persistent_wifi =
285 GetDesiredUpdateInterval(/*is_wifi=*/true, user_class); 341 GetDesiredFetchingInterval(FetchingInterval::PERSISTENT_WIFI, user_class);
286 schedule.interval_fallback = 342 schedule.interval_persistent_fallback = GetDesiredFetchingInterval(
287 GetDesiredUpdateInterval(/*is_wifi=*/false, user_class); 343 FetchingInterval::PERSISTENT_FALLBACK, user_class);
344 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval(
345 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class);
346
288 return schedule; 347 return schedule;
289 } 348 }
290 349
291 SchedulingRemoteSuggestionsProvider::FetchingSchedule 350 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() {
292 SchedulingRemoteSuggestionsProvider::GetLastFetchingSchedule() const { 351 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue(
293 FetchingSchedule schedule; 352 pref_service_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi));
294 schedule.interval_wifi = base::TimeDelta::FromInternalValue( 353 schedule_.interval_persistent_fallback =
295 pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi));
296 schedule.interval_fallback =
297 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( 354 base::TimeDelta::FromInternalValue(pref_service_->GetInt64(
298 prefs::kSnippetBackgroundFetchingIntervalFallback)); 355 prefs::kSnippetPersistentFetchingIntervalFallback));
299 return schedule; 356 schedule_.interval_soft_on_usage_event = base::TimeDelta::FromInternalValue(
357 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnUsageEvent));
300 } 358 }
301 359
302 void SchedulingRemoteSuggestionsProvider::StoreLastFetchingSchedule( 360 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() {
303 const FetchingSchedule& schedule) { 361 pref_service_->SetInt64(prefs::kSnippetPersistentFetchingIntervalWifi,
362 schedule_.interval_persistent_wifi.ToInternalValue());
304 pref_service_->SetInt64( 363 pref_service_->SetInt64(
305 prefs::kSnippetBackgroundFetchingIntervalWifi, 364 prefs::kSnippetPersistentFetchingIntervalFallback,
306 schedule.interval_wifi.ToInternalValue()); 365 schedule_.interval_persistent_fallback.ToInternalValue());
307 pref_service_->SetInt64( 366 pref_service_->SetInt64(
308 prefs::kSnippetBackgroundFetchingIntervalFallback, 367 prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
309 schedule.interval_fallback.ToInternalValue()); 368 schedule_.interval_soft_on_usage_event.ToInternalValue());
369 }
370
371 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled() const {
372 return schedule_.is_empty();
373 }
374
375 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow() {
376 base::Time first_allowed_fetch_time =
377 base::Time::FromInternalValue(
378 pref_service_->GetInt64(prefs::kSnippetLastFetchAttempt)) +
379 schedule_.interval_soft_on_usage_event;
380 return first_allowed_fetch_time <= clock_->Now();
310 } 381 }
311 382
312 void SchedulingRemoteSuggestionsProvider::FetchFinished( 383 void SchedulingRemoteSuggestionsProvider::FetchFinished(
313 const FetchDoneCallback& callback, 384 const FetchDoneCallback& callback,
314 Status status_code, 385 Status fetch_status,
315 std::vector<ContentSuggestion> suggestions) { 386 std::vector<ContentSuggestion> suggestions) {
316 OnFetchCompleted(status_code); 387 OnFetchCompleted(fetch_status);
317 callback.Run(status_code, std::move(suggestions)); 388 if (callback) {
389 callback.Run(fetch_status, std::move(suggestions));
390 }
391 }
392
393 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundFinished(
394 std::unique_ptr<FetchStatusCallback> callback,
395 Status fetch_status) {
396 background_fetch_in_progress_ = false;
397 OnFetchCompleted(fetch_status);
398 if (callback) {
399 callback->Run(fetch_status);
400 }
318 } 401 }
319 402
320 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted( 403 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted(
321 Status fetch_status) { 404 Status fetch_status) {
322 // The scheduler only exists on Android so far, it's null on other platforms. 405 pref_service_->SetInt64(prefs::kSnippetLastFetchAttempt,
323 if (!persistent_scheduler_) { 406 clock_->Now().ToInternalValue());
324 return;
325 }
326 407
408 // Reschedule after a fetch. The persistent schedule is applied only after a
409 // successful fetch. After a failed fetch, we want to keep the previous
410 // persistent schedule intact so that we eventually get a persistent
411 // fallback fetch (if the wifi persistent fetches keep failing).
327 if (fetch_status.code != StatusCode::SUCCESS) { 412 if (fetch_status.code != StatusCode::SUCCESS) {
328 return; 413 return;
329 } 414 }
330 415 ApplyPersistentFetchingSchedule();
331 // Reschedule after a successful fetch. This resets all currently scheduled
332 // fetches, to make sure the fallback interval triggers only if no wifi fetch
333 // succeeded, and also that we don't do a background fetch immediately after
334 // a user-initiated one.
335 ApplyFetchingSchedule(GetLastFetchingSchedule());
336 } 416 }
337 417
338 } // namespace ntp_snippets 418 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698