OLD | NEW |
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 <random> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 // for each interval. Initially all the timers are started at the same time. | 30 // for each interval. Initially all the timers are started at the same time. |
31 // Fetches are | 31 // Fetches are |
32 // only performed when certain conditions associated with the intervals are | 32 // only performed when certain conditions associated with the intervals are |
33 // met. If a fetch failed, then only the corresponding timer is reset. The | 33 // met. If a fetch failed, then only the corresponding timer is reset. The |
34 // other timers are not touched. | 34 // other timers are not touched. |
35 // TODO(markusheintz): Describe the individual intervals. | 35 // TODO(markusheintz): Describe the individual intervals. |
36 enum class FetchingInterval { | 36 enum class FetchingInterval { |
37 PERSISTENT_FALLBACK, | 37 PERSISTENT_FALLBACK, |
38 PERSISTENT_WIFI, | 38 PERSISTENT_WIFI, |
39 SOFT_ON_USAGE_EVENT, | 39 SOFT_ON_USAGE_EVENT, |
| 40 SOFT_ON_NTP_OPENED, |
40 COUNT | 41 COUNT |
41 }; | 42 }; |
42 | 43 |
43 // The following arrays specify default values for remote suggestions fetch | 44 // The following arrays specify default values for remote suggestions fetch |
44 // intervals corresponding to individual user classes. The user classes are | 45 // intervals corresponding to individual user classes. The user classes are |
45 // defined by the user classifier. There must be an array for each user class. | 46 // defined by the user classifier. There must be an array for each user class. |
46 // The values of each array specify a default time interval for the intervals | 47 // The values of each array specify a default time interval for the intervals |
47 // defined by the enum FetchingInterval. The default time intervals defined in | 48 // defined by the enum FetchingInterval. The default time intervals defined in |
48 // the arrays can be overridden using different variation parameters. | 49 // the arrays can be overridden using different variation parameters. |
49 const double kDefaultFetchingIntervalHoursRareNtpUser[] = {48.0, 24.0, 12.0}; | 50 const double kDefaultFetchingIntervalHoursRareNtpUser[] = {48.0, 24.0, 12.0, |
50 const double kDefaultFetchingIntervalHoursActiveNtpUser[] = {24.0, 6.0, 2.0}; | 51 6.0}; |
| 52 const double kDefaultFetchingIntervalHoursActiveNtpUser[] = {24.0, 6.0, 2.0, |
| 53 2.0}; |
51 const double kDefaultFetchingIntervalHoursActiveSuggestionsConsumer[] = { | 54 const double kDefaultFetchingIntervalHoursActiveSuggestionsConsumer[] = { |
52 24.0, 6.0, 2.0}; | 55 24.0, 6.0, 2.0, 1.0}; |
53 | 56 |
54 // Variation parameters than can be used to override the default fetching | 57 // Variation parameters than can be used to override the default fetching |
55 // intervals. | 58 // intervals. |
56 const char* kFetchingIntervalParamNameRareNtpUser[] = { | 59 const char* kFetchingIntervalParamNameRareNtpUser[] = { |
57 "fetching_interval_hours-fallback-rare_ntp_user", | 60 "fetching_interval_hours-fallback-rare_ntp_user", |
58 "fetching_interval_hours-wifi-rare_ntp_user", | 61 "fetching_interval_hours-wifi-rare_ntp_user", |
59 "soft_fetching_interval_hours-active-rare_ntp_user"}; | 62 "soft_fetching_interval_hours-active-rare_ntp_user", |
| 63 "soft_on_ntp_opened_interval_hours-rare_ntp_user"}; |
60 const char* kFetchingIntervalParamNameActiveNtpUser[] = { | 64 const char* kFetchingIntervalParamNameActiveNtpUser[] = { |
61 "fetching_interval_hours-fallback-active_ntp_user", | 65 "fetching_interval_hours-fallback-active_ntp_user", |
62 "fetching_interval_hours-wifi-active_ntp_user", | 66 "fetching_interval_hours-wifi-active_ntp_user", |
63 "soft_fetching_interval_hours-active-active_ntp_user"}; | 67 "soft_fetching_interval_hours-active-active_ntp_user", |
| 68 "soft_on_ntp_opened_interval_hours-active_ntp_user"}; |
64 const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = { | 69 const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = { |
65 "fetching_interval_hours-fallback-active_suggestions_consumer", | 70 "fetching_interval_hours-fallback-active_suggestions_consumer", |
66 "fetching_interval_hours-wifi-active_suggestions_consumer", | 71 "fetching_interval_hours-wifi-active_suggestions_consumer", |
67 "soft_fetching_interval_hours-active-active_suggestions_consumer"}; | 72 "soft_fetching_interval_hours-active-active_suggestions_consumer", |
| 73 "soft_on_ntp_opened_interval_hours-active_suggestions_consumer"}; |
68 | 74 |
69 static_assert( | 75 static_assert( |
70 static_cast<unsigned int>(FetchingInterval::COUNT) == | 76 static_cast<unsigned int>(FetchingInterval::COUNT) == |
71 arraysize(kDefaultFetchingIntervalHoursRareNtpUser) && | 77 arraysize(kDefaultFetchingIntervalHoursRareNtpUser) && |
72 static_cast<unsigned int>(FetchingInterval::COUNT) == | 78 static_cast<unsigned int>(FetchingInterval::COUNT) == |
73 arraysize(kDefaultFetchingIntervalHoursActiveNtpUser) && | 79 arraysize(kDefaultFetchingIntervalHoursActiveNtpUser) && |
74 static_cast<unsigned int>(FetchingInterval::COUNT) == | 80 static_cast<unsigned int>(FetchingInterval::COUNT) == |
75 arraysize(kDefaultFetchingIntervalHoursActiveSuggestionsConsumer) && | 81 arraysize(kDefaultFetchingIntervalHoursActiveSuggestionsConsumer) && |
76 static_cast<unsigned int>(FetchingInterval::COUNT) == | 82 static_cast<unsigned int>(FetchingInterval::COUNT) == |
77 arraysize(kFetchingIntervalParamNameRareNtpUser) && | 83 arraysize(kFetchingIntervalParamNameRareNtpUser) && |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 204 |
199 // static | 205 // static |
200 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( | 206 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( |
201 PrefRegistrySimple* registry) { | 207 PrefRegistrySimple* registry) { |
202 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0); | 208 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0); |
203 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback, | 209 registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback, |
204 0); | 210 0); |
205 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent, | 211 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnUsageEvent, |
206 0); | 212 0); |
207 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0); | 213 registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0); |
| 214 registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalOnNtpOpened, |
| 215 0); |
208 } | 216 } |
209 | 217 |
210 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() { | 218 void SchedulingRemoteSuggestionsProvider::RescheduleFetching() { |
211 // Force the reschedule by stopping and starting it again. | 219 // Force the reschedule by stopping and starting it again. |
212 StopScheduling(); | 220 StopScheduling(); |
213 StartScheduling(); | 221 StartScheduling(); |
214 } | 222 } |
215 | 223 |
216 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() { | 224 void SchedulingRemoteSuggestionsProvider::OnPersistentSchedulerWakeUp() { |
217 RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP); | 225 RefetchInTheBackgroundIfEnabled(TriggerType::PERSISTENT_SCHEDULER_WAKE_UP); |
218 } | 226 } |
219 | 227 |
220 void SchedulingRemoteSuggestionsProvider::OnBrowserForegrounded() { | 228 void SchedulingRemoteSuggestionsProvider::OnBrowserForegrounded() { |
221 // TODO(jkrcal): Consider that this is called whenever we open or return to an | 229 // TODO(jkrcal): Consider that this is called whenever we open or return to an |
222 // Activity. Therefore, keep work light for fast start up calls. | 230 // Activity. Therefore, keep work light for fast start up calls. |
223 if (!ShouldRefetchInTheBackgroundNow()) { | 231 if (!ShouldRefetchInTheBackgroundNow(TriggerType::BROWSER_FOREGROUNDED)) { |
224 return; | 232 return; |
225 } | 233 } |
226 | 234 |
227 RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_FOREGROUNDED); | 235 RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_FOREGROUNDED); |
228 } | 236 } |
229 | 237 |
230 void SchedulingRemoteSuggestionsProvider::OnBrowserColdStart() { | 238 void SchedulingRemoteSuggestionsProvider::OnBrowserColdStart() { |
231 // TODO(fhorschig|jkrcal): Consider that work here must be kept light for fast | 239 // TODO(fhorschig|jkrcal): Consider that work here must be kept light for fast |
232 // cold start ups. | 240 // cold start ups. |
233 if (!ShouldRefetchInTheBackgroundNow()) { | 241 if (!ShouldRefetchInTheBackgroundNow(TriggerType::BROWSER_COLD_START)) { |
234 return; | 242 return; |
235 } | 243 } |
236 | 244 |
237 RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_COLD_START); | 245 RefetchInTheBackgroundIfEnabled(TriggerType::BROWSER_COLD_START); |
238 } | 246 } |
239 | 247 |
240 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() { | 248 void SchedulingRemoteSuggestionsProvider::OnNTPOpened() { |
241 if (!ShouldRefetchInTheBackgroundNow()) { | 249 if (!ShouldRefetchInTheBackgroundNow(TriggerType::NTP_OPENED)) { |
242 return; | 250 return; |
243 } | 251 } |
244 | 252 |
245 RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED); | 253 RefetchInTheBackgroundIfEnabled(TriggerType::NTP_OPENED); |
246 } | 254 } |
247 | 255 |
248 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback( | 256 void SchedulingRemoteSuggestionsProvider::SetProviderStatusCallback( |
249 std::unique_ptr<ProviderStatusCallback> callback) { | 257 std::unique_ptr<ProviderStatusCallback> callback) { |
250 provider_->SetProviderStatusCallback(std::move(callback)); | 258 provider_->SetProviderStatusCallback(std::move(callback)); |
251 } | 259 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const { | 397 SchedulingRemoteSuggestionsProvider::GetDesiredFetchingSchedule() const { |
390 UserClassifier::UserClass user_class = user_classifier_->GetUserClass(); | 398 UserClassifier::UserClass user_class = user_classifier_->GetUserClass(); |
391 | 399 |
392 FetchingSchedule schedule; | 400 FetchingSchedule schedule; |
393 schedule.interval_persistent_wifi = | 401 schedule.interval_persistent_wifi = |
394 GetDesiredFetchingInterval(FetchingInterval::PERSISTENT_WIFI, user_class); | 402 GetDesiredFetchingInterval(FetchingInterval::PERSISTENT_WIFI, user_class); |
395 schedule.interval_persistent_fallback = GetDesiredFetchingInterval( | 403 schedule.interval_persistent_fallback = GetDesiredFetchingInterval( |
396 FetchingInterval::PERSISTENT_FALLBACK, user_class); | 404 FetchingInterval::PERSISTENT_FALLBACK, user_class); |
397 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval( | 405 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval( |
398 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class); | 406 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class); |
| 407 schedule.interval_soft_on_ntp_opened = GetDesiredFetchingInterval( |
| 408 FetchingInterval::SOFT_ON_NTP_OPENED, user_class); |
399 | 409 |
400 return schedule; | 410 return schedule; |
401 } | 411 } |
402 | 412 |
403 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() { | 413 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() { |
404 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue( | 414 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue( |
405 pref_service_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi)); | 415 pref_service_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi)); |
406 schedule_.interval_persistent_fallback = | 416 schedule_.interval_persistent_fallback = |
407 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( | 417 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( |
408 prefs::kSnippetPersistentFetchingIntervalFallback)); | 418 prefs::kSnippetPersistentFetchingIntervalFallback)); |
409 schedule_.interval_soft_on_usage_event = base::TimeDelta::FromInternalValue( | 419 schedule_.interval_soft_on_usage_event = base::TimeDelta::FromInternalValue( |
410 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnUsageEvent)); | 420 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnUsageEvent)); |
| 421 schedule_.interval_soft_on_ntp_opened = base::TimeDelta::FromInternalValue( |
| 422 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnNtpOpened)); |
411 } | 423 } |
412 | 424 |
413 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() { | 425 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() { |
414 pref_service_->SetInt64(prefs::kSnippetPersistentFetchingIntervalWifi, | 426 pref_service_->SetInt64(prefs::kSnippetPersistentFetchingIntervalWifi, |
415 schedule_.interval_persistent_wifi.ToInternalValue()); | 427 schedule_.interval_persistent_wifi.ToInternalValue()); |
416 pref_service_->SetInt64( | 428 pref_service_->SetInt64( |
417 prefs::kSnippetPersistentFetchingIntervalFallback, | 429 prefs::kSnippetPersistentFetchingIntervalFallback, |
418 schedule_.interval_persistent_fallback.ToInternalValue()); | 430 schedule_.interval_persistent_fallback.ToInternalValue()); |
419 pref_service_->SetInt64( | 431 pref_service_->SetInt64( |
420 prefs::kSnippetSoftFetchingIntervalOnUsageEvent, | 432 prefs::kSnippetSoftFetchingIntervalOnUsageEvent, |
421 schedule_.interval_soft_on_usage_event.ToInternalValue()); | 433 schedule_.interval_soft_on_usage_event.ToInternalValue()); |
| 434 pref_service_->SetInt64( |
| 435 prefs::kSnippetSoftFetchingIntervalOnNtpOpened, |
| 436 schedule_.interval_soft_on_ntp_opened.ToInternalValue()); |
422 } | 437 } |
423 | 438 |
424 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled( | 439 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled( |
425 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { | 440 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { |
426 if (BackgroundFetchesDisabled(trigger)) { | 441 if (BackgroundFetchesDisabled(trigger)) { |
427 return; | 442 return; |
428 } | 443 } |
429 | 444 |
430 UMA_HISTOGRAM_ENUMERATION( | 445 UMA_HISTOGRAM_ENUMERATION( |
431 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", | 446 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", |
432 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); | 447 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); |
433 | 448 |
434 RefetchInTheBackground(/*callback=*/nullptr); | 449 RefetchInTheBackground(/*callback=*/nullptr); |
435 } | 450 } |
436 | 451 |
437 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow() { | 452 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow( |
438 base::Time first_allowed_fetch_time = | 453 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { |
439 base::Time::FromInternalValue( | 454 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( |
440 pref_service_->GetInt64(prefs::kSnippetLastFetchAttempt)) + | 455 pref_service_->GetInt64(prefs::kSnippetLastFetchAttempt)); |
441 schedule_.interval_soft_on_usage_event; | 456 base::Time first_allowed_fetch_time; |
| 457 switch (trigger) { |
| 458 case TriggerType::NTP_OPENED: |
| 459 first_allowed_fetch_time = |
| 460 last_fetch_attempt_time + schedule_.interval_soft_on_ntp_opened; |
| 461 break; |
| 462 case TriggerType::BROWSER_FOREGROUNDED: |
| 463 case TriggerType::BROWSER_COLD_START: |
| 464 first_allowed_fetch_time = |
| 465 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; |
| 466 break; |
| 467 case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP: |
| 468 case TriggerType::COUNT: |
| 469 NOTREACHED(); |
| 470 break; |
| 471 } |
442 return first_allowed_fetch_time <= clock_->Now(); | 472 return first_allowed_fetch_time <= clock_->Now(); |
443 } | 473 } |
444 | 474 |
445 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( | 475 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( |
446 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { | 476 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { |
447 if (schedule_.is_empty()) { | 477 if (schedule_.is_empty()) { |
448 return true; // Background fetches are disabled in general. | 478 return true; // Background fetches are disabled in general. |
449 } | 479 } |
450 | 480 |
451 if (enabled_triggers_.count(trigger) == 0) { | 481 if (enabled_triggers_.count(trigger) == 0) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 return enabled_types; | 558 return enabled_types; |
529 } | 559 } |
530 | 560 |
531 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> | 561 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> |
532 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { | 562 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { |
533 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, | 563 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, |
534 TriggerType::BROWSER_FOREGROUNDED}; | 564 TriggerType::BROWSER_FOREGROUNDED}; |
535 } | 565 } |
536 | 566 |
537 } // namespace ntp_snippets | 567 } // namespace ntp_snippets |
OLD | NEW |