| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chrome/browser/engagement/site_engagement_service.h" | 5 #include "chrome/browser/engagement/site_engagement_service.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 // Check if we need to reset last engagement times on startup - we want to | 282 // Check if we need to reset last engagement times on startup - we want to |
| 283 // avoid doing this in AddPoints() if possible. It is still necessary to check | 283 // avoid doing this in AddPoints() if possible. It is still necessary to check |
| 284 // in AddPoints for people who never restart Chrome, but leave it open and | 284 // in AddPoints for people who never restart Chrome, but leave it open and |
| 285 // their computer on standby. | 285 // their computer on standby. |
| 286 CleanupEngagementScores(IsLastEngagementStale()); | 286 CleanupEngagementScores(IsLastEngagementStale()); |
| 287 RecordMetrics(); | 287 RecordMetrics(); |
| 288 } | 288 } |
| 289 | 289 |
| 290 void SiteEngagementService::CleanupEngagementScores( | 290 void SiteEngagementService::CleanupEngagementScores( |
| 291 bool update_last_engagement_time) const { | 291 bool update_last_engagement_time) const { |
| 292 // This method should not be called with |update_last_engagement_time| = true | |
| 293 // if the last engagement time isn't stale. | |
| 294 DCHECK(!update_last_engagement_time || IsLastEngagementStale()); | |
| 295 | |
| 296 HostContentSettingsMap* settings_map = | 292 HostContentSettingsMap* settings_map = |
| 297 HostContentSettingsMapFactory::GetForProfile(profile_); | 293 HostContentSettingsMapFactory::GetForProfile(profile_); |
| 298 std::unique_ptr<ContentSettingsForOneType> engagement_settings = | 294 std::unique_ptr<ContentSettingsForOneType> engagement_settings = |
| 299 GetEngagementContentSettings(settings_map); | 295 GetEngagementContentSettings(settings_map); |
| 300 | 296 |
| 301 // We want to rebase last engagement times relative to MaxDecaysPerScore | 297 // We want to rebase last engagement times relative to MaxDecaysPerScore |
| 302 // periods of decay in the past. | 298 // periods of decay in the past. |
| 303 base::Time now = clock_->Now(); | 299 base::Time now = clock_->Now(); |
| 304 base::Time last_engagement_time = GetLastEngagementTime(); | 300 base::Time last_engagement_time = GetLastEngagementTime(); |
| 305 base::Time rebase_time = now - GetMaxDecayPeriod(); | 301 base::Time rebase_time = now - GetMaxDecayPeriod(); |
| 306 base::Time new_last_engagement_time; | 302 base::Time new_last_engagement_time; |
| 303 |
| 304 // If |update_last_engagement_time| is true, we must have either: |
| 305 // a) last_engagement_time is in the future; OR |
| 306 // b) last_engagement_time < rebase_time < now |
| 307 DCHECK(!update_last_engagement_time || last_engagement_time >= now || |
| 308 (last_engagement_time < rebase_time && rebase_time < now)); |
| 309 |
| 310 // Cap |last_engagement_time| at |now| if it is in the future. This ensures |
| 311 // that we use sane offsets when a user has adjusted their clock backwards and |
| 312 // have a mix of scores prior to and after |now|. |
| 313 if (last_engagement_time > now) |
| 314 last_engagement_time = now; |
| 315 |
| 307 for (const auto& site : *engagement_settings) { | 316 for (const auto& site : *engagement_settings) { |
| 308 GURL origin(site.primary_pattern.ToString()); | 317 GURL origin(site.primary_pattern.ToString()); |
| 309 | 318 |
| 310 if (origin.is_valid()) { | 319 if (origin.is_valid()) { |
| 311 SiteEngagementScore score = CreateEngagementScore(origin); | 320 SiteEngagementScore score = CreateEngagementScore(origin); |
| 312 if (update_last_engagement_time) { | 321 if (update_last_engagement_time) { |
| 313 // Work out the offset between this score's last engagement time and the | 322 // Catch cases of users moving their clocks, or a potential race where |
| 314 // last time the service recorded any engagement. Set the score's last | 323 // a score content setting is written out to prefs, but the updated |
| 315 // engagement time to rebase_time - offset to preserve its state, | 324 // |last_engagement_time| was not written, as both are lossy |
| 316 // relative to the rebase date. This ensures that the score will decay | 325 // preferences. |rebase_time| is strictly in the past, so any score with |
| 317 // the next time it is used, but will not decay too much. | 326 // a last updated time in the future is caught by this branch. |
| 318 DCHECK_LE(score.last_engagement_time(), rebase_time); | 327 if (score.last_engagement_time() > rebase_time) { |
| 319 base::TimeDelta offset = | 328 score.set_last_engagement_time(now); |
| 320 last_engagement_time - score.last_engagement_time(); | 329 } else if (score.last_engagement_time() > last_engagement_time) { |
| 321 base::Time rebase_score_time = rebase_time - offset; | 330 // This score is newer than |last_engagement_time|, but older than |
| 322 score.set_last_engagement_time(rebase_score_time); | 331 // |rebase_time|. It should still be rebased with no offset as we |
| 323 if (rebase_score_time > new_last_engagement_time) | 332 // don't accurately know what the offset should be. |
| 324 new_last_engagement_time = rebase_score_time; | 333 score.set_last_engagement_time(rebase_time); |
| 334 } else { |
| 335 // Work out the offset between this score's last engagement time and |
| 336 // the last time the service recorded any engagement. Set the score's |
| 337 // last engagement time to rebase_time - offset to preserve its state, |
| 338 // relative to the rebase date. This ensures that the score will decay |
| 339 // the next time it is used, but will not decay too much. |
| 340 base::TimeDelta offset = |
| 341 last_engagement_time - score.last_engagement_time(); |
| 342 base::Time rebase_score_time = rebase_time - offset; |
| 343 score.set_last_engagement_time(rebase_score_time); |
| 344 } |
| 325 | 345 |
| 346 if (score.last_engagement_time() > new_last_engagement_time) |
| 347 new_last_engagement_time = score.last_engagement_time(); |
| 326 score.Commit(); | 348 score.Commit(); |
| 327 } | 349 } |
| 328 | 350 |
| 329 if (score.GetScore() > SiteEngagementScore::GetScoreCleanupThreshold()) | 351 if (score.GetScore() > SiteEngagementScore::GetScoreCleanupThreshold()) |
| 330 continue; | 352 continue; |
| 331 } | 353 } |
| 332 | 354 |
| 333 // This origin has a score of 0. Wipe it from content settings. | 355 // This origin has a score of 0. Wipe it from content settings. |
| 334 settings_map->SetWebsiteSettingDefaultScope( | 356 settings_map->SetWebsiteSettingDefaultScope( |
| 335 origin, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), | 357 origin, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 SiteEngagementMetrics::RecordEngagement(type); | 483 SiteEngagementMetrics::RecordEngagement(type); |
| 462 AddPoints(url, SiteEngagementScore::GetUserInputPoints()); | 484 AddPoints(url, SiteEngagementScore::GetUserInputPoints()); |
| 463 | 485 |
| 464 RecordMetrics(); | 486 RecordMetrics(); |
| 465 FOR_EACH_OBSERVER( | 487 FOR_EACH_OBSERVER( |
| 466 SiteEngagementObserver, observer_list_, | 488 SiteEngagementObserver, observer_list_, |
| 467 OnEngagementIncreased(web_contents, url, GetScore(url))); | 489 OnEngagementIncreased(web_contents, url, GetScore(url))); |
| 468 } | 490 } |
| 469 | 491 |
| 470 bool SiteEngagementService::IsLastEngagementStale() const { | 492 bool SiteEngagementService::IsLastEngagementStale() const { |
| 471 // This only happens when Chrome is first run and the user has never recorded | 493 // Only happens on first run when no engagement has ever been recorded. |
| 472 // any engagement. | |
| 473 base::Time last_engagement_time = GetLastEngagementTime(); | 494 base::Time last_engagement_time = GetLastEngagementTime(); |
| 474 if (last_engagement_time.is_null()) | 495 if (last_engagement_time.is_null()) |
| 475 return false; | 496 return false; |
| 476 | 497 |
| 477 return (clock_->Now() - last_engagement_time) >= GetStalePeriod(); | 498 // Stale is either too *far* back, or any amount *forward* in time. This could |
| 499 // occur due to a changed clock, or extended non-use of the browser. |
| 500 return (clock_->Now() - last_engagement_time) >= GetStalePeriod() || |
| 501 (clock_->Now() < last_engagement_time); |
| 478 } | 502 } |
| 479 | 503 |
| 480 void SiteEngagementService::OnURLsDeleted( | 504 void SiteEngagementService::OnURLsDeleted( |
| 481 history::HistoryService* history_service, | 505 history::HistoryService* history_service, |
| 482 bool all_history, | 506 bool all_history, |
| 483 bool expired, | 507 bool expired, |
| 484 const history::URLRows& deleted_rows, | 508 const history::URLRows& deleted_rows, |
| 485 const std::set<GURL>& favicon_urls) { | 509 const std::set<GURL>& favicon_urls) { |
| 486 std::multiset<GURL> origins; | 510 std::multiset<GURL> origins; |
| 487 for (const history::URLRow& row : deleted_rows) | 511 for (const history::URLRow& row : deleted_rows) |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 if (!engagement_score.last_shortcut_launch_time().is_null() && | 621 if (!engagement_score.last_shortcut_launch_time().is_null() && |
| 598 engagement_score.last_shortcut_launch_time() > last_visit) { | 622 engagement_score.last_shortcut_launch_time() > last_visit) { |
| 599 engagement_score.set_last_shortcut_launch_time(last_visit); | 623 engagement_score.set_last_shortcut_launch_time(last_visit); |
| 600 } | 624 } |
| 601 | 625 |
| 602 engagement_score.Commit(); | 626 engagement_score.Commit(); |
| 603 } | 627 } |
| 604 | 628 |
| 605 SetLastEngagementTime(now); | 629 SetLastEngagementTime(now); |
| 606 } | 630 } |
| OLD | NEW |