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

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: Tim's comments + unit-tests 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/default_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)
101 : RemoteSuggestionsProvider(observer), 134 : RemoteSuggestionsProvider(observer),
102 RemoteSuggestionsScheduler(), 135 RemoteSuggestionsScheduler(),
103 provider_(std::move(provider)), 136 provider_(std::move(provider)),
104 persistent_scheduler_(persistent_scheduler), 137 persistent_scheduler_(persistent_scheduler),
138 background_fetch_in_progress_(false),
105 user_classifier_(user_classifier), 139 user_classifier_(user_classifier),
106 pref_service_(pref_service) { 140 pref_service_(pref_service),
141 clock_(base::MakeUnique<base::DefaultClock>()) {
107 DCHECK(user_classifier); 142 DCHECK(user_classifier);
108 DCHECK(pref_service); 143 DCHECK(pref_service);
109 144
145 LoadLastFetchingSchedule();
146
110 provider_->SetProviderStatusCallback( 147 provider_->SetProviderStatusCallback(
111 base::MakeUnique<RemoteSuggestionsProvider::ProviderStatusCallback>( 148 base::MakeUnique<RemoteSuggestionsProvider::ProviderStatusCallback>(
112 base::BindRepeating( 149 base::BindRepeating(
113 &SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged, 150 &SchedulingRemoteSuggestionsProvider::OnProviderStatusChanged,
114 base::Unretained(this)))); 151 base::Unretained(this))));
115 } 152 }
116 153
117 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = 154 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() =
118 default; 155 default;
119 156
120 // static 157 // static
121 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( 158 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
122 PrefRegistrySimple* registry) { 159 PrefRegistrySimple* registry) {
123 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0); 160 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0);
124 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback, 161 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback,
125 0); 162 0);
163 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
164 0);
165 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0);
126 } 166 }
127 167
128 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() { 168 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() {
tschumann 2017/01/04 10:43:52 ultimatively, this method should go away, right? (
jkrcal 2017/01/04 14:19:03 No. This needs to be called when Chrome is updated
tschumann 2017/01/04 15:15:24 I see. Maybe we should rename this function then t
129 // Force the reschedule by stopping and starting it again. 169 // Force the reschedule by stopping and starting it again.
130 StopScheduling(); 170 StopScheduling();
131 StartScheduling(); 171 StartScheduling();
132 } 172 }
133 173
134 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() { 174 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() {
135 provider_->RefetchInTheBackground( 175 if (schedule_.is_empty()) {
tschumann 2017/01/04 10:43:52 can we wrap this in a helper method BackgroundFetc
jkrcal 2017/01/04 14:19:03 Done.
136 base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>( 176 return; // Persistent background fetches are switched off.
137 base::Bind(&SchedulingRemoteSuggestionsProvider::OnFetchCompleted, 177 }
138 base::Unretained(this)))); 178
179 RefetchInTheBackground(/*callback=*/nullptr);
139 } 180 }
140 181
141 void SchedulingRemoteSuggestionsProvider::OnBrowserStartup() { 182 void SchedulingRemoteSuggestionsProvider::OnBrowserStartup() {
142 // TODO(jkrcal): Implement. 183 // TODO(jkrcal): Implement.
143 } 184 }
144 185
145 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() { 186 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() {
146 // TODO(jkrcal): Implement. 187 if (schedule_.is_empty()) {
188 return; // Soft background fetches are switched off.
189 }
190
191 if (!ShouldRefetchInTheBackgroundNow()) {
192 return; // Not enough time has elapsed since last fetch attempt.
tschumann 2017/01/04 10:43:52 nit: let's remove this comment as it duplicates lo
jkrcal 2017/01/04 14:19:03 Good point, done.
193 }
194
195 RefetchInTheBackground(/*callback=*/nullptr);
147 } 196 }
148 197
149 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback( 198 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback(
150 std::unique_ptr<ProviderStatusCallback> callback) { 199 std::unique_ptr<ProviderStatusCallback> callback) {
151 provider_->SetProviderStatusCallback(std::move(callback)); 200 provider_->SetProviderStatusCallback(std::move(callback));
152 } 201 }
153 202
154 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground( 203 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground(
155 std::unique_ptr<FetchStatusCallback> callback) { 204 std::unique_ptr<FetchStatusCallback> callback) {
156 provider_->RefetchInTheBackground(std::move(callback)); 205 if (background_fetch_in_progress_) {
206 if (callback) {
207 callback->Run(
208 Status(StatusCode::TEMPORARY_ERROR, "Background fetch in progress"));
209 }
210 return;
211 }
212
213 RemoteSuggestionsProvider::FetchStatusCallback wrapper_callback = base::Bind(
214 &SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundFinished,
215 base::Unretained(this), base::Passed(&callback));
216 provider_->RefetchInTheBackground(
217 base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>(
218 std::move(wrapper_callback)));
157 } 219 }
158 220
159 const NTPSnippetsFetcher* SchedulingRemoteSuggestionsProvider:: 221 const NTPSnippetsFetcher* SchedulingRemoteSuggestionsProvider::
160 snippets_fetcher_for_testing_and_debugging() const { 222 snippets_fetcher_for_testing_and_debugging() const {
161 return provider_->snippets_fetcher_for_testing_and_debugging(); 223 return provider_->snippets_fetcher_for_testing_and_debugging();
162 } 224 }
163 225
164 CategoryStatus SchedulingRemoteSuggestionsProvider::GetCategoryStatus( 226 CategoryStatus SchedulingRemoteSuggestionsProvider::GetCategoryStatus(
165 Category category) { 227 Category category) {
166 return provider_->GetCategoryStatus(category); 228 return provider_->GetCategoryStatus(category);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 StartScheduling(); 292 StartScheduling();
231 return; 293 return;
232 case RemoteSuggestionsProvider::ProviderStatus::INACTIVE: 294 case RemoteSuggestionsProvider::ProviderStatus::INACTIVE:
233 StopScheduling(); 295 StopScheduling();
234 return; 296 return;
235 } 297 }
236 NOTREACHED(); 298 NOTREACHED();
237 } 299 }
238 300
239 void SchedulingRemoteSuggestionsProvider::StartScheduling() { 301 void SchedulingRemoteSuggestionsProvider::StartScheduling() {
240 // The scheduler only exists on Android so far, it's null on other platforms. 302 FetchingSchedule new_schedule = GetDesiredFetchingSchedule();
241 if (!persistent_scheduler_) { 303
304 if (schedule_ == new_schedule) {
305 // Do not schedule if nothing has changed;
242 return; 306 return;
243 } 307 }
244 308
245 FetchingSchedule last_schedule = GetLastFetchingSchedule(); 309 schedule_ = new_schedule;
246 FetchingSchedule schedule = GetDesiredFetchingSchedule(); 310 StoreFetchingSchedule();
311 ApplyFetchingSchedule(/*also_apply_persistent_schedule=*/true);
312 }
247 313
248 // Reset the schedule only if the parameters have changed. 314 void SchedulingRemoteSuggestionsProvider::StopScheduling() {
249 if (last_schedule != schedule) { 315 if (schedule_.is_empty()) {
250 ApplyFetchingSchedule(schedule); 316 // Do not unschedule if already switched off.
317 return;
318 }
319
320 schedule_ = FetchingSchedule::Empty();
321 StoreFetchingSchedule();
322 ApplyFetchingSchedule(/*also_apply_persistent_schedule=*/true);
323 }
324
325 void SchedulingRemoteSuggestionsProvider::ApplyFetchingSchedule(
tschumann 2017/01/04 10:43:52 Rename to ApplyPersistentFetchingSchedule and get
jkrcal 2017/01/04 14:19:03 Done.
326 bool also_apply_persistent_schedule) {
327 // The scheduler only exists on Android so far, it's null on other platforms.
328 if (persistent_scheduler_ && also_apply_persistent_schedule) {
329 if (schedule_.is_empty()) {
330 persistent_scheduler_->Unschedule();
331 } else {
332 persistent_scheduler_->Schedule(schedule_.interval_persistent_wifi,
333 schedule_.interval_persistent_fallback);
334 }
251 } 335 }
252 } 336 }
253 337
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 338 SchedulingRemoteSuggestionsProvider::FetchingSchedule
280 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const { 339 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const {
281 UserClassifier::UserClass user_class = user_classifier_->GetUserClass(); 340 UserClassifier::UserClass user_class = user_classifier_->GetUserClass();
282 341
283 FetchingSchedule schedule; 342 FetchingSchedule schedule;
284 schedule.interval_wifi = 343 schedule.interval_persistent_wifi =
285 GetDesiredUpdateInterval(/*is_wifi=*/true, user_class); 344 GetDesiredFetchingInterval(FetchingInterval::PERSISTENT_WIFI, user_class);
286 schedule.interval_fallback = 345 schedule.interval_persistent_fallback = GetDesiredFetchingInterval(
287 GetDesiredUpdateInterval(/*is_wifi=*/false, user_class); 346 FetchingInterval::PERSISTENT_FALLBACK, user_class);
347 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval(
348 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class);
349
288 return schedule; 350 return schedule;
289 } 351 }
290 352
291 SchedulingRemoteSuggestionsProvider::FetchingSchedule 353 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() {
292 SchedulingRemoteSuggestionsProvider::GetLastFetchingSchedule() const { 354 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue(
293 FetchingSchedule schedule; 355 pref_service_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi));
294 schedule.interval_wifi = base::TimeDelta::FromInternalValue( 356 schedule_.interval_persistent_fallback =
295 pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi));
296 schedule.interval_fallback =
297 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( 357 base::TimeDelta::FromInternalValue(pref_service_->GetInt64(
298 prefs::kSnippetBackgroundFetchingIntervalFallback)); 358 prefs::kSnippetPersistentFetchingIntervalFallback));
299 return schedule; 359 schedule_.interval_soft_on_usage_event = base::TimeDelta::FromInternalValue(
360 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnUsageEvent));
300 } 361 }
301 362
302 void SchedulingRemoteSuggestionsProvider::StoreLastFetchingSchedule( 363 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() {
303 const FetchingSchedule& schedule) { 364 pref_service_->SetInt64(prefs::kSnippetPersistentFetchingIntervalWifi,
365 schedule_.interval_persistent_wifi.ToInternalValue());
304 pref_service_->SetInt64( 366 pref_service_->SetInt64(
305 prefs::kSnippetBackgroundFetchingIntervalWifi, 367 prefs::kSnippetPersistentFetchingIntervalFallback,
306 schedule.interval_wifi.ToInternalValue()); 368 schedule_.interval_persistent_fallback.ToInternalValue());
307 pref_service_->SetInt64( 369 pref_service_->SetInt64(
308 prefs::kSnippetBackgroundFetchingIntervalFallback, 370 prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
309 schedule.interval_fallback.ToInternalValue()); 371 schedule_.interval_soft_on_usage_event.ToInternalValue());
372 }
373
374 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow() {
375 base::Time first_allowed_fetch_time =
376 base::Time::FromInternalValue(
377 pref_service_->GetInt64(prefs::kSnippetLastFetchAttempt)) +
378 schedule_.interval_soft_on_usage_event;
379 return first_allowed_fetch_time <= clock_->Now();
310 } 380 }
311 381
312 void SchedulingRemoteSuggestionsProvider::FetchFinished( 382 void SchedulingRemoteSuggestionsProvider::FetchFinished(
313 const FetchDoneCallback& callback, 383 const FetchDoneCallback& callback,
314 Status status_code, 384 Status fetch_status,
315 std::vector<ContentSuggestion> suggestions) { 385 std::vector<ContentSuggestion> suggestions) {
316 OnFetchCompleted(status_code); 386 OnFetchCompleted(fetch_status);
317 callback.Run(status_code, std::move(suggestions)); 387 callback.Run(fetch_status, std::move(suggestions));
tschumann 2017/01/04 10:43:52 should we also check for the empty callback?
jkrcal 2017/01/04 14:19:03 Done.
388 }
389
390 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundFinished(
391 std::unique_ptr<FetchStatusCallback> callback,
392 Status fetch_status) {
393 background_fetch_in_progress_ = false;
394 OnFetchCompleted(fetch_status);
395
396 if (callback) {
397 callback->Run(fetch_status);
398 }
318 } 399 }
319 400
320 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted( 401 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted(
321 Status fetch_status) { 402 Status fetch_status) {
322 // The scheduler only exists on Android so far, it's null on other platforms. 403 pref_service_->SetInt64(prefs::kSnippetLastFetchAttempt,
323 if (!persistent_scheduler_) { 404 clock_->Now().ToInternalValue());
324 return;
325 }
326 405
327 if (fetch_status.code != StatusCode::SUCCESS) { 406 // Reschedule after a fetch. The persistent schedule is applied only after a
328 return; 407 // successful fetch. After a failed fetch, we want to keep the previous
329 } 408 // persistent schedule intact so that we eventually get a persistent fallback
330 409 // fetch (if the wifi persistent fetches keep failing).
331 // Reschedule after a successful fetch. This resets all currently scheduled 410 ApplyFetchingSchedule(/*also_apply_persistent_schedule=*/fetch_status.code ==
332 // fetches, to make sure the fallback interval triggers only if no wifi fetch 411 StatusCode::SUCCESS);
333 // succeeded, and also that we don't do a background fetch immediately after
334 // a user-initiated one.
335 ApplyFetchingSchedule(GetLastFetchingSchedule());
336 } 412 }
337 413
338 } // namespace ntp_snippets 414 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698