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

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: Rebase 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[] = "SiteEngagement";
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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 return make_scoped_ptr(new base::DictionaryValue()); 94 return make_scoped_ptr(new base::DictionaryValue());
82 95
83 if (!value->IsType(base::Value::TYPE_DICTIONARY)) 96 if (!value->IsType(base::Value::TYPE_DICTIONARY))
84 return make_scoped_ptr(new base::DictionaryValue()); 97 return make_scoped_ptr(new base::DictionaryValue());
85 98
86 return make_scoped_ptr(static_cast<base::DictionaryValue*>(value.release())); 99 return make_scoped_ptr(static_cast<base::DictionaryValue*>(value.release()));
87 } 100 }
88 101
89 } // namespace 102 } // namespace
90 103
104 const double SiteEngagementScore::kMaxPoints = 100;
105 double SiteEngagementScore::g_max_points_per_day = 5;
106 double SiteEngagementScore::g_navigation_points = 0.5;
107 double SiteEngagementScore::g_user_input_points = 0.05;
108 int SiteEngagementScore::g_decay_period_in_days = 7;
109 double SiteEngagementScore::g_decay_points = 5;
110
91 const char* SiteEngagementScore::kRawScoreKey = "rawScore"; 111 const char* SiteEngagementScore::kRawScoreKey = "rawScore";
92 const char* SiteEngagementScore::kPointsAddedTodayKey = "pointsAddedToday"; 112 const char* SiteEngagementScore::kPointsAddedTodayKey = "pointsAddedToday";
93 const char* SiteEngagementScore::kLastEngagementTimeKey = "lastEngagementTime"; 113 const char* SiteEngagementScore::kLastEngagementTimeKey = "lastEngagementTime";
94 114
95 const double SiteEngagementScore::kMaxPoints = 100; 115 void SiteEngagementScore::UpdateFromVariations() {
96 const double SiteEngagementScore::kMaxPointsPerDay = 5; 116 std::string max_points_per_day_param = variations::GetVariationParamValue(
97 const double SiteEngagementScore::kNavigationPoints = 0.5; 117 kEngagementParams, kMaxPointsPerDayParam);
98 const double SiteEngagementScore::kUserInputPoints = 0.05; 118 std::string navigation_points_param = variations::GetVariationParamValue(
99 const int SiteEngagementScore::kDecayPeriodInDays = 7; 119 kEngagementParams, kNavigationPointsParam);
100 const double SiteEngagementScore::kDecayPoints = 5; 120 std::string user_input_points_param = variations::GetVariationParamValue(
121 kEngagementParams, kUserInputPointsParam);
122 std::string decay_period_in_days_param = variations::GetVariationParamValue(
123 kEngagementParams, kDecayPeriodInDaysParam);
124 std::string decay_points_param = variations::GetVariationParamValue(
125 kEngagementParams, kDecayPointsParam);
126
127 if (!max_points_per_day_param.empty() && !navigation_points_param.empty() &&
128 !user_input_points_param.empty() && !decay_period_in_days_param.empty() &&
129 !decay_points_param.empty()) {
130 double max_points_per_day = 0;
131 double navigation_points = 0;
132 double user_input_points = 0;
133 int decay_period_in_days = 0;
134 double decay_points = 0;
135
136 if (base::StringToDouble(max_points_per_day_param, &max_points_per_day) &&
137 base::StringToDouble(navigation_points_param, &navigation_points) &&
138 base::StringToDouble(user_input_points_param, &user_input_points) &&
139 base::StringToInt(decay_period_in_days_param, &decay_period_in_days) &&
140 base::StringToDouble(decay_points_param, &decay_points) &&
141 max_points_per_day >= navigation_points &&
142 max_points_per_day >= user_input_points && navigation_points >= 0 &&
143 user_input_points >= 0 && decay_period_in_days > 0 &&
144 decay_points >= 0) {
145 g_max_points_per_day = max_points_per_day;
146 g_navigation_points = navigation_points;
147 g_user_input_points = user_input_points;
148 g_decay_period_in_days = decay_period_in_days;
149 g_decay_points = decay_points;
150 }
151 }
152 }
101 153
102 SiteEngagementScore::SiteEngagementScore( 154 SiteEngagementScore::SiteEngagementScore(
103 base::Clock* clock, 155 base::Clock* clock,
104 const base::DictionaryValue& score_dict) 156 const base::DictionaryValue& score_dict)
105 : SiteEngagementScore(clock) { 157 : SiteEngagementScore(clock) {
106 score_dict.GetDouble(kRawScoreKey, &raw_score_); 158 score_dict.GetDouble(kRawScoreKey, &raw_score_);
107 score_dict.GetDouble(kPointsAddedTodayKey, &points_added_today_); 159 score_dict.GetDouble(kPointsAddedTodayKey, &points_added_today_);
108 double internal_time; 160 double internal_time;
109 if (score_dict.GetDouble(kLastEngagementTimeKey, &internal_time)) 161 if (score_dict.GetDouble(kLastEngagementTimeKey, &internal_time))
110 last_engagement_time_ = base::Time::FromInternalValue(internal_time); 162 last_engagement_time_ = base::Time::FromInternalValue(internal_time);
(...skipping 10 matching lines...) Expand all
121 // As the score is about to be updated, commit any decay that has happened 173 // As the score is about to be updated, commit any decay that has happened
122 // since the last update. 174 // since the last update.
123 raw_score_ = DecayedScore(); 175 raw_score_ = DecayedScore();
124 176
125 base::Time now = clock_->Now(); 177 base::Time now = clock_->Now();
126 if (!last_engagement_time_.is_null() && 178 if (!last_engagement_time_.is_null() &&
127 now.LocalMidnight() != last_engagement_time_.LocalMidnight()) { 179 now.LocalMidnight() != last_engagement_time_.LocalMidnight()) {
128 points_added_today_ = 0; 180 points_added_today_ = 0;
129 } 181 }
130 182
131 double to_add = 183 double to_add = std::min(kMaxPoints - raw_score_,
132 std::min(kMaxPoints - raw_score_, kMaxPointsPerDay - points_added_today_); 184 g_max_points_per_day - points_added_today_);
133 to_add = std::min(to_add, points); 185 to_add = std::min(to_add, points);
134 186
135 points_added_today_ += to_add; 187 points_added_today_ += to_add;
136 raw_score_ += to_add; 188 raw_score_ += to_add;
137 189
138 last_engagement_time_ = now; 190 last_engagement_time_ = now;
139 } 191 }
140 192
141 bool SiteEngagementScore::MaxPointsPerDayAdded() { 193 bool SiteEngagementScore::MaxPointsPerDayAdded() {
142 if (!last_engagement_time_.is_null() && 194 if (!last_engagement_time_.is_null() &&
143 clock_->Now().LocalMidnight() != last_engagement_time_.LocalMidnight()) { 195 clock_->Now().LocalMidnight() != last_engagement_time_.LocalMidnight()) {
144 return false; 196 return false;
145 } 197 }
146 198
147 return points_added_today_ == kMaxPointsPerDay; 199 return points_added_today_ == g_max_points_per_day;
148 } 200 }
149 201
150 bool SiteEngagementScore::UpdateScoreDict(base::DictionaryValue* score_dict) { 202 bool SiteEngagementScore::UpdateScoreDict(base::DictionaryValue* score_dict) {
151 double raw_score_orig = 0; 203 double raw_score_orig = 0;
152 double points_added_today_orig = 0; 204 double points_added_today_orig = 0;
153 double last_engagement_time_internal_orig = 0; 205 double last_engagement_time_internal_orig = 0;
154 206
155 score_dict->GetDouble(kRawScoreKey, &raw_score_orig); 207 score_dict->GetDouble(kRawScoreKey, &raw_score_orig);
156 score_dict->GetDouble(kPointsAddedTodayKey, &points_added_today_orig); 208 score_dict->GetDouble(kPointsAddedTodayKey, &points_added_today_orig);
157 score_dict->GetDouble(kLastEngagementTimeKey, 209 score_dict->GetDouble(kLastEngagementTimeKey,
(...skipping 25 matching lines...) Expand all
183 235
184 double SiteEngagementScore::DecayedScore() const { 236 double SiteEngagementScore::DecayedScore() const {
185 // Note that users can change their clock, so from this system's perspective 237 // Note that users can change their clock, so from this system's perspective
186 // time can go backwards. If that does happen and the system detects that the 238 // time can go backwards. If that does happen and the system detects that the
187 // current day is earlier than the last engagement, no decay (or growth) is 239 // current day is earlier than the last engagement, no decay (or growth) is
188 // applied. 240 // applied.
189 int days_since_engagement = (clock_->Now() - last_engagement_time_).InDays(); 241 int days_since_engagement = (clock_->Now() - last_engagement_time_).InDays();
190 if (days_since_engagement < 0) 242 if (days_since_engagement < 0)
191 return raw_score_; 243 return raw_score_;
192 244
193 int periods = days_since_engagement / kDecayPeriodInDays; 245 int periods = days_since_engagement / g_decay_period_in_days;
194 double decayed_score = raw_score_ - periods * kDecayPoints; 246 double decayed_score = raw_score_ - periods * g_decay_points;
195 return std::max(0.0, decayed_score); 247 return std::max(0.0, decayed_score);
196 } 248 }
197 249
198 // static 250 // static
199 SiteEngagementService* SiteEngagementService::Get(Profile* profile) { 251 SiteEngagementService* SiteEngagementService::Get(Profile* profile) {
200 return SiteEngagementServiceFactory::GetForProfile(profile); 252 return SiteEngagementServiceFactory::GetForProfile(profile);
201 } 253 }
202 254
203 // static 255 // static
204 bool SiteEngagementService::IsEnabled() { 256 bool SiteEngagementService::IsEnabled() {
205 return base::CommandLine::ForCurrentProcess()->HasSwitch( 257 return base::CommandLine::ForCurrentProcess()->HasSwitch(
206 switches::kEnableSiteEngagementService); 258 switches::kEnableSiteEngagementService);
207 } 259 }
208 260
209 SiteEngagementService::SiteEngagementService(Profile* profile) 261 SiteEngagementService::SiteEngagementService(Profile* profile)
210 : SiteEngagementService(profile, make_scoped_ptr(new base::DefaultClock)) { 262 : SiteEngagementService(profile, make_scoped_ptr(new base::DefaultClock)) {
211 content::BrowserThread::PostAfterStartupTask( 263 content::BrowserThread::PostAfterStartupTask(
212 FROM_HERE, content::BrowserThread::GetMessageLoopProxyForThread( 264 FROM_HERE, content::BrowserThread::GetMessageLoopProxyForThread(
213 content::BrowserThread::UI), 265 content::BrowserThread::UI),
214 base::Bind(&SiteEngagementService::AfterStartupTask, 266 base::Bind(&SiteEngagementService::AfterStartupTask,
215 weak_factory_.GetWeakPtr())); 267 weak_factory_.GetWeakPtr()));
268
269 if (!gUpdatedFromVariations) {
calamity 2015/10/07 00:27:23 nit: One more here.
dominickn 2015/10/07 01:40:12 Done.
270 SiteEngagementScore::UpdateFromVariations();
271 gUpdatedFromVariations = true;
272 }
216 } 273 }
217 274
218 SiteEngagementService::~SiteEngagementService() { 275 SiteEngagementService::~SiteEngagementService() {
219 } 276 }
220 277
221 void SiteEngagementService::HandleNavigation(const GURL& url, 278 void SiteEngagementService::HandleNavigation(const GURL& url,
222 ui::PageTransition transition) { 279 ui::PageTransition transition) {
223 if (IsEngagementNavigation(transition)) { 280 if (IsEngagementNavigation(transition)) {
224 SiteEngagementMetrics::RecordEngagement( 281 SiteEngagementMetrics::RecordEngagement(
225 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION); 282 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION);
226 AddPoints(url, SiteEngagementScore::kNavigationPoints); 283 AddPoints(url, SiteEngagementScore::g_navigation_points);
227 RecordMetrics(); 284 RecordMetrics();
228 } 285 }
229 } 286 }
230 287
231 void SiteEngagementService::HandleUserInput( 288 void SiteEngagementService::HandleUserInput(
232 const GURL& url, 289 const GURL& url,
233 SiteEngagementMetrics::EngagementType type) { 290 SiteEngagementMetrics::EngagementType type) {
234 SiteEngagementMetrics::RecordEngagement(type); 291 SiteEngagementMetrics::RecordEngagement(type);
235 AddPoints(url, SiteEngagementScore::kUserInputPoints); 292 AddPoints(url, SiteEngagementScore::g_user_input_points);
236 RecordMetrics(); 293 RecordMetrics();
237 } 294 }
238 295
239 double SiteEngagementService::GetScore(const GURL& url) { 296 double SiteEngagementService::GetScore(const GURL& url) {
240 HostContentSettingsMap* settings_map = 297 HostContentSettingsMap* settings_map =
241 HostContentSettingsMapFactory::GetForProfile(profile_); 298 HostContentSettingsMapFactory::GetForProfile(profile_);
242 scoped_ptr<base::DictionaryValue> score_dict = 299 scoped_ptr<base::DictionaryValue> score_dict =
243 GetScoreDictForOrigin(settings_map, url); 300 GetScoreDictForOrigin(settings_map, url);
244 SiteEngagementScore score(clock_.get(), *score_dict); 301 SiteEngagementScore score(clock_.get(), *score_dict);
245 302
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 int SiteEngagementService::OriginsWithMaxEngagement( 466 int SiteEngagementService::OriginsWithMaxEngagement(
410 std::map<GURL, double>& score_map) { 467 std::map<GURL, double>& score_map) {
411 int total_origins = 0; 468 int total_origins = 0;
412 469
413 for (const auto& value : score_map) 470 for (const auto& value : score_map)
414 if (value.second == SiteEngagementScore::kMaxPoints) 471 if (value.second == SiteEngagementScore::kMaxPoints)
415 ++total_origins; 472 ++total_origins;
416 473
417 return total_origins; 474 return total_origins;
418 } 475 }
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