| 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 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 // |kTriggerTypeNames| above. | 167 // |kTriggerTypeNames| above. |
| 168 enum class SchedulingRemoteSuggestionsProvider::TriggerType { | 168 enum class SchedulingRemoteSuggestionsProvider::TriggerType { |
| 169 PERSISTENT_SCHEDULER_WAKE_UP = 0, | 169 PERSISTENT_SCHEDULER_WAKE_UP = 0, |
| 170 NTP_OPENED = 1, | 170 NTP_OPENED = 1, |
| 171 BROWSER_FOREGROUNDED = 2, | 171 BROWSER_FOREGROUNDED = 2, |
| 172 BROWSER_COLD_START = 3, | 172 BROWSER_COLD_START = 3, |
| 173 COUNT | 173 COUNT |
| 174 }; | 174 }; |
| 175 | 175 |
| 176 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider( | 176 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider( |
| 177 Observer* observer, | 177 ContentSuggestionsProvider::Observer* observer, |
| 178 std::unique_ptr<RemoteSuggestionsProvider> provider, | 178 std::unique_ptr<RemoteSuggestionsProvider> provider, |
| 179 PersistentScheduler* persistent_scheduler, | 179 PersistentScheduler* persistent_scheduler, |
| 180 const UserClassifier* user_classifier, | 180 const UserClassifier* user_classifier, |
| 181 PrefService* pref_service, | 181 PrefService* profile_prefs, |
| 182 PrefService* local_state_prefs, |
| 182 std::unique_ptr<base::Clock> clock) | 183 std::unique_ptr<base::Clock> clock) |
| 183 : RemoteSuggestionsProvider(observer), | 184 : RemoteSuggestionsProvider(observer), |
| 184 RemoteSuggestionsScheduler(), | 185 RemoteSuggestionsScheduler(), |
| 185 provider_(std::move(provider)), | 186 provider_(std::move(provider)), |
| 186 persistent_scheduler_(persistent_scheduler), | 187 persistent_scheduler_(persistent_scheduler), |
| 187 background_fetch_in_progress_(false), | 188 background_fetch_in_progress_(false), |
| 188 user_classifier_(user_classifier), | 189 user_classifier_(user_classifier), |
| 189 request_throttler_rare_ntp_user_( | 190 request_throttler_rare_ntp_user_( |
| 190 pref_service, | 191 profile_prefs, |
| 191 RequestThrottler::RequestType:: | 192 RequestThrottler::RequestType:: |
| 192 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), | 193 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), |
| 193 request_throttler_active_ntp_user_( | 194 request_throttler_active_ntp_user_( |
| 194 pref_service, | 195 profile_prefs, |
| 195 RequestThrottler::RequestType:: | 196 RequestThrottler::RequestType:: |
| 196 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), | 197 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), |
| 197 request_throttler_active_suggestions_consumer_( | 198 request_throttler_active_suggestions_consumer_( |
| 198 pref_service, | 199 profile_prefs, |
| 199 RequestThrottler::RequestType:: | 200 RequestThrottler::RequestType:: |
| 200 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), | 201 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), |
| 201 pref_service_(pref_service), | 202 eula_notifier_( |
| 203 web_resource::EulaAcceptedNotifier::Create(local_state_prefs)), |
| 204 profile_prefs_(profile_prefs), |
| 202 clock_(std::move(clock)), | 205 clock_(std::move(clock)), |
| 203 enabled_triggers_(GetEnabledTriggerTypes()) { | 206 enabled_triggers_(GetEnabledTriggerTypes()) { |
| 204 DCHECK(user_classifier); | 207 DCHECK(user_classifier); |
| 205 DCHECK(pref_service); | 208 DCHECK(profile_prefs); |
| 209 // EulaNotifier is not constructed on some platforms (such as desktop). |
| 210 if (eula_notifier_) { |
| 211 eula_notifier_->Init(this); |
| 212 } |
| 206 | 213 |
| 207 LoadLastFetchingSchedule(); | 214 LoadLastFetchingSchedule(); |
| 208 } | 215 } |
| 209 | 216 |
| 210 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = | 217 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = |
| 211 default; | 218 default; |
| 212 | 219 |
| 213 // static | 220 // static |
| 214 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( | 221 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( |
| 215 PrefRegistrySimple* registry) { | 222 PrefRegistrySimple* registry) { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 Category category, | 393 Category category, |
| 387 const DismissedSuggestionsCallback& callback) { | 394 const DismissedSuggestionsCallback& callback) { |
| 388 provider_->GetDismissedSuggestionsForDebugging(category, callback); | 395 provider_->GetDismissedSuggestionsForDebugging(category, callback); |
| 389 } | 396 } |
| 390 | 397 |
| 391 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging( | 398 void SchedulingRemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging( |
| 392 Category category) { | 399 Category category) { |
| 393 provider_->ClearDismissedSuggestionsForDebugging(category); | 400 provider_->ClearDismissedSuggestionsForDebugging(category); |
| 394 } | 401 } |
| 395 | 402 |
| 403 void SchedulingRemoteSuggestionsProvider::OnEulaAccepted() { |
| 404 // Emulate a browser foregrounded event. |
| 405 OnBrowserForegrounded(); |
| 406 } |
| 407 |
| 396 void SchedulingRemoteSuggestionsProvider::StartScheduling() { | 408 void SchedulingRemoteSuggestionsProvider::StartScheduling() { |
| 397 FetchingSchedule new_schedule = GetDesiredFetchingSchedule(); | 409 FetchingSchedule new_schedule = GetDesiredFetchingSchedule(); |
| 398 | 410 |
| 399 if (schedule_ == new_schedule) { | 411 if (schedule_ == new_schedule) { |
| 400 // Do not schedule if nothing has changed; | 412 // Do not schedule if nothing has changed; |
| 401 return; | 413 return; |
| 402 } | 414 } |
| 403 | 415 |
| 404 schedule_ = new_schedule; | 416 schedule_ = new_schedule; |
| 405 StoreFetchingSchedule(); | 417 StoreFetchingSchedule(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval( | 453 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval( |
| 442 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class); | 454 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class); |
| 443 schedule.interval_soft_on_ntp_opened = GetDesiredFetchingInterval( | 455 schedule.interval_soft_on_ntp_opened = GetDesiredFetchingInterval( |
| 444 FetchingInterval::SOFT_ON_NTP_OPENED, user_class); | 456 FetchingInterval::SOFT_ON_NTP_OPENED, user_class); |
| 445 | 457 |
| 446 return schedule; | 458 return schedule; |
| 447 } | 459 } |
| 448 | 460 |
| 449 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() { | 461 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() { |
| 450 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue( | 462 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue( |
| 451 pref_service_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi)); | 463 profile_prefs_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi)); |
| 452 schedule_.interval_persistent_fallback = | 464 schedule_.interval_persistent_fallback = |
| 453 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( | 465 base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64( |
| 454 prefs::kSnippetPersistentFetchingIntervalFallback)); | 466 prefs::kSnippetPersistentFetchingIntervalFallback)); |
| 455 schedule_.interval_soft_on_usage_event = base::TimeDelta::FromInternalValue( | 467 schedule_.interval_soft_on_usage_event = |
| 456 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnUsageEvent)); | 468 base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64( |
| 469 prefs::kSnippetSoftFetchingIntervalOnUsageEvent)); |
| 457 schedule_.interval_soft_on_ntp_opened = base::TimeDelta::FromInternalValue( | 470 schedule_.interval_soft_on_ntp_opened = base::TimeDelta::FromInternalValue( |
| 458 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnNtpOpened)); | 471 profile_prefs_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnNtpOpened)); |
| 459 } | 472 } |
| 460 | 473 |
| 461 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() { | 474 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() { |
| 462 pref_service_->SetInt64(prefs::kSnippetPersistentFetchingIntervalWifi, | 475 profile_prefs_->SetInt64( |
| 463 schedule_.interval_persistent_wifi.ToInternalValue()); | 476 prefs::kSnippetPersistentFetchingIntervalWifi, |
| 464 pref_service_->SetInt64( | 477 schedule_.interval_persistent_wifi.ToInternalValue()); |
| 478 profile_prefs_->SetInt64( |
| 465 prefs::kSnippetPersistentFetchingIntervalFallback, | 479 prefs::kSnippetPersistentFetchingIntervalFallback, |
| 466 schedule_.interval_persistent_fallback.ToInternalValue()); | 480 schedule_.interval_persistent_fallback.ToInternalValue()); |
| 467 pref_service_->SetInt64( | 481 profile_prefs_->SetInt64( |
| 468 prefs::kSnippetSoftFetchingIntervalOnUsageEvent, | 482 prefs::kSnippetSoftFetchingIntervalOnUsageEvent, |
| 469 schedule_.interval_soft_on_usage_event.ToInternalValue()); | 483 schedule_.interval_soft_on_usage_event.ToInternalValue()); |
| 470 pref_service_->SetInt64( | 484 profile_prefs_->SetInt64( |
| 471 prefs::kSnippetSoftFetchingIntervalOnNtpOpened, | 485 prefs::kSnippetSoftFetchingIntervalOnNtpOpened, |
| 472 schedule_.interval_soft_on_ntp_opened.ToInternalValue()); | 486 schedule_.interval_soft_on_ntp_opened.ToInternalValue()); |
| 473 } | 487 } |
| 474 | 488 |
| 475 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled( | 489 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled( |
| 476 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { | 490 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { |
| 477 if (BackgroundFetchesDisabled(trigger)) { | 491 if (BackgroundFetchesDisabled(trigger)) { |
| 478 return; | 492 return; |
| 479 } | 493 } |
| 480 | 494 |
| 481 UMA_HISTOGRAM_ENUMERATION( | 495 UMA_HISTOGRAM_ENUMERATION( |
| 482 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", | 496 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", |
| 483 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); | 497 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); |
| 484 | 498 |
| 485 RefetchInTheBackground(/*callback=*/nullptr); | 499 RefetchInTheBackground(/*callback=*/nullptr); |
| 486 } | 500 } |
| 487 | 501 |
| 488 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow( | 502 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow( |
| 489 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { | 503 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { |
| 490 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( | 504 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( |
| 491 pref_service_->GetInt64(prefs::kSnippetLastFetchAttempt)); | 505 profile_prefs_->GetInt64(prefs::kSnippetLastFetchAttempt)); |
| 492 base::Time first_allowed_fetch_time; | 506 base::Time first_allowed_fetch_time; |
| 493 switch (trigger) { | 507 switch (trigger) { |
| 494 case TriggerType::NTP_OPENED: | 508 case TriggerType::NTP_OPENED: |
| 495 first_allowed_fetch_time = | 509 first_allowed_fetch_time = |
| 496 last_fetch_attempt_time + schedule_.interval_soft_on_ntp_opened; | 510 last_fetch_attempt_time + schedule_.interval_soft_on_ntp_opened; |
| 497 break; | 511 break; |
| 498 case TriggerType::BROWSER_FOREGROUNDED: | 512 case TriggerType::BROWSER_FOREGROUNDED: |
| 499 case TriggerType::BROWSER_COLD_START: | 513 case TriggerType::BROWSER_COLD_START: |
| 500 first_allowed_fetch_time = | 514 first_allowed_fetch_time = |
| 501 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; | 515 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 513 | 527 |
| 514 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( | 528 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( |
| 515 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { | 529 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { |
| 516 if (schedule_.is_empty()) { | 530 if (schedule_.is_empty()) { |
| 517 return true; // Background fetches are disabled in general. | 531 return true; // Background fetches are disabled in general. |
| 518 } | 532 } |
| 519 | 533 |
| 520 if (enabled_triggers_.count(trigger) == 0) { | 534 if (enabled_triggers_.count(trigger) == 0) { |
| 521 return true; // Background fetches for |trigger| are not enabled. | 535 return true; // Background fetches for |trigger| are not enabled. |
| 522 } | 536 } |
| 537 |
| 538 if (eula_notifier_ && !eula_notifier_->IsEulaAccepted()) { |
| 539 return true; // No background fetches are allowed before EULA is accepted. |
| 540 } |
| 541 |
| 523 return false; | 542 return false; |
| 524 } | 543 } |
| 525 | 544 |
| 526 bool SchedulingRemoteSuggestionsProvider::AcquireQuota( | 545 bool SchedulingRemoteSuggestionsProvider::AcquireQuota( |
| 527 bool interactive_request) { | 546 bool interactive_request) { |
| 528 switch (user_classifier_->GetUserClass()) { | 547 switch (user_classifier_->GetUserClass()) { |
| 529 case UserClassifier::UserClass::RARE_NTP_USER: | 548 case UserClassifier::UserClass::RARE_NTP_USER: |
| 530 return request_throttler_rare_ntp_user_.DemandQuotaForRequest( | 549 return request_throttler_rare_ntp_user_.DemandQuotaForRequest( |
| 531 interactive_request); | 550 interactive_request); |
| 532 case UserClassifier::UserClass::ACTIVE_NTP_USER: | 551 case UserClassifier::UserClass::ACTIVE_NTP_USER: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 555 Status fetch_status) { | 574 Status fetch_status) { |
| 556 background_fetch_in_progress_ = false; | 575 background_fetch_in_progress_ = false; |
| 557 OnFetchCompleted(fetch_status); | 576 OnFetchCompleted(fetch_status); |
| 558 if (callback) { | 577 if (callback) { |
| 559 callback->Run(fetch_status); | 578 callback->Run(fetch_status); |
| 560 } | 579 } |
| 561 } | 580 } |
| 562 | 581 |
| 563 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted( | 582 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted( |
| 564 Status fetch_status) { | 583 Status fetch_status) { |
| 565 pref_service_->SetInt64(prefs::kSnippetLastFetchAttempt, | 584 profile_prefs_->SetInt64(prefs::kSnippetLastFetchAttempt, |
| 566 clock_->Now().ToInternalValue()); | 585 clock_->Now().ToInternalValue()); |
| 567 | 586 |
| 568 // Reschedule after a fetch. The persistent schedule is applied only after a | 587 // Reschedule after a fetch. The persistent schedule is applied only after a |
| 569 // successful fetch. After a failed fetch, we want to keep the previous | 588 // successful fetch. After a failed fetch, we want to keep the previous |
| 570 // persistent schedule intact so that we eventually get a persistent | 589 // persistent schedule intact so that we eventually get a persistent |
| 571 // fallback fetch (if the wifi persistent fetches keep failing). | 590 // fallback fetch (if the wifi persistent fetches keep failing). |
| 572 if (fetch_status.code != StatusCode::SUCCESS) { | 591 if (fetch_status.code != StatusCode::SUCCESS) { |
| 573 return; | 592 return; |
| 574 } | 593 } |
| 575 ApplyPersistentFetchingSchedule(); | 594 ApplyPersistentFetchingSchedule(); |
| 576 } | 595 } |
| 577 | 596 |
| 578 void SchedulingRemoteSuggestionsProvider::ClearLastFetchAttemptTime() { | 597 void SchedulingRemoteSuggestionsProvider::ClearLastFetchAttemptTime() { |
| 579 pref_service_->ClearPref(prefs::kSnippetLastFetchAttempt); | 598 profile_prefs_->ClearPref(prefs::kSnippetLastFetchAttempt); |
| 580 } | 599 } |
| 581 | 600 |
| 582 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> | 601 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> |
| 583 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() { | 602 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() { |
| 584 static_assert(static_cast<unsigned int>(TriggerType::COUNT) == | 603 static_assert(static_cast<unsigned int>(TriggerType::COUNT) == |
| 585 arraysize(kTriggerTypeNames), | 604 arraysize(kTriggerTypeNames), |
| 586 "Fill in names for trigger types."); | 605 "Fill in names for trigger types."); |
| 587 | 606 |
| 588 std::string param_value = base::GetFieldTrialParamValueByFeature( | 607 std::string param_value = base::GetFieldTrialParamValueByFeature( |
| 589 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName); | 608 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 618 return enabled_types; | 637 return enabled_types; |
| 619 } | 638 } |
| 620 | 639 |
| 621 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> | 640 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> |
| 622 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { | 641 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { |
| 623 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, | 642 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, |
| 624 TriggerType::BROWSER_FOREGROUNDED}; | 643 TriggerType::BROWSER_FOREGROUNDED}; |
| 625 } | 644 } |
| 626 | 645 |
| 627 } // namespace ntp_snippets | 646 } // namespace ntp_snippets |
| OLD | NEW |