| 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 | 126 |
| 127 double value_hours = base::GetFieldTrialParamByFeatureAsDouble( | 127 double value_hours = base::GetFieldTrialParamByFeatureAsDouble( |
| 128 ntp_snippets::kArticleSuggestionsFeature, param_name, | 128 ntp_snippets::kArticleSuggestionsFeature, param_name, |
| 129 default_value_hours); | 129 default_value_hours); |
| 130 | 130 |
| 131 return base::TimeDelta::FromSecondsD(value_hours * 3600.0); | 131 return base::TimeDelta::FromSecondsD(value_hours * 3600.0); |
| 132 } | 132 } |
| 133 | 133 |
| 134 } // namespace | 134 } // namespace |
| 135 | 135 |
| 136 class EulaState : public web_resource::EulaAcceptedNotifier::Observer { |
| 137 public: |
| 138 EulaState(PrefService* local_state_prefs, |
| 139 RemoteSuggestionsScheduler* scheduler) |
| 140 : eula_notifier_( |
| 141 web_resource::EulaAcceptedNotifier::Create(local_state_prefs)), |
| 142 scheduler_(scheduler) { |
| 143 // EulaNotifier is not constructed on some platforms (such as desktop). |
| 144 if (!eula_notifier_) { |
| 145 return; |
| 146 } |
| 147 |
| 148 // Register the observer. |
| 149 eula_notifier_->Init(this); |
| 150 } |
| 151 |
| 152 ~EulaState() = default; |
| 153 |
| 154 bool IsEulaAccepted() { |
| 155 if (!eula_notifier_) { |
| 156 return true; |
| 157 } |
| 158 return eula_notifier_->IsEulaAccepted(); |
| 159 } |
| 160 |
| 161 // EulaAcceptedNotifier::Observer implementation. |
| 162 void OnEulaAccepted() override { |
| 163 // Emulate a browser foregrounded event. |
| 164 scheduler_->OnBrowserForegrounded(); |
| 165 } |
| 166 |
| 167 private: |
| 168 std::unique_ptr<web_resource::EulaAcceptedNotifier> eula_notifier_; |
| 169 RemoteSuggestionsScheduler* scheduler_; |
| 170 |
| 171 DISALLOW_COPY_AND_ASSIGN(EulaState); |
| 172 }; |
| 173 |
| 136 // static | 174 // static |
| 137 SchedulingRemoteSuggestionsProvider::FetchingSchedule | 175 SchedulingRemoteSuggestionsProvider::FetchingSchedule |
| 138 SchedulingRemoteSuggestionsProvider::FetchingSchedule::Empty() { | 176 SchedulingRemoteSuggestionsProvider::FetchingSchedule::Empty() { |
| 139 return FetchingSchedule{base::TimeDelta(), base::TimeDelta(), | 177 return FetchingSchedule{base::TimeDelta(), base::TimeDelta(), |
| 140 base::TimeDelta(), base::TimeDelta()}; | 178 base::TimeDelta(), base::TimeDelta()}; |
| 141 } | 179 } |
| 142 | 180 |
| 143 bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::operator==( | 181 bool SchedulingRemoteSuggestionsProvider::FetchingSchedule::operator==( |
| 144 const FetchingSchedule& other) const { | 182 const FetchingSchedule& other) const { |
| 145 return interval_persistent_wifi == other.interval_persistent_wifi && | 183 return interval_persistent_wifi == other.interval_persistent_wifi && |
| (...skipping 25 matching lines...) Expand all Loading... |
| 171 BROWSER_FOREGROUNDED = 2, | 209 BROWSER_FOREGROUNDED = 2, |
| 172 BROWSER_COLD_START = 3, | 210 BROWSER_COLD_START = 3, |
| 173 COUNT | 211 COUNT |
| 174 }; | 212 }; |
| 175 | 213 |
| 176 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider( | 214 SchedulingRemoteSuggestionsProvider::SchedulingRemoteSuggestionsProvider( |
| 177 Observer* observer, | 215 Observer* observer, |
| 178 std::unique_ptr<RemoteSuggestionsProvider> provider, | 216 std::unique_ptr<RemoteSuggestionsProvider> provider, |
| 179 PersistentScheduler* persistent_scheduler, | 217 PersistentScheduler* persistent_scheduler, |
| 180 const UserClassifier* user_classifier, | 218 const UserClassifier* user_classifier, |
| 181 PrefService* pref_service, | 219 PrefService* profile_prefs, |
| 220 PrefService* local_state_prefs, |
| 182 std::unique_ptr<base::Clock> clock) | 221 std::unique_ptr<base::Clock> clock) |
| 183 : RemoteSuggestionsProvider(observer), | 222 : RemoteSuggestionsProvider(observer), |
| 184 RemoteSuggestionsScheduler(), | 223 RemoteSuggestionsScheduler(), |
| 185 provider_(std::move(provider)), | 224 provider_(std::move(provider)), |
| 186 persistent_scheduler_(persistent_scheduler), | 225 persistent_scheduler_(persistent_scheduler), |
| 187 background_fetch_in_progress_(false), | 226 background_fetch_in_progress_(false), |
| 188 user_classifier_(user_classifier), | 227 user_classifier_(user_classifier), |
| 189 request_throttler_rare_ntp_user_( | 228 request_throttler_rare_ntp_user_( |
| 190 pref_service, | 229 profile_prefs, |
| 191 RequestThrottler::RequestType:: | 230 RequestThrottler::RequestType:: |
| 192 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), | 231 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), |
| 193 request_throttler_active_ntp_user_( | 232 request_throttler_active_ntp_user_( |
| 194 pref_service, | 233 profile_prefs, |
| 195 RequestThrottler::RequestType:: | 234 RequestThrottler::RequestType:: |
| 196 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), | 235 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), |
| 197 request_throttler_active_suggestions_consumer_( | 236 request_throttler_active_suggestions_consumer_( |
| 198 pref_service, | 237 profile_prefs, |
| 199 RequestThrottler::RequestType:: | 238 RequestThrottler::RequestType:: |
| 200 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), | 239 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), |
| 201 pref_service_(pref_service), | 240 eula_state_(base::MakeUnique<EulaState>(local_state_prefs, this)), |
| 241 profile_prefs_(profile_prefs), |
| 202 clock_(std::move(clock)), | 242 clock_(std::move(clock)), |
| 203 enabled_triggers_(GetEnabledTriggerTypes()) { | 243 enabled_triggers_(GetEnabledTriggerTypes()) { |
| 204 DCHECK(user_classifier); | 244 DCHECK(user_classifier); |
| 205 DCHECK(pref_service); | 245 DCHECK(profile_prefs); |
| 206 | 246 |
| 207 LoadLastFetchingSchedule(); | 247 LoadLastFetchingSchedule(); |
| 208 } | 248 } |
| 209 | 249 |
| 210 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = | 250 SchedulingRemoteSuggestionsProvider::~SchedulingRemoteSuggestionsProvider() = |
| 211 default; | 251 default; |
| 212 | 252 |
| 213 // static | 253 // static |
| 214 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( | 254 void SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( |
| 215 PrefRegistrySimple* registry) { | 255 PrefRegistrySimple* registry) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval( | 481 schedule.interval_soft_on_usage_event = GetDesiredFetchingInterval( |
| 442 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class); | 482 FetchingInterval::SOFT_ON_USAGE_EVENT, user_class); |
| 443 schedule.interval_soft_on_ntp_opened = GetDesiredFetchingInterval( | 483 schedule.interval_soft_on_ntp_opened = GetDesiredFetchingInterval( |
| 444 FetchingInterval::SOFT_ON_NTP_OPENED, user_class); | 484 FetchingInterval::SOFT_ON_NTP_OPENED, user_class); |
| 445 | 485 |
| 446 return schedule; | 486 return schedule; |
| 447 } | 487 } |
| 448 | 488 |
| 449 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() { | 489 void SchedulingRemoteSuggestionsProvider::LoadLastFetchingSchedule() { |
| 450 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue( | 490 schedule_.interval_persistent_wifi = base::TimeDelta::FromInternalValue( |
| 451 pref_service_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi)); | 491 profile_prefs_->GetInt64(prefs::kSnippetPersistentFetchingIntervalWifi)); |
| 452 schedule_.interval_persistent_fallback = | 492 schedule_.interval_persistent_fallback = |
| 453 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( | 493 base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64( |
| 454 prefs::kSnippetPersistentFetchingIntervalFallback)); | 494 prefs::kSnippetPersistentFetchingIntervalFallback)); |
| 455 schedule_.interval_soft_on_usage_event = base::TimeDelta::FromInternalValue( | 495 schedule_.interval_soft_on_usage_event = |
| 456 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnUsageEvent)); | 496 base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64( |
| 497 prefs::kSnippetSoftFetchingIntervalOnUsageEvent)); |
| 457 schedule_.interval_soft_on_ntp_opened = base::TimeDelta::FromInternalValue( | 498 schedule_.interval_soft_on_ntp_opened = base::TimeDelta::FromInternalValue( |
| 458 pref_service_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnNtpOpened)); | 499 profile_prefs_->GetInt64(prefs::kSnippetSoftFetchingIntervalOnNtpOpened)); |
| 459 } | 500 } |
| 460 | 501 |
| 461 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() { | 502 void SchedulingRemoteSuggestionsProvider::StoreFetchingSchedule() { |
| 462 pref_service_->SetInt64(prefs::kSnippetPersistentFetchingIntervalWifi, | 503 profile_prefs_->SetInt64( |
| 463 schedule_.interval_persistent_wifi.ToInternalValue()); | 504 prefs::kSnippetPersistentFetchingIntervalWifi, |
| 464 pref_service_->SetInt64( | 505 schedule_.interval_persistent_wifi.ToInternalValue()); |
| 506 profile_prefs_->SetInt64( |
| 465 prefs::kSnippetPersistentFetchingIntervalFallback, | 507 prefs::kSnippetPersistentFetchingIntervalFallback, |
| 466 schedule_.interval_persistent_fallback.ToInternalValue()); | 508 schedule_.interval_persistent_fallback.ToInternalValue()); |
| 467 pref_service_->SetInt64( | 509 profile_prefs_->SetInt64( |
| 468 prefs::kSnippetSoftFetchingIntervalOnUsageEvent, | 510 prefs::kSnippetSoftFetchingIntervalOnUsageEvent, |
| 469 schedule_.interval_soft_on_usage_event.ToInternalValue()); | 511 schedule_.interval_soft_on_usage_event.ToInternalValue()); |
| 470 pref_service_->SetInt64( | 512 profile_prefs_->SetInt64( |
| 471 prefs::kSnippetSoftFetchingIntervalOnNtpOpened, | 513 prefs::kSnippetSoftFetchingIntervalOnNtpOpened, |
| 472 schedule_.interval_soft_on_ntp_opened.ToInternalValue()); | 514 schedule_.interval_soft_on_ntp_opened.ToInternalValue()); |
| 473 } | 515 } |
| 474 | 516 |
| 475 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled( | 517 void SchedulingRemoteSuggestionsProvider::RefetchInTheBackgroundIfEnabled( |
| 476 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { | 518 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { |
| 477 if (BackgroundFetchesDisabled(trigger)) { | 519 if (BackgroundFetchesDisabled(trigger)) { |
| 478 return; | 520 return; |
| 479 } | 521 } |
| 480 | 522 |
| 481 UMA_HISTOGRAM_ENUMERATION( | 523 UMA_HISTOGRAM_ENUMERATION( |
| 482 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", | 524 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", |
| 483 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); | 525 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); |
| 484 | 526 |
| 485 RefetchInTheBackground(/*callback=*/nullptr); | 527 RefetchInTheBackground(/*callback=*/nullptr); |
| 486 } | 528 } |
| 487 | 529 |
| 488 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow( | 530 bool SchedulingRemoteSuggestionsProvider::ShouldRefetchInTheBackgroundNow( |
| 489 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { | 531 SchedulingRemoteSuggestionsProvider::TriggerType trigger) { |
| 490 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( | 532 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( |
| 491 pref_service_->GetInt64(prefs::kSnippetLastFetchAttempt)); | 533 profile_prefs_->GetInt64(prefs::kSnippetLastFetchAttempt)); |
| 492 base::Time first_allowed_fetch_time; | 534 base::Time first_allowed_fetch_time; |
| 493 switch (trigger) { | 535 switch (trigger) { |
| 494 case TriggerType::NTP_OPENED: | 536 case TriggerType::NTP_OPENED: |
| 495 first_allowed_fetch_time = | 537 first_allowed_fetch_time = |
| 496 last_fetch_attempt_time + schedule_.interval_soft_on_ntp_opened; | 538 last_fetch_attempt_time + schedule_.interval_soft_on_ntp_opened; |
| 497 break; | 539 break; |
| 498 case TriggerType::BROWSER_FOREGROUNDED: | 540 case TriggerType::BROWSER_FOREGROUNDED: |
| 499 case TriggerType::BROWSER_COLD_START: | 541 case TriggerType::BROWSER_COLD_START: |
| 500 first_allowed_fetch_time = | 542 first_allowed_fetch_time = |
| 501 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; | 543 last_fetch_attempt_time + schedule_.interval_soft_on_usage_event; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 513 | 555 |
| 514 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( | 556 bool SchedulingRemoteSuggestionsProvider::BackgroundFetchesDisabled( |
| 515 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { | 557 SchedulingRemoteSuggestionsProvider::TriggerType trigger) const { |
| 516 if (schedule_.is_empty()) { | 558 if (schedule_.is_empty()) { |
| 517 return true; // Background fetches are disabled in general. | 559 return true; // Background fetches are disabled in general. |
| 518 } | 560 } |
| 519 | 561 |
| 520 if (enabled_triggers_.count(trigger) == 0) { | 562 if (enabled_triggers_.count(trigger) == 0) { |
| 521 return true; // Background fetches for |trigger| are not enabled. | 563 return true; // Background fetches for |trigger| are not enabled. |
| 522 } | 564 } |
| 565 |
| 566 if (!eula_state_->IsEulaAccepted()) { |
| 567 return true; // No background fetches are allowed before EULA is accepted. |
| 568 } |
| 569 |
| 523 return false; | 570 return false; |
| 524 } | 571 } |
| 525 | 572 |
| 526 bool SchedulingRemoteSuggestionsProvider::AcquireQuota( | 573 bool SchedulingRemoteSuggestionsProvider::AcquireQuota( |
| 527 bool interactive_request) { | 574 bool interactive_request) { |
| 528 switch (user_classifier_->GetUserClass()) { | 575 switch (user_classifier_->GetUserClass()) { |
| 529 case UserClassifier::UserClass::RARE_NTP_USER: | 576 case UserClassifier::UserClass::RARE_NTP_USER: |
| 530 return request_throttler_rare_ntp_user_.DemandQuotaForRequest( | 577 return request_throttler_rare_ntp_user_.DemandQuotaForRequest( |
| 531 interactive_request); | 578 interactive_request); |
| 532 case UserClassifier::UserClass::ACTIVE_NTP_USER: | 579 case UserClassifier::UserClass::ACTIVE_NTP_USER: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 555 Status fetch_status) { | 602 Status fetch_status) { |
| 556 background_fetch_in_progress_ = false; | 603 background_fetch_in_progress_ = false; |
| 557 OnFetchCompleted(fetch_status); | 604 OnFetchCompleted(fetch_status); |
| 558 if (callback) { | 605 if (callback) { |
| 559 callback->Run(fetch_status); | 606 callback->Run(fetch_status); |
| 560 } | 607 } |
| 561 } | 608 } |
| 562 | 609 |
| 563 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted( | 610 void SchedulingRemoteSuggestionsProvider::OnFetchCompleted( |
| 564 Status fetch_status) { | 611 Status fetch_status) { |
| 565 pref_service_->SetInt64(prefs::kSnippetLastFetchAttempt, | 612 profile_prefs_->SetInt64(prefs::kSnippetLastFetchAttempt, |
| 566 clock_->Now().ToInternalValue()); | 613 clock_->Now().ToInternalValue()); |
| 567 | 614 |
| 568 // Reschedule after a fetch. The persistent schedule is applied only after a | 615 // 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 | 616 // successful fetch. After a failed fetch, we want to keep the previous |
| 570 // persistent schedule intact so that we eventually get a persistent | 617 // persistent schedule intact so that we eventually get a persistent |
| 571 // fallback fetch (if the wifi persistent fetches keep failing). | 618 // fallback fetch (if the wifi persistent fetches keep failing). |
| 572 if (fetch_status.code != StatusCode::SUCCESS) { | 619 if (fetch_status.code != StatusCode::SUCCESS) { |
| 573 return; | 620 return; |
| 574 } | 621 } |
| 575 ApplyPersistentFetchingSchedule(); | 622 ApplyPersistentFetchingSchedule(); |
| 576 } | 623 } |
| 577 | 624 |
| 578 void SchedulingRemoteSuggestionsProvider::ClearLastFetchAttemptTime() { | 625 void SchedulingRemoteSuggestionsProvider::ClearLastFetchAttemptTime() { |
| 579 pref_service_->ClearPref(prefs::kSnippetLastFetchAttempt); | 626 profile_prefs_->ClearPref(prefs::kSnippetLastFetchAttempt); |
| 580 } | 627 } |
| 581 | 628 |
| 582 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> | 629 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> |
| 583 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() { | 630 SchedulingRemoteSuggestionsProvider::GetEnabledTriggerTypes() { |
| 584 static_assert(static_cast<unsigned int>(TriggerType::COUNT) == | 631 static_assert(static_cast<unsigned int>(TriggerType::COUNT) == |
| 585 arraysize(kTriggerTypeNames), | 632 arraysize(kTriggerTypeNames), |
| 586 "Fill in names for trigger types."); | 633 "Fill in names for trigger types."); |
| 587 | 634 |
| 588 std::string param_value = base::GetFieldTrialParamValueByFeature( | 635 std::string param_value = base::GetFieldTrialParamValueByFeature( |
| 589 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName); | 636 ntp_snippets::kArticleSuggestionsFeature, kTriggerTypesParamName); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 618 return enabled_types; | 665 return enabled_types; |
| 619 } | 666 } |
| 620 | 667 |
| 621 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> | 668 std::set<SchedulingRemoteSuggestionsProvider::TriggerType> |
| 622 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { | 669 SchedulingRemoteSuggestionsProvider::GetDefaultEnabledTriggerTypes() { |
| 623 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, | 670 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, |
| 624 TriggerType::BROWSER_FOREGROUNDED}; | 671 TriggerType::BROWSER_FOREGROUNDED}; |
| 625 } | 672 } |
| 626 | 673 |
| 627 } // namespace ntp_snippets | 674 } // namespace ntp_snippets |
| OLD | NEW |