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 "chrome/browser/engagement/site_engagement_score.h" | 5 #include "chrome/browser/engagement/site_engagement_score.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/time/clock.h" | 12 #include "base/time/clock.h" |
| 13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 15 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 16 #include "chrome/browser/engagement/site_engagement_metrics.h" | 16 #include "chrome/browser/engagement/site_engagement_metrics.h" |
| 17 #include "chrome/browser/permissions/permission_manager.h" | |
|
benwells
2017/03/08 04:19:32
is this include used?
dominickn
2017/03/08 04:44:52
It was, but that was unfeasible. Removed!
| |
| 17 #include "components/content_settings/core/browser/host_content_settings_map.h" | 18 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 19 #include "components/content_settings/core/common/content_settings.h" | |
| 20 #include "components/content_settings/core/common/content_settings_types.h" | |
| 18 #include "components/variations/variations_associated_data.h" | 21 #include "components/variations/variations_associated_data.h" |
| 19 | 22 |
| 20 namespace { | 23 namespace { |
| 21 | 24 |
| 22 // Delta within which to consider scores equal. | 25 // Delta within which to consider scores equal. |
| 23 const double kScoreDelta = 0.001; | 26 const double kScoreDelta = 0.001; |
| 24 | 27 |
| 25 // Delta within which to consider internal time values equal. Internal time | 28 // Delta within which to consider internal time values equal. Internal time |
| 26 // values are in microseconds, so this delta comes out at one second. | 29 // values are in microseconds, so this delta comes out at one second. |
| 27 const double kTimeDelta = 1000000; | 30 const double kTimeDelta = 1000000; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 param_values[VISIBLE_MEDIA_POINTS] = {"visible_media_playing_points", 0.06}; | 84 param_values[VISIBLE_MEDIA_POINTS] = {"visible_media_playing_points", 0.06}; |
| 82 param_values[HIDDEN_MEDIA_POINTS] = {"hidden_media_playing_points", 0.01}; | 85 param_values[HIDDEN_MEDIA_POINTS] = {"hidden_media_playing_points", 0.01}; |
| 83 param_values[WEB_APP_INSTALLED_POINTS] = {"web_app_installed_points", 5}; | 86 param_values[WEB_APP_INSTALLED_POINTS] = {"web_app_installed_points", 5}; |
| 84 param_values[FIRST_DAILY_ENGAGEMENT] = {"first_daily_engagement_points", 1.5}; | 87 param_values[FIRST_DAILY_ENGAGEMENT] = {"first_daily_engagement_points", 1.5}; |
| 85 param_values[BOOTSTRAP_POINTS] = {"bootstrap_points", 24}; | 88 param_values[BOOTSTRAP_POINTS] = {"bootstrap_points", 24}; |
| 86 param_values[MEDIUM_ENGAGEMENT_BOUNDARY] = {"medium_engagement_boundary", 15}; | 89 param_values[MEDIUM_ENGAGEMENT_BOUNDARY] = {"medium_engagement_boundary", 15}; |
| 87 param_values[HIGH_ENGAGEMENT_BOUNDARY] = {"high_engagement_boundary", 50}; | 90 param_values[HIGH_ENGAGEMENT_BOUNDARY] = {"high_engagement_boundary", 50}; |
| 88 param_values[MAX_DECAYS_PER_SCORE] = {"max_decays_per_score", 4}; | 91 param_values[MAX_DECAYS_PER_SCORE] = {"max_decays_per_score", 4}; |
| 89 param_values[LAST_ENGAGEMENT_GRACE_PERIOD_IN_HOURS] = { | 92 param_values[LAST_ENGAGEMENT_GRACE_PERIOD_IN_HOURS] = { |
| 90 "last_engagement_grace_period_in_hours", 1}; | 93 "last_engagement_grace_period_in_hours", 1}; |
| 94 param_values[NOTIFICATION_PERMISSION_POINTS] = { | |
| 95 "notification_permission_points", 5}; | |
| 91 return param_values; | 96 return param_values; |
| 92 } | 97 } |
| 93 | 98 |
| 94 double SiteEngagementScore::GetMaxPointsPerDay() { | 99 double SiteEngagementScore::GetMaxPointsPerDay() { |
| 95 return GetParamValues()[MAX_POINTS_PER_DAY].second; | 100 return GetParamValues()[MAX_POINTS_PER_DAY].second; |
| 96 } | 101 } |
| 97 | 102 |
| 98 double SiteEngagementScore::GetDecayPeriodInHours() { | 103 double SiteEngagementScore::GetDecayPeriodInHours() { |
| 99 return GetParamValues()[DECAY_PERIOD_IN_HOURS].second; | 104 return GetParamValues()[DECAY_PERIOD_IN_HOURS].second; |
| 100 } | 105 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 } | 153 } |
| 149 | 154 |
| 150 double SiteEngagementScore::GetMaxDecaysPerScore() { | 155 double SiteEngagementScore::GetMaxDecaysPerScore() { |
| 151 return GetParamValues()[MAX_DECAYS_PER_SCORE].second; | 156 return GetParamValues()[MAX_DECAYS_PER_SCORE].second; |
| 152 } | 157 } |
| 153 | 158 |
| 154 double SiteEngagementScore::GetLastEngagementGracePeriodInHours() { | 159 double SiteEngagementScore::GetLastEngagementGracePeriodInHours() { |
| 155 return GetParamValues()[LAST_ENGAGEMENT_GRACE_PERIOD_IN_HOURS].second; | 160 return GetParamValues()[LAST_ENGAGEMENT_GRACE_PERIOD_IN_HOURS].second; |
| 156 } | 161 } |
| 157 | 162 |
| 163 double SiteEngagementScore::GetNotificationPermissionPoints() { | |
| 164 return GetParamValues()[NOTIFICATION_PERMISSION_POINTS].second; | |
| 165 } | |
| 166 | |
| 158 // static | 167 // static |
| 159 void SiteEngagementScore::UpdateFromVariations(const char* param_name) { | 168 void SiteEngagementScore::UpdateFromVariations(const char* param_name) { |
| 160 double param_vals[MAX_VARIATION]; | 169 double param_vals[MAX_VARIATION]; |
| 161 | 170 |
| 162 for (int i = 0; i < MAX_VARIATION; ++i) { | 171 for (int i = 0; i < MAX_VARIATION; ++i) { |
| 163 std::string param_string = variations::GetVariationParamValue( | 172 std::string param_string = variations::GetVariationParamValue( |
| 164 param_name, GetParamValues()[i].first); | 173 param_name, GetParamValues()[i].first); |
| 165 | 174 |
| 166 // Bail out if we didn't get a param string for the key, or if we couldn't | 175 // Bail out if we didn't get a param string for the key, or if we couldn't |
| 167 // convert the param string to a double, or if we get a negative value. | 176 // convert the param string to a double, or if we get a negative value. |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 SiteEngagementScore::SiteEngagementScore( | 335 SiteEngagementScore::SiteEngagementScore( |
| 327 base::Clock* clock, | 336 base::Clock* clock, |
| 328 const GURL& origin, | 337 const GURL& origin, |
| 329 std::unique_ptr<base::DictionaryValue> score_dict) | 338 std::unique_ptr<base::DictionaryValue> score_dict) |
| 330 : clock_(clock), | 339 : clock_(clock), |
| 331 raw_score_(0), | 340 raw_score_(0), |
| 332 points_added_today_(0), | 341 points_added_today_(0), |
| 333 last_engagement_time_(), | 342 last_engagement_time_(), |
| 334 last_shortcut_launch_time_(), | 343 last_shortcut_launch_time_(), |
| 335 score_dict_(score_dict.release()), | 344 score_dict_(score_dict.release()), |
| 336 origin_(origin) { | 345 origin_(origin), |
| 346 settings_map_(nullptr) { | |
| 337 if (!score_dict_) | 347 if (!score_dict_) |
| 338 return; | 348 return; |
| 339 | 349 |
| 340 score_dict_->GetDouble(kRawScoreKey, &raw_score_); | 350 score_dict_->GetDouble(kRawScoreKey, &raw_score_); |
| 341 score_dict_->GetDouble(kPointsAddedTodayKey, &points_added_today_); | 351 score_dict_->GetDouble(kPointsAddedTodayKey, &points_added_today_); |
| 342 | 352 |
| 343 double internal_time; | 353 double internal_time; |
| 344 if (score_dict_->GetDouble(kLastEngagementTimeKey, &internal_time)) | 354 if (score_dict_->GetDouble(kLastEngagementTimeKey, &internal_time)) |
| 345 last_engagement_time_ = base::Time::FromInternalValue(internal_time); | 355 last_engagement_time_ = base::Time::FromInternalValue(internal_time); |
| 346 if (score_dict_->GetDouble(kLastShortcutLaunchTimeKey, &internal_time)) | 356 if (score_dict_->GetDouble(kLastShortcutLaunchTimeKey, &internal_time)) |
| 347 last_shortcut_launch_time_ = base::Time::FromInternalValue(internal_time); | 357 last_shortcut_launch_time_ = base::Time::FromInternalValue(internal_time); |
| 348 } | 358 } |
| 349 | 359 |
| 350 double SiteEngagementScore::DecayedScore() const { | 360 double SiteEngagementScore::DecayedScore() const { |
| 351 // Note that users can change their clock, so from this system's perspective | 361 // Note that users can change their clock, so from this system's perspective |
| 352 // time can go backwards. If that does happen and the system detects that the | 362 // time can go backwards. If that does happen and the system detects that the |
| 353 // current day is earlier than the last engagement, no decay (or growth) is | 363 // current day is earlier than the last engagement, no decay (or growth) is |
| 354 // applied. | 364 // applied. |
| 355 int hours_since_engagement = | 365 int hours_since_engagement = |
| 356 (clock_->Now() - last_engagement_time_).InHours(); | 366 (clock_->Now() - last_engagement_time_).InHours(); |
| 357 if (hours_since_engagement < 0) | 367 if (hours_since_engagement < 0) |
| 358 return raw_score_; | 368 return raw_score_; |
| 359 | 369 |
| 360 int periods = hours_since_engagement / GetDecayPeriodInHours(); | 370 int periods = hours_since_engagement / GetDecayPeriodInHours(); |
| 361 return std::max(0.0, raw_score_ * pow(GetDecayProportion(), periods) - | 371 return std::max(0.0, raw_score_ * pow(GetDecayProportion(), periods) - |
| 362 periods * GetDecayPoints()); | 372 periods * GetDecayPoints()); |
| 363 } | 373 } |
| 364 | 374 |
| 365 double SiteEngagementScore::BonusScore() const { | 375 double SiteEngagementScore::BonusScore() const { |
| 376 double bonus = 0; | |
| 366 int days_since_shortcut_launch = | 377 int days_since_shortcut_launch = |
| 367 (clock_->Now() - last_shortcut_launch_time_).InDays(); | 378 (clock_->Now() - last_shortcut_launch_time_).InDays(); |
| 368 if (days_since_shortcut_launch <= kMaxDaysSinceShortcutLaunch) | 379 if (days_since_shortcut_launch <= kMaxDaysSinceShortcutLaunch) |
| 369 return GetWebAppInstalledPoints(); | 380 bonus += GetWebAppInstalledPoints(); |
| 370 | 381 |
| 371 return 0; | 382 // TODO(dominickn, raymes): call PermissionManager::GetPermissionStatus when |
| 383 // the PermissionManager is thread-safe. | |
| 384 if (settings_map_ && | |
| 385 settings_map_->GetContentSetting( | |
| 386 origin_, origin_, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, | |
| 387 std::string()) == CONTENT_SETTING_ALLOW) { | |
| 388 bonus += GetNotificationPermissionPoints(); | |
| 389 } | |
| 390 | |
| 391 return bonus; | |
| 372 } | 392 } |
| 373 | 393 |
| 374 void SiteEngagementScore::SetParamValuesForTesting() { | 394 void SiteEngagementScore::SetParamValuesForTesting() { |
| 375 GetParamValues()[MAX_POINTS_PER_DAY].second = 5; | 395 GetParamValues()[MAX_POINTS_PER_DAY].second = 5; |
| 376 GetParamValues()[DECAY_PERIOD_IN_HOURS].second = 7 * 24; | 396 GetParamValues()[DECAY_PERIOD_IN_HOURS].second = 7 * 24; |
| 377 GetParamValues()[DECAY_POINTS].second = 5; | 397 GetParamValues()[DECAY_POINTS].second = 5; |
| 378 GetParamValues()[NAVIGATION_POINTS].second = 0.5; | 398 GetParamValues()[NAVIGATION_POINTS].second = 0.5; |
| 379 GetParamValues()[USER_INPUT_POINTS].second = 0.05; | 399 GetParamValues()[USER_INPUT_POINTS].second = 0.05; |
| 380 GetParamValues()[VISIBLE_MEDIA_POINTS].second = 0.02; | 400 GetParamValues()[VISIBLE_MEDIA_POINTS].second = 0.02; |
| 381 GetParamValues()[HIDDEN_MEDIA_POINTS].second = 0.01; | 401 GetParamValues()[HIDDEN_MEDIA_POINTS].second = 0.01; |
| 382 GetParamValues()[WEB_APP_INSTALLED_POINTS].second = 5; | 402 GetParamValues()[WEB_APP_INSTALLED_POINTS].second = 5; |
| 383 GetParamValues()[BOOTSTRAP_POINTS].second = 8; | 403 GetParamValues()[BOOTSTRAP_POINTS].second = 8; |
| 384 GetParamValues()[MEDIUM_ENGAGEMENT_BOUNDARY].second = 5; | 404 GetParamValues()[MEDIUM_ENGAGEMENT_BOUNDARY].second = 5; |
| 385 GetParamValues()[HIGH_ENGAGEMENT_BOUNDARY].second = 50; | 405 GetParamValues()[HIGH_ENGAGEMENT_BOUNDARY].second = 50; |
| 386 GetParamValues()[MAX_DECAYS_PER_SCORE].second = 1; | 406 GetParamValues()[MAX_DECAYS_PER_SCORE].second = 1; |
| 387 GetParamValues()[LAST_ENGAGEMENT_GRACE_PERIOD_IN_HOURS].second = 72; | 407 GetParamValues()[LAST_ENGAGEMENT_GRACE_PERIOD_IN_HOURS].second = 72; |
| 408 GetParamValues()[NOTIFICATION_PERMISSION_POINTS].second = 5; | |
| 388 | 409 |
| 389 // This is set to values that avoid interference with tests and are set when | 410 // This is set to values that avoid interference with tests and are set when |
| 390 // testing these features. | 411 // testing these features. |
| 391 GetParamValues()[FIRST_DAILY_ENGAGEMENT].second = 0; | 412 GetParamValues()[FIRST_DAILY_ENGAGEMENT].second = 0; |
| 392 GetParamValues()[DECAY_PROPORTION].second = 1; | 413 GetParamValues()[DECAY_PROPORTION].second = 1; |
| 393 GetParamValues()[SCORE_CLEANUP_THRESHOLD].second = 0; | 414 GetParamValues()[SCORE_CLEANUP_THRESHOLD].second = 0; |
| 394 } | 415 } |
| OLD | NEW |