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

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

Issue 1373453002: Allow the site engagement service thresholds to be varied via field trial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@time-on-site-uma
Patch Set: Addressing reviewer feedback Created 5 years, 2 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 <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/strings/string_number_conversions.h"
12 #include "base/time/clock.h" 13 #include "base/time/clock.h"
13 #include "base/time/default_clock.h" 14 #include "base/time/default_clock.h"
14 #include "base/values.h" 15 #include "base/values.h"
15 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 16 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
16 #include "chrome/browser/engagement/site_engagement_helper.h" 17 #include "chrome/browser/engagement/site_engagement_helper.h"
17 #include "chrome/browser/engagement/site_engagement_service_factory.h" 18 #include "chrome/browser/engagement/site_engagement_service_factory.h"
18 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
19 #include "components/content_settings/core/browser/host_content_settings_map.h" 20 #include "components/content_settings/core/browser/host_content_settings_map.h"
20 #include "components/content_settings/core/common/content_settings_pattern.h" 21 #include "components/content_settings/core/common/content_settings_pattern.h"
22 #include "components/variations/variations_associated_data.h"
21 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
22 #include "url/gurl.h" 24 #include "url/gurl.h"
23 25
24 namespace { 26 namespace {
25 27
28 // Global bool to ensure we only update the parameters from variations once.
29 bool gUpdatedFromVariations = false;
30
31 // Keys used in the variations params.
32 const char kEngagementParams[] = "SiteEngagementParams";
benwells 2015/10/06 02:55:50 Nit: can we just call this SiteEngagement?
dominickn 2015/10/06 05:00:39 Done.
33 const char kMaxPointsPerDayParam[] = "max_points_per_day";
34 const char kNavigationPointsParam[] = "navigation_points";
35 const char kUserInputPointsParam[] = "user_input_points";
36 const char kDecayPeriodInDaysParam[] = "decay_period_in_days";
37 const char kDecayPointsParam[] = "decay_points";
38
26 // Length of time between metrics logging. 39 // Length of time between metrics logging.
27 const base::TimeDelta metrics_interval = base::TimeDelta::FromMinutes(60); 40 const base::TimeDelta metrics_interval = base::TimeDelta::FromMinutes(60);
28 41
29 // Delta within which to consider scores equal. 42 // Delta within which to consider scores equal.
30 const double kScoreDelta = 0.001; 43 const double kScoreDelta = 0.001;
31 44
32 // Delta within which to consider internal time values equal. Internal time 45 // Delta within which to consider internal time values equal. Internal time
33 // values are in microseconds, so this delta comes out at one second. 46 // values are in microseconds, so this delta comes out at one second.
34 const double kTimeDelta = 1000000; 47 const double kTimeDelta = 1000000;
35 48
(...skipping 24 matching lines...) Expand all
60 return make_scoped_ptr(new base::DictionaryValue()); 73 return make_scoped_ptr(new base::DictionaryValue());
61 74
62 if (!value->IsType(base::Value::TYPE_DICTIONARY)) 75 if (!value->IsType(base::Value::TYPE_DICTIONARY))
63 return make_scoped_ptr(new base::DictionaryValue()); 76 return make_scoped_ptr(new base::DictionaryValue());
64 77
65 return make_scoped_ptr(static_cast<base::DictionaryValue*>(value.release())); 78 return make_scoped_ptr(static_cast<base::DictionaryValue*>(value.release()));
66 } 79 }
67 80
68 } // namespace 81 } // namespace
69 82
83 const double SiteEngagementScore::kMaxPoints = 100;
84 double SiteEngagementScore::gMaxPointsPerDay = 5;
85 double SiteEngagementScore::gNavigationPoints = 0.5;
86 double SiteEngagementScore::gUserInputPoints = 0.05;
87 int SiteEngagementScore::gDecayPeriodInDays = 7;
88 double SiteEngagementScore::gDecayPoints = 5;
89
70 const char* SiteEngagementScore::kRawScoreKey = "rawScore"; 90 const char* SiteEngagementScore::kRawScoreKey = "rawScore";
71 const char* SiteEngagementScore::kPointsAddedTodayKey = "pointsAddedToday"; 91 const char* SiteEngagementScore::kPointsAddedTodayKey = "pointsAddedToday";
72 const char* SiteEngagementScore::kLastEngagementTimeKey = "lastEngagementTime"; 92 const char* SiteEngagementScore::kLastEngagementTimeKey = "lastEngagementTime";
73 93
74 const double SiteEngagementScore::kMaxPoints = 100; 94 void SiteEngagementScore::UpdateFromVariations() {
75 const double SiteEngagementScore::kMaxPointsPerDay = 5; 95 std::string max_points_per_day_param = variations::GetVariationParamValue(
76 const double SiteEngagementScore::kNavigationPoints = 0.5; 96 kEngagementParams, kMaxPointsPerDayParam);
77 const double SiteEngagementScore::kUserInputPoints = 0.05; 97 std::string navigation_points_param = variations::GetVariationParamValue(
78 const int SiteEngagementScore::kDecayPeriodInDays = 7; 98 kEngagementParams, kNavigationPointsParam);
79 const double SiteEngagementScore::kDecayPoints = 5; 99 std::string user_input_points_param = variations::GetVariationParamValue(
100 kEngagementParams, kUserInputPointsParam);
101 std::string decay_period_in_days_param = variations::GetVariationParamValue(
102 kEngagementParams, kDecayPeriodInDaysParam);
103 std::string decay_points_param = variations::GetVariationParamValue(
104 kEngagementParams, kDecayPointsParam);
105
106 if (!max_points_per_day_param.empty() && !navigation_points_param.empty() &&
107 !user_input_points_param.empty() && !decay_period_in_days_param.empty() &&
108 !decay_points_param.empty()) {
109 double max_points_per_day = 0;
110 double navigation_points = 0;
111 double user_input_points = 0;
112 int decay_period_in_days = 0;
113 double decay_points = 0;
114
115 if (base::StringToDouble(max_points_per_day_param, &max_points_per_day) &&
116 base::StringToDouble(navigation_points_param, &navigation_points) &&
117 base::StringToDouble(user_input_points_param, &user_input_points) &&
118 base::StringToInt(decay_period_in_days_param, &decay_period_in_days) &&
119 base::StringToDouble(decay_points_param, &decay_points) &&
120 max_points_per_day >= navigation_points &&
121 max_points_per_day >= user_input_points && navigation_points >= 0 &&
122 user_input_points >= 0 && decay_period_in_days > 0 &&
123 decay_points >= 0) {
124 gMaxPointsPerDay = max_points_per_day;
125 gNavigationPoints = navigation_points;
126 gUserInputPoints = user_input_points;
127 gDecayPeriodInDays = decay_period_in_days;
128 gDecayPoints = decay_points;
129 }
130 }
131 }
80 132
81 SiteEngagementScore::SiteEngagementScore( 133 SiteEngagementScore::SiteEngagementScore(
82 base::Clock* clock, 134 base::Clock* clock,
83 const base::DictionaryValue& score_dict) 135 const base::DictionaryValue& score_dict)
84 : SiteEngagementScore(clock) { 136 : SiteEngagementScore(clock) {
85 score_dict.GetDouble(kRawScoreKey, &raw_score_); 137 score_dict.GetDouble(kRawScoreKey, &raw_score_);
86 score_dict.GetDouble(kPointsAddedTodayKey, &points_added_today_); 138 score_dict.GetDouble(kPointsAddedTodayKey, &points_added_today_);
87 double internal_time; 139 double internal_time;
88 if (score_dict.GetDouble(kLastEngagementTimeKey, &internal_time)) 140 if (score_dict.GetDouble(kLastEngagementTimeKey, &internal_time))
89 last_engagement_time_ = base::Time::FromInternalValue(internal_time); 141 last_engagement_time_ = base::Time::FromInternalValue(internal_time);
(...skipping 11 matching lines...) Expand all
101 // since the last update. 153 // since the last update.
102 raw_score_ = DecayedScore(); 154 raw_score_ = DecayedScore();
103 155
104 base::Time now = clock_->Now(); 156 base::Time now = clock_->Now();
105 if (!last_engagement_time_.is_null() && 157 if (!last_engagement_time_.is_null() &&
106 now.LocalMidnight() != last_engagement_time_.LocalMidnight()) { 158 now.LocalMidnight() != last_engagement_time_.LocalMidnight()) {
107 points_added_today_ = 0; 159 points_added_today_ = 0;
108 } 160 }
109 161
110 double to_add = 162 double to_add =
111 std::min(kMaxPoints - raw_score_, kMaxPointsPerDay - points_added_today_); 163 std::min(kMaxPoints - raw_score_, gMaxPointsPerDay - points_added_today_);
112 to_add = std::min(to_add, points); 164 to_add = std::min(to_add, points);
113 165
114 points_added_today_ += to_add; 166 points_added_today_ += to_add;
115 raw_score_ += to_add; 167 raw_score_ += to_add;
116 168
117 last_engagement_time_ = now; 169 last_engagement_time_ = now;
118 } 170 }
119 171
120 bool SiteEngagementScore::MaxPointsPerDayAdded() { 172 bool SiteEngagementScore::MaxPointsPerDayAdded() {
121 if (!last_engagement_time_.is_null() && 173 if (!last_engagement_time_.is_null() &&
122 clock_->Now().LocalMidnight() != last_engagement_time_.LocalMidnight()) { 174 clock_->Now().LocalMidnight() != last_engagement_time_.LocalMidnight()) {
123 return false; 175 return false;
124 } 176 }
125 177
126 return points_added_today_ == kMaxPointsPerDay; 178 return points_added_today_ == gMaxPointsPerDay;
127 } 179 }
128 180
129 bool SiteEngagementScore::UpdateScoreDict(base::DictionaryValue* score_dict) { 181 bool SiteEngagementScore::UpdateScoreDict(base::DictionaryValue* score_dict) {
130 double raw_score_orig = 0; 182 double raw_score_orig = 0;
131 double points_added_today_orig = 0; 183 double points_added_today_orig = 0;
132 double last_engagement_time_internal_orig = 0; 184 double last_engagement_time_internal_orig = 0;
133 185
134 score_dict->GetDouble(kRawScoreKey, &raw_score_orig); 186 score_dict->GetDouble(kRawScoreKey, &raw_score_orig);
135 score_dict->GetDouble(kPointsAddedTodayKey, &points_added_today_orig); 187 score_dict->GetDouble(kPointsAddedTodayKey, &points_added_today_orig);
136 score_dict->GetDouble(kLastEngagementTimeKey, 188 score_dict->GetDouble(kLastEngagementTimeKey,
(...skipping 25 matching lines...) Expand all
162 214
163 double SiteEngagementScore::DecayedScore() const { 215 double SiteEngagementScore::DecayedScore() const {
164 // Note that users can change their clock, so from this system's perspective 216 // Note that users can change their clock, so from this system's perspective
165 // time can go backwards. If that does happen and the system detects that the 217 // time can go backwards. If that does happen and the system detects that the
166 // current day is earlier than the last engagement, no decay (or growth) is 218 // current day is earlier than the last engagement, no decay (or growth) is
167 // applied. 219 // applied.
168 int days_since_engagement = (clock_->Now() - last_engagement_time_).InDays(); 220 int days_since_engagement = (clock_->Now() - last_engagement_time_).InDays();
169 if (days_since_engagement < 0) 221 if (days_since_engagement < 0)
170 return raw_score_; 222 return raw_score_;
171 223
172 int periods = days_since_engagement / kDecayPeriodInDays; 224 int periods = days_since_engagement / gDecayPeriodInDays;
173 double decayed_score = raw_score_ - periods * kDecayPoints; 225 double decayed_score = raw_score_ - periods * gDecayPoints;
174 return std::max(0.0, decayed_score); 226 return std::max(0.0, decayed_score);
175 } 227 }
176 228
177 // static 229 // static
178 SiteEngagementService* SiteEngagementService::Get(Profile* profile) { 230 SiteEngagementService* SiteEngagementService::Get(Profile* profile) {
179 return SiteEngagementServiceFactory::GetForProfile(profile); 231 return SiteEngagementServiceFactory::GetForProfile(profile);
180 } 232 }
181 233
182 // static 234 // static
183 bool SiteEngagementService::IsEnabled() { 235 bool SiteEngagementService::IsEnabled() {
184 return base::CommandLine::ForCurrentProcess()->HasSwitch( 236 return base::CommandLine::ForCurrentProcess()->HasSwitch(
185 switches::kEnableSiteEngagementService); 237 switches::kEnableSiteEngagementService);
186 } 238 }
187 239
188 SiteEngagementService::SiteEngagementService(Profile* profile) 240 SiteEngagementService::SiteEngagementService(Profile* profile)
189 : SiteEngagementService(profile, make_scoped_ptr(new base::DefaultClock)) { 241 : SiteEngagementService(profile, make_scoped_ptr(new base::DefaultClock)) {
190 content::BrowserThread::PostAfterStartupTask( 242 content::BrowserThread::PostAfterStartupTask(
191 FROM_HERE, content::BrowserThread::GetMessageLoopProxyForThread( 243 FROM_HERE, content::BrowserThread::GetMessageLoopProxyForThread(
192 content::BrowserThread::UI), 244 content::BrowserThread::UI),
193 base::Bind(&SiteEngagementService::AfterStartupTask, 245 base::Bind(&SiteEngagementService::AfterStartupTask,
194 weak_factory_.GetWeakPtr())); 246 weak_factory_.GetWeakPtr()));
247
248 if (!gUpdatedFromVariations) {
249 SiteEngagementScore::UpdateFromVariations();
250 gUpdatedFromVariations = true;
251 }
195 } 252 }
196 253
197 SiteEngagementService::~SiteEngagementService() { 254 SiteEngagementService::~SiteEngagementService() {
198 } 255 }
199 256
200 void SiteEngagementService::HandleNavigation(const GURL& url, 257 void SiteEngagementService::HandleNavigation(const GURL& url,
201 ui::PageTransition transition) { 258 ui::PageTransition transition) {
202 SiteEngagementMetrics::RecordEngagement( 259 SiteEngagementMetrics::RecordEngagement(
203 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION); 260 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION);
204 AddPoints(url, SiteEngagementScore::kNavigationPoints); 261 AddPoints(url, SiteEngagementScore::gNavigationPoints);
205 RecordMetrics(); 262 RecordMetrics();
206 } 263 }
207 264
208 void SiteEngagementService::HandleUserInput( 265 void SiteEngagementService::HandleUserInput(
209 const GURL& url, 266 const GURL& url,
210 SiteEngagementMetrics::EngagementType type) { 267 SiteEngagementMetrics::EngagementType type) {
211 SiteEngagementMetrics::RecordEngagement(type); 268 SiteEngagementMetrics::RecordEngagement(type);
212 AddPoints(url, SiteEngagementScore::kUserInputPoints); 269 AddPoints(url, SiteEngagementScore::gUserInputPoints);
213 RecordMetrics(); 270 RecordMetrics();
214 } 271 }
215 272
216 double SiteEngagementService::GetScore(const GURL& url) { 273 double SiteEngagementService::GetScore(const GURL& url) {
217 HostContentSettingsMap* settings_map = 274 HostContentSettingsMap* settings_map =
218 HostContentSettingsMapFactory::GetForProfile(profile_); 275 HostContentSettingsMapFactory::GetForProfile(profile_);
219 scoped_ptr<base::DictionaryValue> score_dict = 276 scoped_ptr<base::DictionaryValue> score_dict =
220 GetScoreDictForOrigin(settings_map, url); 277 GetScoreDictForOrigin(settings_map, url);
221 SiteEngagementScore score(clock_.get(), *score_dict); 278 SiteEngagementScore score(clock_.get(), *score_dict);
222 279
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 int SiteEngagementService::OriginsWithMaxEngagement( 443 int SiteEngagementService::OriginsWithMaxEngagement(
387 std::map<GURL, double>& score_map) { 444 std::map<GURL, double>& score_map) {
388 int total_origins = 0; 445 int total_origins = 0;
389 446
390 for (const auto& value : score_map) 447 for (const auto& value : score_map)
391 if (value.second == SiteEngagementScore::kMaxPoints) 448 if (value.second == SiteEngagementScore::kMaxPoints)
392 ++total_origins; 449 ++total_origins;
393 450
394 return total_origins; 451 return total_origins;
395 } 452 }
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