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

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

Issue 2774663002: [Remote suggestions] Refactor the scheduler (Closed)
Patch Set: Fix iOS compile Created 3 years, 8 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/remote_suggestions_scheduler_impl.h"
6 6
7 #include <random> 7 #include <random>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/metrics/field_trial_params.h" 13 #include "base/metrics/field_trial_params.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 165 }
166 166
167 private: 167 private:
168 std::unique_ptr<web_resource::EulaAcceptedNotifier> eula_notifier_; 168 std::unique_ptr<web_resource::EulaAcceptedNotifier> eula_notifier_;
169 RemoteSuggestionsScheduler* scheduler_; 169 RemoteSuggestionsScheduler* scheduler_;
170 170
171 DISALLOW_COPY_AND_ASSIGN(EulaState); 171 DISALLOW_COPY_AND_ASSIGN(EulaState);
172 }; 172 };
173 173
174 // static 174 // static
175 SchedulingRemoteSuggestionsProvider::FetchingSchedule 175 RemoteSuggestionsSchedulerImpl::FetchingSchedule
176 SchedulingRemoteSuggestionsProvider::FetchingSchedule::Empty() { 176 RemoteSuggestionsSchedulerImpl::FetchingSchedule::Empty() {
177 return FetchingSchedule{base::TimeDelta(), base::TimeDelta(), 177 return FetchingSchedule{base::TimeDelta(), base::TimeDelta(),
178 base::TimeDelta(), base::TimeDelta()}; 178 base::TimeDelta(), base::TimeDelta()};
179 } 179 }
180 180
181 bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::operator==( 181 bool RemoteSuggestionsSchedulerImpl::FetchingSchedule::operator==(
182 const FetchingSchedule& other) const { 182 const FetchingSchedule& other) const {
183 return interval_persistent_wifi == other.interval_persistent_wifi && 183 return interval_persistent_wifi == other.interval_persistent_wifi &&
184 interval_persistent_fallback == other.interval_persistent_fallback && 184 interval_persistent_fallback == other.interval_persistent_fallback &&
185 interval_soft_on_usage_event == other.interval_soft_on_usage_event && 185 interval_soft_on_usage_event == other.interval_soft_on_usage_event &&
186 interval_soft_on_ntp_opened == other.interval_soft_on_ntp_opened; 186 interval_soft_on_ntp_opened == other.interval_soft_on_ntp_opened;
187 } 187 }
188 188
189 bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::operator!=( 189 bool RemoteSuggestionsSchedulerImpl::FetchingSchedule::operator!=(
190 const FetchingSchedule& other) const { 190 const FetchingSchedule& other) const {
191 return !operator==(other); 191 return !operator==(other);
192 } 192 }
193 193
194 bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::is_empty() const { 194 bool RemoteSuggestionsSchedulerImpl::FetchingSchedule::is_empty() const {
195 return interval_persistent_wifi.is_zero() && 195 return interval_persistent_wifi.is_zero() &&
196 interval_persistent_fallback.is_zero() && 196 interval_persistent_fallback.is_zero() &&
197 interval_soft_on_usage_event.is_zero() && 197 interval_soft_on_usage_event.is_zero() &&
198 interval_soft_on_ntp_opened.is_zero(); 198 interval_soft_on_ntp_opened.is_zero();
199 } 199 }
200 200
201 // The TriggerType enum specifies values for the events that can trigger 201 // The TriggerType enum specifies values for the events that can trigger
202 // fetching remote suggestions. These values are written to logs. New enum 202 // fetching remote suggestions. These values are written to logs. New enum
203 // values can be added, but existing enums must never be renumbered or deleted 203 // values can be added, but existing enums must never be renumbered or deleted
204 // and reused. When adding new entries, also update the array 204 // and reused. When adding new entries, also update the array
205 // |kTriggerTypeNames| above. 205 // |kTriggerTypeNames| above.
206 enum class SchedulingRemoteSuggestionsProvider::TriggerType { 206 enum class RemoteSuggestionsSchedulerImpl::TriggerType {
207 PERSISTENT_SCHEDULER_WAKE_UP = 0, 207 PERSISTENT_SCHEDULER_WAKE_UP = 0,
208 NTP_OPENED = 1, 208 NTP_OPENED = 1,
209 BROWSER_FOREGROUNDED = 2, 209 BROWSER_FOREGROUNDED = 2,
210 BROWSER_COLD_START = 3, 210 BROWSER_COLD_START = 3,
211 COUNT 211 COUNT
212 }; 212 };
213 213
214 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider( 214 RemoteSuggestionsSchedulerImpl::RemoteSuggestionsSchedulerImpl(
215 Observer* observer,
216 std::unique_ptr<RemoteSuggestionsProvider> provider,
217 PersistentScheduler* persistent_scheduler, 215 PersistentScheduler* persistent_scheduler,
218 const UserClassifier* user_classifier, 216 const UserClassifier* user_classifier,
219 PrefService* profile_prefs, 217 PrefService* profile_prefs,
220 PrefService* local_state_prefs, 218 PrefService* local_state_prefs,
221 std::unique_ptr<base::Clock> clock) 219 std::unique_ptr<base::Clock> clock)
222 : RemoteSuggestionsProvider(observer), 220 : RemoteSuggestionsScheduler(),
Marc Treib 2017/03/27 11:31:01 Not needed
jkrcal 2017/03/27 14:09:31 Done.
223 RemoteSuggestionsScheduler(),
224 provider_(std::move(provider)),
225 persistent_scheduler_(persistent_scheduler), 221 persistent_scheduler_(persistent_scheduler),
226 background_fetch_in_progress_(false), 222 background_fetch_in_progress_(false),
227 user_classifier_(user_classifier), 223 user_classifier_(user_classifier),
228 request_throttler_rare_ntp_user_( 224 request_throttler_rare_ntp_user_(
229 profile_prefs, 225 profile_prefs,
230 RequestThrottler::RequestType:: 226 RequestThrottler::RequestType::
231 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), 227 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER),
232 request_throttler_active_ntp_user_( 228 request_throttler_active_ntp_user_(
233 profile_prefs, 229 profile_prefs,
234 RequestThrottler::RequestType:: 230 RequestThrottler::RequestType::
235 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), 231 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER),
236 request_throttler_active_suggestions_consumer_( 232 request_throttler_active_suggestions_consumer_(
237 profile_prefs, 233 profile_prefs,
238 RequestThrottler::RequestType:: 234 RequestThrottler::RequestType::
239 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), 235 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER),
240 eula_state_(base::MakeUnique<EulaState>(local_state_prefs, this)), 236 eula_state_(base::MakeUnique<EulaState>(local_state_prefs, this)),
241 profile_prefs_(profile_prefs), 237 profile_prefs_(profile_prefs),
242 clock_(std::move(clock)), 238 clock_(std::move(clock)),
243 enabled_triggers_(GetEnabledTriggerTypes()) { 239 enabled_triggers_(GetEnabledTriggerTypes()) {
244 DCHECK(user_classifier); 240 DCHECK(user_classifier);
245 DCHECK(profile_prefs); 241 DCHECK(profile_prefs);
246 242
247 LoadLastFetchingSchedule(); 243 LoadLastFetchingSchedule();
248 } 244 }
249 245
250 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = 246 RemoteSuggestionsSchedulerImpl::~RemoteSuggestionsSchedulerImpl() = default;
251 default;
252 247
253 // static 248 // static
254 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( 249 void RemoteSuggestionsSchedulerImpl::RegisterProfilePrefs(
255 PrefRegistrySimple* registry) { 250 PrefRegistrySimple* registry) {
256 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0); 251 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0);
257 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback, 252 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback,
258 0); 253 0);
259 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent, 254 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
260 0); 255 0);
261 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0); 256 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0);
262 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnNtpOpened, 257 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnNtpOpened,
263 0); 258 0);
264 } 259 }
265 260
266 void SchedulingRemoteSuggestionsProvider::OnProviderActivated() { 261 void RemoteSuggestionsSchedulerImpl::OnProviderActivated() {
267 StartScheduling(); 262 StartScheduling();
268 } 263 }
269 264
270 void SchedulingRemoteSuggestionsProvider::OnProviderDeactivated() { 265 void RemoteSuggestionsSchedulerImpl::OnProviderDeactivated() {
271 StopScheduling(); 266 StopScheduling();
272 } 267 }
273 268
274 void SchedulingRemoteSuggestionsProvider::OnSuggestionsCleared() { 269 void RemoteSuggestionsSchedulerImpl::OnSuggestionsCleared() {
270 // This should be called by |provider_| so it should exist.
271 DCHECK(provider_);
275 // Some user action causes suggestions to be cleared, fetch now (as an 272 // Some user action causes suggestions to be cleared, fetch now (as an
276 // interactive request). 273 // interactive request).
277 ReloadSuggestions(); 274 provider_->ReloadSuggestions();
278 } 275 }
279 276
280 void SchedulingRemoteSuggestionsProvider::OnHistoryCleared() { 277 void RemoteSuggestionsSchedulerImpl::OnHistoryCleared() {
281 // Due to privacy, we should not fetch for a while (unless the user explicitly 278 // Due to privacy, we should not fetch for a while (unless the user explicitly
282 // asks for new suggestions) to give sync the time to propagate the changes in 279 // asks for new suggestions) to give sync the time to propagate the changes in
283 // history to the server. 280 // history to the server.
284 background_fetches_allowed_after_ = 281 background_fetches_allowed_after_ =
285 clock_->Now() + base::TimeDelta::FromMinutes( 282 clock_->Now() + base::TimeDelta::FromMinutes(
286 kBlockBackgroundFetchesMinutesAfterClearingHistory); 283 kBlockBackgroundFetchesMinutesAfterClearingHistory);
287 // After that time elapses, we should fetch as soon as possible. 284 // After that time elapses, we should fetch as soon as possible.
288 ClearLastFetchAttemptTime(); 285 ClearLastFetchAttemptTime();
289 } 286 }
290 287
291 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() { 288 void RemoteSuggestionsSchedulerImpl::RescheduleFetching() {
292 // Force the reschedule by stopping and starting it again. 289 // Force the reschedule by stopping and starting it again.
293 StopScheduling(); 290 StopScheduling();
294 StartScheduling(); 291 StartScheduling();
295 } 292 }
296 293
297 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() { 294 bool RemoteSuggestionsSchedulerImpl::AcquireQuotaForInteractiveFetch() {
295 return AcquireQuota(/*interactive_request=*/true);
296 }
297
298 void RemoteSuggestionsSchedulerImpl::OnInteractiveFetchFinished(
299 Status fetch_status) {
300 OnFetchCompleted(fetch_status);
301 }
302
303 void RemoteSuggestionsSchedulerImpl::OnPersistentSchedulerWakeUp() {
298 RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP); 304 RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP);
299 } 305 }
300 306
301 void SchedulingRemoteSuggestionsProvider::OnBrowserForegrounded() { 307 void RemoteSuggestionsSchedulerImpl::OnBrowserForegrounded() {
302 // TODO(jkrcal): Consider that this is called whenever we open or return to an 308 // TODO(jkrcal): Consider that this is called whenever we open or return to an
303 // Activity. Therefore, keep work light for fast start up calls. 309 // Activity. Therefore, keep work light for fast start up calls.
304 if (!ShouldRefetchInTheBackgroundNow(TriggerType::BROWSER_FOREGROUNDED)) { 310 if (!ShouldRefetchInTheBackgroundNow(TriggerType::BROWSER_FOREGROUNDED)) {
305 return; 311 return;
306 } 312 }
307 313
308 RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_FOREGROUNDED); 314 RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_FOREGROUNDED);
309 } 315 }
310 316
311 void SchedulingRemoteSuggestionsProvider::OnBrowserColdStart() { 317 void RemoteSuggestionsSchedulerImpl::OnBrowserColdStart() {
312 // TODO(fhorschig|jkrcal): Consider that work here must be kept light for fast 318 // TODO(fhorschig|jkrcal): Consider that work here must be kept light for fast
313 // cold start ups. 319 // cold start ups.
314 if (!ShouldRefetchInTheBackgroundNow(TriggerType::BROWSER_COLD_START)) { 320 if (!ShouldRefetchInTheBackgroundNow(TriggerType::BROWSER_COLD_START)) {
315 return; 321 return;
316 } 322 }
317 323
318 RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_COLD_START); 324 RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_COLD_START);
319 } 325 }
320 326
321 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() { 327 void RemoteSuggestionsSchedulerImpl::OnNTPOpened() {
322 if (!ShouldRefetchInTheBackgroundNow(TriggerType::NTP_OPENED)) { 328 if (!ShouldRefetchInTheBackgroundNow(TriggerType::NTP_OPENED)) {
323 return; 329 return;
324 } 330 }
325 331
326 RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED); 332 RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED);
327 } 333 }
328 334
329 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackground( 335 void RemoteSuggestionsSchedulerImpl::StartScheduling() {
330 std::unique_ptr<FetchStatusCallback> callback) {
331 if (background_fetch_in_progress_) {
332 if (callback) {
333 callback->Run(
334 Status(StatusCode::TEMPORARY_ERROR, "Background fetch in progress"));
335 }
336 return;
337 }
338
339 if (!AcquireQuota(/*interactive_request=*/false)) {
340 if (callback) {
341 callback->Run(Status(StatusCode::TEMPORARY_ERROR,
342 "Non-interactive quota exceeded"));
343 }
344 return;
345 }
346
347 background_fetch_in_progress_ = true;
348 RemoteSuggestionsProvider::FetchStatusCallback wrapper_callback = base::Bind(
349 &SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundFinished,
350 base::Unretained(this), base::Passed(&callback));
351 provider_->RefetchInTheBackground(
352 base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>(
353 std::move(wrapper_callback)));
354 }
355
356 const RemoteSuggestionsFetcher*
357 SchedulingRemoteSuggestionsProvider::suggestions_fetcher_for_debugging() const {
358 return provider_->suggestions_fetcher_for_debugging();
359 }
360
361 CategoryStatus SchedulingRemoteSuggestionsProvider::GetCategoryStatus(
362 Category category) {
363 return provider_->GetCategoryStatus(category);
364 }
365
366 CategoryInfo SchedulingRemoteSuggestionsProvider::GetCategoryInfo(
367 Category category) {
368 return provider_->GetCategoryInfo(category);
369 }
370
371 void SchedulingRemoteSuggestionsProvider::DismissSuggestion(
372 const ContentSuggestion::ID& suggestion_id) {
373 provider_->DismissSuggestion(suggestion_id);
374 }
375
376 void SchedulingRemoteSuggestionsProvider::FetchSuggestionImage(
377 const ContentSuggestion::ID& suggestion_id,
378 const ImageFetchedCallback& callback) {
379 provider_->FetchSuggestionImage(suggestion_id, callback);
380 }
381
382 void SchedulingRemoteSuggestionsProvider::Fetch(
383 const Category& category,
384 const std::set<std::string>& known_suggestion_ids,
385 const FetchDoneCallback& callback) {
386 if (!AcquireQuota(/*interactive_request=*/true)) {
387 if (callback) {
388 callback.Run(
389 Status(StatusCode::TEMPORARY_ERROR, "Interactive quota exceeded"),
390 std::vector<ContentSuggestion>());
391 }
392 return;
393 }
394
395 provider_->Fetch(
396 category, known_suggestion_ids,
397 base::Bind(&SchedulingRemoteSuggestionsProvider::FetchFinished,
398 base::Unretained(this), callback));
399 }
400
401 void SchedulingRemoteSuggestionsProvider::ReloadSuggestions() {
402 if (!AcquireQuota(/*interactive_request=*/true)) {
403 return;
404 }
405
406 provider_->ReloadSuggestions();
407 }
408
409 void SchedulingRemoteSuggestionsProvider::ClearHistory(
410 base::Time begin,
411 base::Time end,
412 const base::Callback<bool(const GURL& url)>& filter) {
413 provider_->ClearHistory(begin, end, filter);
414 }
415
416 void SchedulingRemoteSuggestionsProvider::ClearCachedSuggestions(
417 Category category) {
418 provider_->ClearCachedSuggestions(category);
419 }
420
421 void SchedulingRemoteSuggestionsProvider::OnSignInStateChanged() {
422 provider_->OnSignInStateChanged();
423 }
424
425 void SchedulingRemoteSuggestionsProvider::GetDismissedSuggestionsForDebugging(
426 Category category,
427 const DismissedSuggestionsCallback& callback) {
428 provider_->GetDismissedSuggestionsForDebugging(category, callback);
429 }
430
431 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
432 Category category) {
433 provider_->ClearDismissedSuggestionsForDebugging(category);
434 }
435
436 void SchedulingRemoteSuggestionsProvider::StartScheduling() {
437 FetchingSchedule new_schedule = GetDesiredFetchingSchedule(); 336 FetchingSchedule new_schedule = GetDesiredFetchingSchedule();
438 337
439 if (schedule_ == new_schedule) { 338 if (schedule_ == new_schedule) {
440 // Do not schedule if nothing has changed; 339 // Do not schedule if nothing has changed;
441 return; 340 return;
442 } 341 }
443 342
444 schedule_ = new_schedule; 343 schedule_ = new_schedule;
445 StoreFetchingSchedule(); 344 StoreFetchingSchedule();
446 ApplyPersistentFetchingSchedule(); 345 ApplyPersistentFetchingSchedule();
447 } 346 }
448 347
449 void SchedulingRemoteSuggestionsProvider::StopScheduling() { 348 void RemoteSuggestionsSchedulerImpl::StopScheduling() {
450 if (schedule_.is_empty()) { 349 if (schedule_.is_empty()) {
451 // Do not unschedule if already switched off. 350 // Do not unschedule if already switched off.
452 return; 351 return;
453 } 352 }
454 353
455 schedule_ = FetchingSchedule::Empty(); 354 schedule_ = FetchingSchedule::Empty();
456 StoreFetchingSchedule(); 355 StoreFetchingSchedule();
457 ApplyPersistentFetchingSchedule(); 356 ApplyPersistentFetchingSchedule();
458 } 357 }
459 358
460 void SchedulingRemoteSuggestionsProvider::ApplyPersistentFetchingSchedule() { 359 void RemoteSuggestionsSchedulerImpl::ApplyPersistentFetchingSchedule() {
461 // The scheduler only exists on Android so far, it's null on other platforms. 360 // The scheduler only exists on Android so far, it's null on other platforms.
462 if (persistent_scheduler_) { 361 if (persistent_scheduler_) {
463 if (schedule_.is_empty()) { 362 if (schedule_.is_empty()) {
464 persistent_scheduler_->Unschedule(); 363 persistent_scheduler_->Unschedule();
465 } else { 364 } else {
466 persistent_scheduler_->Schedule(schedule_.interval_persistent_wifi, 365 persistent_scheduler_->Schedule(schedule_.interval_persistent_wifi,
467 schedule_.interval_persistent_fallback); 366 schedule_.interval_persistent_fallback);
468 } 367 }
469 } 368 }
470 } 369 }
471 370
472 SchedulingRemoteSuggestionsProvider::FetchingSchedule 371 RemoteSuggestionsSchedulerImpl::FetchingSchedule
473 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const { 372 RemoteSuggestionsSchedulerImpl::GetDesiredFetchingSchedule() const {
474 UserClassifier::UserClass user_class = user_classifier_->GetUserClass(); 373 UserClassifier::UserClass user_class = user_classifier_->GetUserClass();
475 374
476 FetchingSchedule schedule; 375 FetchingSchedule schedule;
477 schedule.interval_persistent_wifi = 376 schedule.interval_persistent_wifi =
478 GetDesiredFetchingInterval(FetchingInterval::PERSISTENT_WIFI, user_class); 377 GetDesiredFetchingInterval(FetchingInterval::PERSISTENT_WIFI, user_class);
479 schedule.interval_persistent_fallback = GetDesiredFetchingInterval( 378 schedule.interval_persistent_fallback = GetDesiredFetchingInterval(
480 FetchingInterval::PERSISTENT_FALLBACK, user_class); 379 FetchingInterval::PERSISTENT_FALLBACK, user_class);
481 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval( 380 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval(
482 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class); 381 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class);
483 schedule.interval_soft_on_ntp_opened = GetDesiredFetchingInterval( 382 schedule.interval_soft_on_ntp_opened = GetDesiredFetchingInterval(
484 FetchingInterval::SOFT_ON_NTP_OPENED, user_class); 383 FetchingInterval::SOFT_ON_NTP_OPENED, user_class);
485 384
486 return schedule; 385 return schedule;
487 } 386 }
488 387
489 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() { 388 void RemoteSuggestionsSchedulerImpl::LoadLastFetchingSchedule() {
490 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue( 389 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue(
491 profile_prefs_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi)); 390 profile_prefs_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi));
492 schedule_.interval_persistent_fallback = 391 schedule_.interval_persistent_fallback =
493 base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64( 392 base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64(
494 prefs::kSnippetPersistentFetchingIntervalFallback)); 393 prefs::kSnippetPersistentFetchingIntervalFallback));
495 schedule_.interval_soft_on_usage_event = 394 schedule_.interval_soft_on_usage_event =
496 base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64( 395 base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64(
497 prefs::kSnippetSoftFetchingIntervalOnUsageEvent)); 396 prefs::kSnippetSoftFetchingIntervalOnUsageEvent));
498 schedule_.interval_soft_on_ntp_opened = base::TimeDelta::FromInternalValue( 397 schedule_.interval_soft_on_ntp_opened = base::TimeDelta::FromInternalValue(
499 profile_prefs_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnNtpOpened)); 398 profile_prefs_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnNtpOpened));
500 } 399 }
501 400
502 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() { 401 void RemoteSuggestionsSchedulerImpl::StoreFetchingSchedule() {
503 profile_prefs_->SetInt64( 402 profile_prefs_->SetInt64(
504 prefs::kSnippetPersistentFetchingIntervalWifi, 403 prefs::kSnippetPersistentFetchingIntervalWifi,
505 schedule_.interval_persistent_wifi.ToInternalValue()); 404 schedule_.interval_persistent_wifi.ToInternalValue());
506 profile_prefs_->SetInt64( 405 profile_prefs_->SetInt64(
507 prefs::kSnippetPersistentFetchingIntervalFallback, 406 prefs::kSnippetPersistentFetchingIntervalFallback,
508 schedule_.interval_persistent_fallback.ToInternalValue()); 407 schedule_.interval_persistent_fallback.ToInternalValue());
509 profile_prefs_->SetInt64( 408 profile_prefs_->SetInt64(
510 prefs::kSnippetSoftFetchingIntervalOnUsageEvent, 409 prefs::kSnippetSoftFetchingIntervalOnUsageEvent,
511 schedule_.interval_soft_on_usage_event.ToInternalValue()); 410 schedule_.interval_soft_on_usage_event.ToInternalValue());
512 profile_prefs_->SetInt64( 411 profile_prefs_->SetInt64(
513 prefs::kSnippetSoftFetchingIntervalOnNtpOpened, 412 prefs::kSnippetSoftFetchingIntervalOnNtpOpened,
514 schedule_.interval_soft_on_ntp_opened.ToInternalValue()); 413 schedule_.interval_soft_on_ntp_opened.ToInternalValue());
515 } 414 }
516 415
517 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled( 416 void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundIfEnabled(
518 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { 417 RemoteSuggestionsSchedulerImpl::TriggerType trigger) {
Marc Treib 2017/03/27 11:31:00 "RemoteSuggestionsSchedulerImpl::" not required
jkrcal 2017/03/27 14:09:31 Done.
519 if (BackgroundFetchesDisabled(trigger)) { 418 if (BackgroundFetchesDisabled(trigger)) {
520 return; 419 return;
521 } 420 }
522 421
523 UMA_HISTOGRAM_ENUMERATION( 422 UMA_HISTOGRAM_ENUMERATION(
524 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", 423 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger",
525 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); 424 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT));
526 425
527 RefetchInTheBackground(/*callback=*/nullptr); 426 RefetchInTheBackground();
528 } 427 }
529 428
530 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow( 429 void RemoteSuggestionsSchedulerImpl::RefetchInTheBackground() {
531 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { 430 if (background_fetch_in_progress_) {
431 return;
432 }
433
434 if (!AcquireQuota(/*interactive_request=*/false)) {
435 return;
436 }
437
438 background_fetch_in_progress_ = true;
439 RemoteSuggestionsProvider::FetchStatusCallback callback = base::Bind(
440 &RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundFinished,
441 base::Unretained(this));
442 provider_->RefetchInTheBackground(
443 base::MakeUnique<RemoteSuggestionsProvider::FetchStatusCallback>(
444 std::move(callback)));
Marc Treib 2017/03/27 11:31:00 nit: Inline the Bind() call here? Then the move is
jkrcal 2017/03/27 14:09:31 Done.
445 }
446
447 bool RemoteSuggestionsSchedulerImpl::ShouldRefetchInTheBackgroundNow(
448 RemoteSuggestionsSchedulerImpl::TriggerType trigger) {
Marc Treib 2017/03/27 11:31:01 "RemoteSuggestionsSchedulerImpl::" not required
jkrcal 2017/03/27 14:09:31 Done.
532 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( 449 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue(
533 profile_prefs_->GetInt64(prefs::kSnippetLastFetchAttempt)); 450 profile_prefs_->GetInt64(prefs::kSnippetLastFetchAttempt));
534 base::Time first_allowed_fetch_time; 451 base::Time first_allowed_fetch_time;
535 switch (trigger) { 452 switch (trigger) {
536 case TriggerType::NTP_OPENED: 453 case TriggerType::NTP_OPENED:
537 first_allowed_fetch_time = 454 first_allowed_fetch_time =
538 last_fetch_attempt_time + schedule_.interval_soft_on_ntp_opened; 455 last_fetch_attempt_time + schedule_.interval_soft_on_ntp_opened;
539 break; 456 break;
540 case TriggerType::BROWSER_FOREGROUNDED: 457 case TriggerType::BROWSER_FOREGROUNDED:
541 case TriggerType::BROWSER_COLD_START: 458 case TriggerType::BROWSER_COLD_START:
542 first_allowed_fetch_time = 459 first_allowed_fetch_time =
543 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; 460 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event;
544 break; 461 break;
545 case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP: 462 case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP:
546 case TriggerType::COUNT: 463 case TriggerType::COUNT:
547 NOTREACHED(); 464 NOTREACHED();
548 break; 465 break;
549 } 466 }
550 base::Time now = clock_->Now(); 467 base::Time now = clock_->Now();
551 468
552 return background_fetches_allowed_after_ <= now && 469 return background_fetches_allowed_after_ <= now &&
553 first_allowed_fetch_time <= now; 470 first_allowed_fetch_time <= now;
554 } 471 }
555 472
556 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( 473 bool RemoteSuggestionsSchedulerImpl::BackgroundFetchesDisabled(
557 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { 474 RemoteSuggestionsSchedulerImpl::TriggerType trigger) const {
Marc Treib 2017/03/27 11:31:01 Also here
jkrcal 2017/03/27 14:09:31 Done.
475 if (!provider_) {
476 return true; // Cannot fetch as remote suggestions provider does not exist.
477 }
478
558 if (schedule_.is_empty()) { 479 if (schedule_.is_empty()) {
559 return true; // Background fetches are disabled in general. 480 return true; // Background fetches are disabled in general.
560 } 481 }
561 482
562 if (enabled_triggers_.count(trigger) == 0) { 483 if (enabled_triggers_.count(trigger) == 0) {
563 return true; // Background fetches for |trigger| are not enabled. 484 return true; // Background fetches for |trigger| are not enabled.
564 } 485 }
565 486
566 if (!eula_state_->IsEulaAccepted()) { 487 if (!eula_state_->IsEulaAccepted()) {
567 return true; // No background fetches are allowed before EULA is accepted. 488 return true; // No background fetches are allowed before EULA is accepted.
568 } 489 }
569 490
570 return false; 491 return false;
571 } 492 }
572 493
573 bool SchedulingRemoteSuggestionsProvider::AcquireQuota( 494 bool RemoteSuggestionsSchedulerImpl::AcquireQuota(bool interactive_request) {
574 bool interactive_request) {
575 switch (user_classifier_->GetUserClass()) { 495 switch (user_classifier_->GetUserClass()) {
576 case UserClassifier::UserClass::RARE_NTP_USER: 496 case UserClassifier::UserClass::RARE_NTP_USER:
577 return request_throttler_rare_ntp_user_.DemandQuotaForRequest( 497 return request_throttler_rare_ntp_user_.DemandQuotaForRequest(
578 interactive_request); 498 interactive_request);
579 case UserClassifier::UserClass::ACTIVE_NTP_USER: 499 case UserClassifier::UserClass::ACTIVE_NTP_USER:
580 return request_throttler_active_ntp_user_.DemandQuotaForRequest( 500 return request_throttler_active_ntp_user_.DemandQuotaForRequest(
581 interactive_request); 501 interactive_request);
582 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: 502 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER:
583 return request_throttler_active_suggestions_consumer_ 503 return request_throttler_active_suggestions_consumer_
584 .DemandQuotaForRequest(interactive_request); 504 .DemandQuotaForRequest(interactive_request);
585 } 505 }
586 NOTREACHED(); 506 NOTREACHED();
587 return false; 507 return false;
588 } 508 }
589 509
590 void SchedulingRemoteSuggestionsProvider::FetchFinished( 510 void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundFinished(
591 const FetchDoneCallback& callback,
592 Status fetch_status,
593 std::vector<ContentSuggestion> suggestions) {
594 OnFetchCompleted(fetch_status);
595 if (callback) {
596 callback.Run(fetch_status, std::move(suggestions));
597 }
598 }
599
600 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundFinished(
601 std::unique_ptr<FetchStatusCallback> callback,
602 Status fetch_status) { 511 Status fetch_status) {
603 background_fetch_in_progress_ = false; 512 background_fetch_in_progress_ = false;
604 OnFetchCompleted(fetch_status); 513 OnFetchCompleted(fetch_status);
605 if (callback) {
606 callback->Run(fetch_status);
607 }
608 } 514 }
609 515
610 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted( 516 void RemoteSuggestionsSchedulerImpl::OnFetchCompleted(Status fetch_status) {
611 Status fetch_status) {
612 profile_prefs_->SetInt64(prefs::kSnippetLastFetchAttempt, 517 profile_prefs_->SetInt64(prefs::kSnippetLastFetchAttempt,
613 clock_->Now().ToInternalValue()); 518 clock_->Now().ToInternalValue());
614 519
615 // Reschedule after a fetch. The persistent schedule is applied only after a 520 // Reschedule after a fetch. The persistent schedule is applied only after a
616 // successful fetch. After a failed fetch, we want to keep the previous 521 // successful fetch. After a failed fetch, we want to keep the previous
617 // persistent schedule intact so that we eventually get a persistent 522 // persistent schedule intact so that we eventually get a persistent
618 // fallback fetch (if the wifi persistent fetches keep failing). 523 // fallback fetch (if the wifi persistent fetches keep failing).
619 if (fetch_status.code != StatusCode::SUCCESS) { 524 if (fetch_status.code != StatusCode::SUCCESS) {
620 return; 525 return;
621 } 526 }
622 ApplyPersistentFetchingSchedule(); 527 ApplyPersistentFetchingSchedule();
623 } 528 }
624 529
625 void SchedulingRemoteSuggestionsProvider::ClearLastFetchAttemptTime() { 530 void RemoteSuggestionsSchedulerImpl::ClearLastFetchAttemptTime() {
626 profile_prefs_->ClearPref(prefs::kSnippetLastFetchAttempt); 531 profile_prefs_->ClearPref(prefs::kSnippetLastFetchAttempt);
627 } 532 }
628 533
629 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> 534 std::set<RemoteSuggestionsSchedulerImpl::TriggerType>
630 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() { 535 RemoteSuggestionsSchedulerImpl::GetEnabledTriggerTypes() {
631 static_assert(static_cast<unsigned int>(TriggerType::COUNT) == 536 static_assert(static_cast<unsigned int>(TriggerType::COUNT) ==
632 arraysize(kTriggerTypeNames), 537 arraysize(kTriggerTypeNames),
633 "Fill in names for trigger types."); 538 "Fill in names for trigger types.");
634 539
635 std::string param_value = base::GetFieldTrialParamValueByFeature( 540 std::string param_value = base::GetFieldTrialParamValueByFeature(
636 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName); 541 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName);
637 if (param_value == kTriggerTypesParamValueForEmptyList) { 542 if (param_value == kTriggerTypesParamValueForEmptyList) {
638 return std::set<TriggerType>(); 543 return std::set<TriggerType>();
639 } 544 }
640 545
(...skipping 17 matching lines...) Expand all
658 return GetDefaultEnabledTriggerTypes(); 563 return GetDefaultEnabledTriggerTypes();
659 } 564 }
660 565
661 // Add the enabled type represented by |token| into the result set. 566 // Add the enabled type represented by |token| into the result set.
662 enabled_types.insert( 567 enabled_types.insert(
663 static_cast<TriggerType>(it - std::begin(kTriggerTypeNames))); 568 static_cast<TriggerType>(it - std::begin(kTriggerTypeNames)));
664 } 569 }
665 return enabled_types; 570 return enabled_types;
666 } 571 }
667 572
668 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> 573 std::set<RemoteSuggestionsSchedulerImpl::TriggerType>
669 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { 574 RemoteSuggestionsSchedulerImpl::GetDefaultEnabledTriggerTypes() {
670 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, 575 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED,
671 TriggerType::BROWSER_FOREGROUNDED}; 576 TriggerType::BROWSER_FOREGROUNDED};
672 } 577 }
673 578
674 } // namespace ntp_snippets 579 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698