Chromium Code Reviews| 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/remote_suggestions_scheduler_impl.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 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 break; | 138 break; |
| 139 } | 139 } |
| 140 | 140 |
| 141 double value_hours = base::GetFieldTrialParamByFeatureAsDouble( | 141 double value_hours = base::GetFieldTrialParamByFeatureAsDouble( |
| 142 ntp_snippets::kArticleSuggestionsFeature, param_name, | 142 ntp_snippets::kArticleSuggestionsFeature, param_name, |
| 143 default_value_hours); | 143 default_value_hours); |
| 144 | 144 |
| 145 return base::TimeDelta::FromSecondsD(value_hours * 3600.0); | 145 return base::TimeDelta::FromSecondsD(value_hours * 3600.0); |
| 146 } | 146 } |
| 147 | 147 |
| 148 void ReportTimeUntilFirstTrigger(UserClassifier::UserClass user_class, | |
|
Marc Treib
2017/04/12 13:43:30
optional: s/FirstTrigger/FirstSoftTrigger/ ?
jkrcal
2017/04/12 14:03:27
Done.
| |
| 149 base::TimeDelta time_until_first_trigger) { | |
| 150 switch (user_class) { | |
| 151 case UserClassifier::UserClass::RARE_NTP_USER: | |
| 152 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 153 "NewTabPage.ContentSuggestions.TimeUntilFirstTrigger_RareNTPUser", | |
| 154 time_until_first_trigger, base::TimeDelta::FromSeconds(1), | |
| 155 base::TimeDelta::FromDays(7), | |
| 156 /*bucket_count=*/100); | |
| 157 break; | |
| 158 case UserClassifier::UserClass::ACTIVE_NTP_USER: | |
| 159 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 160 "NewTabPage.ContentSuggestions.TimeUntilFirstTrigger_ActiveNTPUser", | |
| 161 time_until_first_trigger, base::TimeDelta::FromSeconds(1), | |
| 162 base::TimeDelta::FromDays(7), | |
| 163 /*bucket_count=*/100); | |
| 164 break; | |
| 165 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: | |
| 166 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 167 "NewTabPage.ContentSuggestions.TimeUntilFirstTrigger_" | |
| 168 "ActiveSuggestionsConsumer", | |
| 169 time_until_first_trigger, base::TimeDelta::FromSeconds(1), | |
| 170 base::TimeDelta::FromDays(7), | |
| 171 /*bucket_count=*/100); | |
| 172 break; | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 void ReportTimeUntilFirstSuccessfulTrigger( | |
|
Marc Treib
2017/04/12 13:43:30
similar here
jkrcal
2017/04/12 14:03:27
Actually renamed even better to match the Persiste
| |
| 177 UserClassifier::UserClass user_class, | |
| 178 base::TimeDelta time_until_first_successful_trigger) { | |
| 179 switch (user_class) { | |
| 180 case UserClassifier::UserClass::RARE_NTP_USER: | |
| 181 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 182 "NewTabPage.ContentSuggestions.TimeUntilFirstSuccessfulTrigger_" | |
| 183 "RareNTPUser", | |
| 184 time_until_first_successful_trigger, base::TimeDelta::FromSeconds(1), | |
| 185 base::TimeDelta::FromDays(7), | |
| 186 /*bucket_count=*/100); | |
| 187 break; | |
| 188 case UserClassifier::UserClass::ACTIVE_NTP_USER: | |
| 189 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 190 "NewTabPage.ContentSuggestions.TimeUntilFirstSuccessfulTrigger_" | |
| 191 "ActiveNTPUser", | |
| 192 time_until_first_successful_trigger, base::TimeDelta::FromSeconds(1), | |
| 193 base::TimeDelta::FromDays(7), | |
| 194 /*bucket_count=*/100); | |
| 195 break; | |
| 196 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: | |
| 197 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 198 "NewTabPage.ContentSuggestions.TimeUntilFirstSuccessfulTrigger_" | |
| 199 "ActiveSuggestionsConsumer", | |
| 200 time_until_first_successful_trigger, base::TimeDelta::FromSeconds(1), | |
| 201 base::TimeDelta::FromDays(7), | |
| 202 /*bucket_count=*/100); | |
| 203 break; | |
| 204 } | |
| 205 } | |
| 206 | |
| 207 void ReportTimeUntilPersistentFetch( | |
| 208 UserClassifier::UserClass user_class, | |
| 209 base::TimeDelta time_until_persistent_fetch) { | |
| 210 switch (user_class) { | |
| 211 case UserClassifier::UserClass::RARE_NTP_USER: | |
| 212 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 213 "NewTabPage.ContentSuggestions.TimeUntilPersistentFetch_" | |
| 214 "RareNTPUser", | |
| 215 time_until_persistent_fetch, base::TimeDelta::FromSeconds(1), | |
| 216 base::TimeDelta::FromDays(7), | |
| 217 /*bucket_count=*/100); | |
| 218 break; | |
| 219 case UserClassifier::UserClass::ACTIVE_NTP_USER: | |
| 220 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 221 "NewTabPage.ContentSuggestions.TimeUntilPersistentFetch_" | |
| 222 "ActiveNTPUser", | |
| 223 time_until_persistent_fetch, base::TimeDelta::FromSeconds(1), | |
| 224 base::TimeDelta::FromDays(7), | |
| 225 /*bucket_count=*/100); | |
| 226 break; | |
| 227 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: | |
| 228 UMA_HISTOGRAM_CUSTOM_TIMES( | |
| 229 "NewTabPage.ContentSuggestions.TimeUntilPersistentFetch_" | |
| 230 "ActiveSuggestionsConsumer", | |
| 231 time_until_persistent_fetch, base::TimeDelta::FromSeconds(1), | |
| 232 base::TimeDelta::FromDays(7), | |
| 233 /*bucket_count=*/100); | |
| 234 break; | |
| 235 } | |
| 236 } | |
| 237 | |
| 148 } // namespace | 238 } // namespace |
| 149 | 239 |
| 150 class EulaState : public web_resource::EulaAcceptedNotifier::Observer { | 240 class EulaState : public web_resource::EulaAcceptedNotifier::Observer { |
| 151 public: | 241 public: |
| 152 EulaState(PrefService* local_state_prefs, | 242 EulaState(PrefService* local_state_prefs, |
| 153 RemoteSuggestionsScheduler* scheduler) | 243 RemoteSuggestionsScheduler* scheduler) |
| 154 : eula_notifier_( | 244 : eula_notifier_( |
| 155 web_resource::EulaAcceptedNotifier::Create(local_state_prefs)), | 245 web_resource::EulaAcceptedNotifier::Create(local_state_prefs)), |
| 156 scheduler_(scheduler) { | 246 scheduler_(scheduler) { |
| 157 // EulaNotifier is not constructed on some platforms (such as desktop). | 247 // EulaNotifier is not constructed on some platforms (such as desktop). |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 RequestThrottler::RequestType:: | 329 RequestThrottler::RequestType:: |
| 240 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), | 330 CONTENT_SUGGESTION_FETCHER_RARE_NTP_USER), |
| 241 request_throttler_active_ntp_user_( | 331 request_throttler_active_ntp_user_( |
| 242 profile_prefs, | 332 profile_prefs, |
| 243 RequestThrottler::RequestType:: | 333 RequestThrottler::RequestType:: |
| 244 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), | 334 CONTENT_SUGGESTION_FETCHER_ACTIVE_NTP_USER), |
| 245 request_throttler_active_suggestions_consumer_( | 335 request_throttler_active_suggestions_consumer_( |
| 246 profile_prefs, | 336 profile_prefs, |
| 247 RequestThrottler::RequestType:: | 337 RequestThrottler::RequestType:: |
| 248 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), | 338 CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER), |
| 339 time_until_first_trigger_reported_(false), | |
| 249 eula_state_(base::MakeUnique<EulaState>(local_state_prefs, this)), | 340 eula_state_(base::MakeUnique<EulaState>(local_state_prefs, this)), |
| 250 profile_prefs_(profile_prefs), | 341 profile_prefs_(profile_prefs), |
| 251 clock_(std::move(clock)), | 342 clock_(std::move(clock)), |
| 252 enabled_triggers_(GetEnabledTriggerTypes()) { | 343 enabled_triggers_(GetEnabledTriggerTypes()) { |
| 253 DCHECK(user_classifier); | 344 DCHECK(user_classifier); |
| 254 DCHECK(profile_prefs); | 345 DCHECK(profile_prefs); |
| 255 | 346 |
| 256 // Cleanup procedure in M59. Remove for M62. | 347 // Cleanup procedure in M59. Remove for M62. |
| 257 profile_prefs_->ClearPref(kSnippetSoftFetchingIntervalOnUsageEventDeprecated); | 348 profile_prefs_->ClearPref(kSnippetSoftFetchingIntervalOnUsageEventDeprecated); |
| 258 profile_prefs_->ClearPref(kSnippetSoftFetchingIntervalOnNtpOpenedDeprecated); | 349 profile_prefs_->ClearPref(kSnippetSoftFetchingIntervalOnNtpOpenedDeprecated); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundIfAppropriate( | 522 void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundIfAppropriate( |
| 432 TriggerType trigger) { | 523 TriggerType trigger) { |
| 433 if (background_fetch_in_progress_) { | 524 if (background_fetch_in_progress_) { |
| 434 return; | 525 return; |
| 435 } | 526 } |
| 436 | 527 |
| 437 if (BackgroundFetchesDisabled(trigger)) { | 528 if (BackgroundFetchesDisabled(trigger)) { |
| 438 return; | 529 return; |
| 439 } | 530 } |
| 440 | 531 |
| 441 if (trigger != TriggerType::PERSISTENT_SCHEDULER_WAKE_UP && | 532 bool is_soft = trigger != TriggerType::PERSISTENT_SCHEDULER_WAKE_UP; |
| 442 !ShouldRefetchInTheBackgroundNow()) { | 533 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( |
| 534 profile_prefs_->GetInt64(prefs::kSnippetLastFetchAttempt)); | |
| 535 | |
| 536 if (is_soft && !time_until_first_trigger_reported_) { | |
| 537 time_until_first_trigger_reported_ = true; | |
| 538 ReportTimeUntilFirstTrigger(user_classifier_->GetUserClass(), | |
| 539 clock_->Now() - last_fetch_attempt_time); | |
| 540 } | |
| 541 | |
| 542 if (is_soft && !ShouldRefetchInTheBackgroundNow(last_fetch_attempt_time)) { | |
| 443 return; | 543 return; |
| 444 } | 544 } |
| 445 | 545 |
| 446 if (!AcquireQuota(/*interactive_request=*/false)) { | 546 if (!AcquireQuota(/*interactive_request=*/false)) { |
| 447 return; | 547 return; |
| 448 } | 548 } |
| 449 | 549 |
| 550 if (is_soft) { | |
| 551 ReportTimeUntilFirstSuccessfulTrigger( | |
| 552 user_classifier_->GetUserClass(), | |
| 553 clock_->Now() - last_fetch_attempt_time); | |
| 554 } else { | |
| 555 ReportTimeUntilPersistentFetch(user_classifier_->GetUserClass(), | |
| 556 clock_->Now() - last_fetch_attempt_time); | |
| 557 } | |
| 558 | |
| 450 UMA_HISTOGRAM_ENUMERATION( | 559 UMA_HISTOGRAM_ENUMERATION( |
| 451 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", | 560 "NewTabPage.ContentSuggestions.BackgroundFetchTrigger", |
| 452 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); | 561 static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT)); |
| 453 | 562 |
| 454 background_fetch_in_progress_ = true; | 563 background_fetch_in_progress_ = true; |
| 455 provider_->RefetchInTheBackground(base::Bind( | 564 provider_->RefetchInTheBackground(base::Bind( |
| 456 &RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundFinished, | 565 &RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundFinished, |
| 457 base::Unretained(this))); | 566 base::Unretained(this))); |
| 458 } | 567 } |
| 459 | 568 |
| 460 bool RemoteSuggestionsSchedulerImpl::ShouldRefetchInTheBackgroundNow() { | 569 bool RemoteSuggestionsSchedulerImpl::ShouldRefetchInTheBackgroundNow( |
| 461 const base::Time last_fetch_attempt_time = base::Time::FromInternalValue( | 570 base::Time last_fetch_attempt_time) { |
| 462 profile_prefs_->GetInt64(prefs::kSnippetLastFetchAttempt)); | |
| 463 | |
| 464 // If we have no persistent scheduler to ask, err on the side of caution. | 571 // If we have no persistent scheduler to ask, err on the side of caution. |
| 465 bool wifi = false; | 572 bool wifi = false; |
| 466 if (persistent_scheduler_) { | 573 if (persistent_scheduler_) { |
| 467 wifi = persistent_scheduler_->IsOnUnmeteredConnection(); | 574 wifi = persistent_scheduler_->IsOnUnmeteredConnection(); |
| 468 } | 575 } |
| 469 | 576 |
| 470 base::Time first_allowed_fetch_time = | 577 base::Time first_allowed_fetch_time = |
| 471 last_fetch_attempt_time + | 578 last_fetch_attempt_time + |
| 472 (wifi ? schedule_.interval_soft_wifi : schedule_.interval_soft_fallback); | 579 (wifi ? schedule_.interval_soft_wifi : schedule_.interval_soft_fallback); |
| 473 base::Time now = clock_->Now(); | 580 base::Time now = clock_->Now(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 | 621 |
| 515 void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundFinished( | 622 void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundFinished( |
| 516 Status fetch_status) { | 623 Status fetch_status) { |
| 517 background_fetch_in_progress_ = false; | 624 background_fetch_in_progress_ = false; |
| 518 OnFetchCompleted(fetch_status); | 625 OnFetchCompleted(fetch_status); |
| 519 } | 626 } |
| 520 | 627 |
| 521 void RemoteSuggestionsSchedulerImpl::OnFetchCompleted(Status fetch_status) { | 628 void RemoteSuggestionsSchedulerImpl::OnFetchCompleted(Status fetch_status) { |
| 522 profile_prefs_->SetInt64(prefs::kSnippetLastFetchAttempt, | 629 profile_prefs_->SetInt64(prefs::kSnippetLastFetchAttempt, |
| 523 clock_->Now().ToInternalValue()); | 630 clock_->Now().ToInternalValue()); |
| 631 time_until_first_trigger_reported_ = false; | |
| 524 | 632 |
| 525 // Reschedule after a fetch. The persistent schedule is applied only after a | 633 // Reschedule after a fetch. The persistent schedule is applied only after a |
| 526 // successful fetch. After a failed fetch, we want to keep the previous | 634 // successful fetch. After a failed fetch, we want to keep the previous |
| 527 // persistent schedule intact so that we eventually get a persistent | 635 // persistent schedule intact so that we eventually get a persistent |
| 528 // fallback fetch (if the wifi persistent fetches keep failing). | 636 // fallback fetch (if the wifi persistent fetches keep failing). |
| 529 if (fetch_status.code != StatusCode::SUCCESS) { | 637 if (fetch_status.code != StatusCode::SUCCESS) { |
| 530 return; | 638 return; |
| 531 } | 639 } |
| 532 ApplyPersistentFetchingSchedule(); | 640 ApplyPersistentFetchingSchedule(); |
| 533 } | 641 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 return enabled_types; | 683 return enabled_types; |
| 576 } | 684 } |
| 577 | 685 |
| 578 std::set<RemoteSuggestionsSchedulerImpl::TriggerType> | 686 std::set<RemoteSuggestionsSchedulerImpl::TriggerType> |
| 579 RemoteSuggestionsSchedulerImpl::GetDefaultEnabledTriggerTypes() { | 687 RemoteSuggestionsSchedulerImpl::GetDefaultEnabledTriggerTypes() { |
| 580 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, | 688 return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED, |
| 581 TriggerType::BROWSER_FOREGROUNDED}; | 689 TriggerType::BROWSER_FOREGROUNDED}; |
| 582 } | 690 } |
| 583 | 691 |
| 584 } // namespace ntp_snippets | 692 } // namespace ntp_snippets |
| OLD | NEW |