Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: chrome/browser/engagement/site_engagement_service.cc

Issue 1908443003: Set site engagement timestamps to privacy-respectful values when history is cleared. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2704
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include <algorithm> 8 #include <algorithm>
9 #include <cmath> 9 #include <cmath>
10 #include <utility> 10 #include <utility>
(...skipping 16 matching lines...) Expand all
27 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
28 #include "components/content_settings/core/browser/host_content_settings_map.h" 28 #include "components/content_settings/core/browser/host_content_settings_map.h"
29 #include "components/content_settings/core/common/content_settings_pattern.h" 29 #include "components/content_settings/core/common/content_settings_pattern.h"
30 #include "components/history/core/browser/history_service.h" 30 #include "components/history/core/browser/history_service.h"
31 #include "components/variations/variations_associated_data.h" 31 #include "components/variations/variations_associated_data.h"
32 #include "content/public/browser/browser_thread.h" 32 #include "content/public/browser/browser_thread.h"
33 #include "url/gurl.h" 33 #include "url/gurl.h"
34 34
35 namespace { 35 namespace {
36 36
37 const int FOUR_WEEKS_IN_DAYS = 28;
38
37 // Global bool to ensure we only update the parameters from variations once. 39 // Global bool to ensure we only update the parameters from variations once.
38 bool g_updated_from_variations = false; 40 bool g_updated_from_variations = false;
39 41
40 // Keys used in the variations params. Order matches 42 // Keys used in the variations params. Order matches
41 // SiteEngagementScore::Variation enum. 43 // SiteEngagementScore::Variation enum.
42 const char* kVariationNames[] = { 44 const char* kVariationNames[] = {
43 "max_points_per_day", 45 "max_points_per_day",
44 "decay_period_in_days", 46 "decay_period_in_days",
45 "decay_points", 47 "decay_points",
46 "navigation_points", 48 "navigation_points",
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 double to_add = std::min(kMaxPoints - raw_score_, 262 double to_add = std::min(kMaxPoints - raw_score_,
261 GetMaxPointsPerDay() - points_added_today_); 263 GetMaxPointsPerDay() - points_added_today_);
262 to_add = std::min(to_add, points); 264 to_add = std::min(to_add, points);
263 265
264 points_added_today_ += to_add; 266 points_added_today_ += to_add;
265 raw_score_ += to_add; 267 raw_score_ += to_add;
266 268
267 last_engagement_time_ = now; 269 last_engagement_time_ = now;
268 } 270 }
269 271
270 void SiteEngagementScore::Reset(double points) { 272 void SiteEngagementScore::Reset(double points, const base::Time* updated_time) {
271 raw_score_ = points; 273 raw_score_ = points;
272 points_added_today_ = 0; 274 points_added_today_ = 0;
273 275
274 // This must be set in order to prevent the score from decaying when read. 276 // This must be set in order to prevent the score from decaying when read.
275 last_engagement_time_ = clock_->Now(); 277 if (updated_time) {
278 last_engagement_time_ = *updated_time;
279 if (!last_shortcut_launch_time_.is_null())
280 last_shortcut_launch_time_ = *updated_time;
281 } else {
282 last_engagement_time_ = clock_->Now();
283 }
276 } 284 }
277 285
278 bool SiteEngagementScore::MaxPointsPerDayAdded() const { 286 bool SiteEngagementScore::MaxPointsPerDayAdded() const {
279 if (!last_engagement_time_.is_null() && 287 if (!last_engagement_time_.is_null() &&
280 clock_->Now().LocalMidnight() != last_engagement_time_.LocalMidnight()) { 288 clock_->Now().LocalMidnight() != last_engagement_time_.LocalMidnight()) {
281 return false; 289 return false;
282 } 290 }
283 291
284 return points_added_today_ == GetMaxPointsPerDay(); 292 return points_added_today_ == GetMaxPointsPerDay();
285 } 293 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 bool is_hidden) { 446 bool is_hidden) {
439 SiteEngagementMetrics::RecordEngagement( 447 SiteEngagementMetrics::RecordEngagement(
440 is_hidden ? SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN 448 is_hidden ? SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN
441 : SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE); 449 : SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE);
442 AddPoints(url, is_hidden ? SiteEngagementScore::GetHiddenMediaPoints() 450 AddPoints(url, is_hidden ? SiteEngagementScore::GetHiddenMediaPoints()
443 : SiteEngagementScore::GetVisibleMediaPoints()); 451 : SiteEngagementScore::GetVisibleMediaPoints());
444 RecordMetrics(); 452 RecordMetrics();
445 } 453 }
446 454
447 void SiteEngagementService::ResetScoreForURL(const GURL& url, double score) { 455 void SiteEngagementService::ResetScoreForURL(const GURL& url, double score) {
448 DCHECK(url.is_valid()); 456 ResetScoreAndAccessTimesForURL(url, score, nullptr);
449 DCHECK_GE(score, 0);
450 DCHECK_LE(score, SiteEngagementScore::kMaxPoints);
451
452 HostContentSettingsMap* settings_map =
453 HostContentSettingsMapFactory::GetForProfile(profile_);
454 scoped_ptr<base::DictionaryValue> score_dict =
455 GetScoreDictForOrigin(settings_map, url);
456 SiteEngagementScore engagement_score(clock_.get(), *score_dict);
457
458 engagement_score.Reset(score);
459 if (score == 0) {
460 settings_map->SetWebsiteSettingDefaultScope(
461 url, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
462 nullptr);
463 return;
464 }
465
466 if (engagement_score.UpdateScoreDict(score_dict.get())) {
467 settings_map->SetWebsiteSettingDefaultScope(
468 url, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
469 score_dict.release());
470 }
471 } 457 }
472 458
473 void SiteEngagementService::OnURLsDeleted( 459 void SiteEngagementService::OnURLsDeleted(
474 history::HistoryService* history_service, 460 history::HistoryService* history_service,
475 bool all_history, 461 bool all_history,
476 bool expired, 462 bool expired,
477 const history::URLRows& deleted_rows, 463 const history::URLRows& deleted_rows,
478 const std::set<GURL>& favicon_urls) { 464 const std::set<GURL>& favicon_urls) {
479 std::multiset<GURL> origins; 465 std::multiset<GURL> origins;
480 for (const history::URLRow& row : deleted_rows) 466 for (const history::URLRow& row : deleted_rows)
481 origins.insert(row.url().GetOrigin()); 467 origins.insert(row.url().GetOrigin());
482 468
483 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( 469 history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
484 profile_, ServiceAccessType::EXPLICIT_ACCESS); 470 profile_, ServiceAccessType::EXPLICIT_ACCESS);
485 hs->GetCountsForOrigins( 471 hs->GetCountsAndLastVisitForOrigins(
486 std::set<GURL>(origins.begin(), origins.end()), 472 std::set<GURL>(origins.begin(), origins.end()),
487 base::Bind(&SiteEngagementService::GetCountsForOriginsComplete, 473 base::Bind(
488 weak_factory_.GetWeakPtr(), origins, expired)); 474 &SiteEngagementService::GetCountsAndLastVisitForOriginsComplete,
475 weak_factory_.GetWeakPtr(), hs, origins, expired));
489 } 476 }
490 477
491 void SiteEngagementService::SetLastShortcutLaunchTime(const GURL& url) { 478 void SiteEngagementService::SetLastShortcutLaunchTime(const GURL& url) {
492 HostContentSettingsMap* settings_map = 479 HostContentSettingsMap* settings_map =
493 HostContentSettingsMapFactory::GetForProfile(profile_); 480 HostContentSettingsMapFactory::GetForProfile(profile_);
494 scoped_ptr<base::DictionaryValue> score_dict = 481 scoped_ptr<base::DictionaryValue> score_dict =
495 GetScoreDictForOrigin(settings_map, url); 482 GetScoreDictForOrigin(settings_map, url);
496 SiteEngagementScore score(clock_.get(), *score_dict); 483 SiteEngagementScore score(clock_.get(), *score_dict);
497 484
498 // Record the number of days since the last launch in UMA. If the user's clock 485 // Record the number of days since the last launch in UMA. If the user's clock
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 const std::map<GURL, double>& score_map) const { 723 const std::map<GURL, double>& score_map) const {
737 int total_origins = 0; 724 int total_origins = 0;
738 725
739 for (const auto& value : score_map) 726 for (const auto& value : score_map)
740 if (value.second == SiteEngagementScore::kMaxPoints) 727 if (value.second == SiteEngagementScore::kMaxPoints)
741 ++total_origins; 728 ++total_origins;
742 729
743 return total_origins; 730 return total_origins;
744 } 731 }
745 732
746 void SiteEngagementService::GetCountsForOriginsComplete( 733 void SiteEngagementService::GetCountsAndLastVisitForOriginsComplete(
734 history::HistoryService* history_service,
747 const std::multiset<GURL>& deleted_origins, 735 const std::multiset<GURL>& deleted_origins,
748 bool expired, 736 bool expired,
749 const history::OriginCountMap& remaining_origins) { 737 const history::OriginCountAndLastVisitMap& remaining_origins) {
738
739 // The most in-the-past option in the Clear Browsing Dialog aside from "all
740 // time" is 4 weeks ago. Set the last updated date to 4 weeks ago for origins
741 // where we can't find a valid last visit date.
742 base::Time now = clock_->Now();
743 base::Time four_weeks_ago =
744 now - base::TimeDelta::FromDays(FOUR_WEEKS_IN_DAYS);
745
750 for (const auto& origin_to_count : remaining_origins) { 746 for (const auto& origin_to_count : remaining_origins) {
751 GURL origin = origin_to_count.first; 747 GURL origin = origin_to_count.first;
752 int remaining = origin_to_count.second; 748 int remaining = origin_to_count.second.first;
749 base::Time last_visit = origin_to_count.second.second;
753 int deleted = deleted_origins.count(origin); 750 int deleted = deleted_origins.count(origin);
754 751
755 // Do not update engagement scores if the deletion was an expiry, but the 752 // Do not update engagement scores if the deletion was an expiry, but the
756 // URL still has entries in history. 753 // URL still has entries in history.
757 if ((expired && remaining != 0) || deleted == 0) 754 if ((expired && remaining != 0) || deleted == 0)
758 continue; 755 continue;
759 756
760 // Remove engagement proportional to the urls expired from the origin's 757 // Remove engagement proportional to the urls expired from the origin's
761 // entire history. 758 // entire history.
762 double proportion_remaining = 759 double proportion_remaining =
763 static_cast<double>(remaining) / (remaining + deleted); 760 static_cast<double>(remaining) / (remaining + deleted);
764 ResetScoreForURL(origin, proportion_remaining * GetScore(origin)); 761 if (last_visit.is_null() || last_visit > now)
762 last_visit = four_weeks_ago;
763
764 // At this point, we are going to proportionally decay the origin's
765 // engagement, and reset its last visit date to the last visit to a URL
766 // under the origin in history. If this new last visit date is long enough
767 // in the past, the next time the origin's engagement is accessed the
768 // automatic decay will kick in - i.e. a double decay will have occurred.
769 // To prevent this, compute the decay that would have taken place since the
770 // new last visit and add it to the engagement at this point. When the
771 // engagement is next accessed, it will decay back to the proportionally
772 // reduced value rather than being decayed once here, and then once again
773 // when it is next accessed.
774 int undecay = 0;
775 int days_since_engagement = (now - last_visit).InDays();
776 if (days_since_engagement > 0) {
777 int periods = days_since_engagement /
778 SiteEngagementScore::GetDecayPeriodInDays();
779 undecay = periods * SiteEngagementScore::GetDecayPoints();
780 }
781
782 double score =
783 std::min(SiteEngagementScore::kMaxPoints,
784 (proportion_remaining * GetScore(origin)) + undecay);
785 ResetScoreAndAccessTimesForURL(origin, score, &last_visit);
765 } 786 }
766 } 787 }
788
789 void SiteEngagementService::ResetScoreAndAccessTimesForURL(
790 const GURL& url, double score, const base::Time* updated_time) {
791 DCHECK(url.is_valid());
792 DCHECK_GE(score, 0);
793 DCHECK_LE(score, SiteEngagementScore::kMaxPoints);
794
795 HostContentSettingsMap* settings_map =
796 HostContentSettingsMapFactory::GetForProfile(profile_);
797 scoped_ptr<base::DictionaryValue> score_dict =
798 GetScoreDictForOrigin(settings_map, url);
799 SiteEngagementScore engagement_score(clock_.get(), *score_dict);
800
801 engagement_score.Reset(score, updated_time);
802 if (score == 0) {
803 settings_map->SetWebsiteSettingDefaultScope(
804 url, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
805 nullptr);
806 return;
807 }
808
809 if (engagement_score.UpdateScoreDict(score_dict.get())) {
810 settings_map->SetWebsiteSettingDefaultScope(
811 url, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
812 score_dict.release());
813 }
814 }
OLDNEW
« no previous file with comments | « chrome/browser/engagement/site_engagement_service.h ('k') | chrome/browser/engagement/site_engagement_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698