| 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> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/metrics/field_trial.h" | 15 #include "base/metrics/field_trial.h" |
| 16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 17 #include "base/time/clock.h" | 17 #include "base/time/clock.h" |
| 18 #include "base/time/default_clock.h" | 18 #include "base/time/default_clock.h" |
| 19 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 20 #include "base/values.h" | 20 #include "base/values.h" |
| 21 #include "chrome/browser/banners/app_banner_settings_helper.h" | 21 #include "chrome/browser/banners/app_banner_settings_helper.h" |
| 22 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 22 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 23 #include "chrome/browser/engagement/site_engagement_eviction_policy.h" | 23 #include "chrome/browser/engagement/site_engagement_eviction_policy.h" |
| 24 #include "chrome/browser/engagement/site_engagement_helper.h" |
| 24 #include "chrome/browser/engagement/site_engagement_metrics.h" | 25 #include "chrome/browser/engagement/site_engagement_metrics.h" |
| 25 #include "chrome/browser/engagement/site_engagement_score.h" | 26 #include "chrome/browser/engagement/site_engagement_score.h" |
| 26 #include "chrome/browser/engagement/site_engagement_service_factory.h" | 27 #include "chrome/browser/engagement/site_engagement_service_factory.h" |
| 27 #include "chrome/browser/history/history_service_factory.h" | 28 #include "chrome/browser/history/history_service_factory.h" |
| 28 #include "chrome/browser/profiles/profile.h" | 29 #include "chrome/browser/profiles/profile.h" |
| 29 #include "chrome/common/chrome_switches.h" | 30 #include "chrome/common/chrome_switches.h" |
| 30 #include "chrome/common/pref_names.h" | 31 #include "chrome/common/pref_names.h" |
| 31 #include "components/content_settings/core/browser/host_content_settings_map.h" | 32 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 32 #include "components/content_settings/core/common/content_settings_pattern.h" | 33 #include "components/content_settings/core/common/content_settings_pattern.h" |
| 33 #include "components/history/core/browser/history_service.h" | 34 #include "components/history/core/browser/history_service.h" |
| 34 #include "components/prefs/pref_service.h" | 35 #include "components/prefs/pref_service.h" |
| 35 #include "content/public/browser/browser_thread.h" | 36 #include "content/public/browser/browser_thread.h" |
| 37 #include "content/public/browser/render_frame_host.h" |
| 36 #include "content/public/browser/web_contents.h" | 38 #include "content/public/browser/web_contents.h" |
| 39 #include "content/public/common/associated_interface_provider.h" |
| 37 #include "url/gurl.h" | 40 #include "url/gurl.h" |
| 38 | 41 |
| 39 namespace { | 42 namespace { |
| 40 | 43 |
| 41 const int FOUR_WEEKS_IN_DAYS = 28; | 44 const int FOUR_WEEKS_IN_DAYS = 28; |
| 42 | 45 |
| 43 // Global bool to ensure we only update the parameters from variations once. | 46 // Global bool to ensure we only update the parameters from variations once. |
| 44 bool g_updated_from_variations = false; | 47 bool g_updated_from_variations = false; |
| 45 | 48 |
| 46 // Length of time between metrics logging. | 49 // Length of time between metrics logging. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 } | 119 } |
| 117 } | 120 } |
| 118 | 121 |
| 119 SiteEngagementService::~SiteEngagementService() { | 122 SiteEngagementService::~SiteEngagementService() { |
| 120 history::HistoryService* history = HistoryServiceFactory::GetForProfile( | 123 history::HistoryService* history = HistoryServiceFactory::GetForProfile( |
| 121 profile_, ServiceAccessType::IMPLICIT_ACCESS); | 124 profile_, ServiceAccessType::IMPLICIT_ACCESS); |
| 122 if (history) | 125 if (history) |
| 123 history->RemoveObserver(this); | 126 history->RemoveObserver(this); |
| 124 } | 127 } |
| 125 | 128 |
| 126 SiteEngagementService::EngagementLevel | 129 blink::mojom::EngagementLevel |
| 127 SiteEngagementService::GetEngagementLevel(const GURL& url) const { | 130 SiteEngagementService::GetEngagementLevel(const GURL& url) const { |
| 128 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(), | 131 if (IsLastEngagementStale()) |
| 129 SiteEngagementScore::GetHighEngagementBoundary()); | 132 CleanupEngagementScores(true); |
| 130 double score = GetScore(url); | |
| 131 if (score == 0) | |
| 132 return ENGAGEMENT_LEVEL_NONE; | |
| 133 | 133 |
| 134 if (score < SiteEngagementScore::GetMediumEngagementBoundary()) | 134 return CreateEngagementScore(url).GetEngagementLevel(); |
| 135 return ENGAGEMENT_LEVEL_LOW; | |
| 136 | |
| 137 if (score < SiteEngagementScore::GetHighEngagementBoundary()) | |
| 138 return ENGAGEMENT_LEVEL_MEDIUM; | |
| 139 | |
| 140 if (score < SiteEngagementScore::kMaxPoints) | |
| 141 return ENGAGEMENT_LEVEL_HIGH; | |
| 142 | |
| 143 return ENGAGEMENT_LEVEL_MAX; | |
| 144 } | 135 } |
| 145 | 136 |
| 146 std::map<GURL, double> SiteEngagementService::GetScoreMap() const { | 137 std::map<GURL, double> SiteEngagementService::GetScoreMap() const { |
| 147 HostContentSettingsMap* settings_map = | 138 HostContentSettingsMap* settings_map = |
| 148 HostContentSettingsMapFactory::GetForProfile(profile_); | 139 HostContentSettingsMapFactory::GetForProfile(profile_); |
| 149 std::unique_ptr<ContentSettingsForOneType> engagement_settings = | 140 std::unique_ptr<ContentSettingsForOneType> engagement_settings = |
| 150 GetEngagementContentSettings(settings_map); | 141 GetEngagementContentSettings(settings_map); |
| 151 | 142 |
| 152 std::map<GURL, double> score_map; | 143 std::map<GURL, double> score_map; |
| 153 for (const auto& site : *engagement_settings) { | 144 for (const auto& site : *engagement_settings) { |
| 154 GURL origin(site.primary_pattern.ToString()); | 145 GURL origin(site.primary_pattern.ToString()); |
| 155 if (!origin.is_valid()) | 146 if (!origin.is_valid()) |
| 156 continue; | 147 continue; |
| 157 | 148 |
| 158 score_map[origin] = GetScore(origin); | 149 score_map[origin] = GetScore(origin); |
| 159 } | 150 } |
| 160 | 151 |
| 161 return score_map; | 152 return score_map; |
| 162 } | 153 } |
| 163 | 154 |
| 164 bool SiteEngagementService::IsBootstrapped() const { | 155 bool SiteEngagementService::IsBootstrapped() const { |
| 165 return GetTotalEngagementPoints() >= | 156 return GetTotalEngagementPoints() >= |
| 166 SiteEngagementScore::GetBootstrapPoints(); | 157 SiteEngagementScore::GetBootstrapPoints(); |
| 167 } | 158 } |
| 168 | 159 |
| 169 bool SiteEngagementService::IsEngagementAtLeast(const GURL& url, | 160 bool SiteEngagementService::IsEngagementAtLeast( |
| 170 EngagementLevel level) const { | 161 const GURL& url, |
| 162 blink::mojom::EngagementLevel level) const { |
| 171 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(), | 163 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(), |
| 172 SiteEngagementScore::GetHighEngagementBoundary()); | 164 SiteEngagementScore::GetHighEngagementBoundary()); |
| 173 double score = GetScore(url); | 165 double score = GetScore(url); |
| 174 switch (level) { | 166 switch (level) { |
| 175 case ENGAGEMENT_LEVEL_NONE: | 167 case blink::mojom::EngagementLevel::NONE: |
| 176 return true; | 168 return true; |
| 177 case ENGAGEMENT_LEVEL_LOW: | 169 case blink::mojom::EngagementLevel::MINIMAL: |
| 178 return score > 0; | 170 return score > 0; |
| 179 case ENGAGEMENT_LEVEL_MEDIUM: | 171 case blink::mojom::EngagementLevel::LOW: |
| 172 return score >= 1; |
| 173 case blink::mojom::EngagementLevel::MEDIUM: |
| 180 return score >= SiteEngagementScore::GetMediumEngagementBoundary(); | 174 return score >= SiteEngagementScore::GetMediumEngagementBoundary(); |
| 181 case ENGAGEMENT_LEVEL_HIGH: | 175 case blink::mojom::EngagementLevel::HIGH: |
| 182 return score >= SiteEngagementScore::GetHighEngagementBoundary(); | 176 return score >= SiteEngagementScore::GetHighEngagementBoundary(); |
| 183 case ENGAGEMENT_LEVEL_MAX: | 177 case blink::mojom::EngagementLevel::MAX: |
| 184 return score == SiteEngagementScore::kMaxPoints; | 178 return score == SiteEngagementScore::kMaxPoints; |
| 185 } | 179 } |
| 186 NOTREACHED(); | 180 NOTREACHED(); |
| 187 return false; | 181 return false; |
| 188 } | 182 } |
| 189 | 183 |
| 190 void SiteEngagementService::AddObserver(SiteEngagementObserver* observer) { | 184 void SiteEngagementService::AddObserver(SiteEngagementObserver* observer) { |
| 191 observer_list_.AddObserver(observer); | 185 observer_list_.AddObserver(observer); |
| 192 } | 186 } |
| 193 | 187 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 212 SiteEngagementMetrics::RecordDaysSinceLastShortcutLaunch( | 206 SiteEngagementMetrics::RecordDaysSinceLastShortcutLaunch( |
| 213 std::max(0, (now - last_launch).InDays())); | 207 std::max(0, (now - last_launch).InDays())); |
| 214 } | 208 } |
| 215 SiteEngagementMetrics::RecordEngagement( | 209 SiteEngagementMetrics::RecordEngagement( |
| 216 SiteEngagementMetrics::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH); | 210 SiteEngagementMetrics::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH); |
| 217 | 211 |
| 218 score.set_last_shortcut_launch_time(now); | 212 score.set_last_shortcut_launch_time(now); |
| 219 score.Commit(); | 213 score.Commit(); |
| 220 } | 214 } |
| 221 | 215 |
| 216 void SiteEngagementService::HelperCreated( |
| 217 SiteEngagementService::Helper* helper) { |
| 218 helpers_.insert(helper); |
| 219 } |
| 220 |
| 221 void SiteEngagementService::HelperDeleted( |
| 222 SiteEngagementService::Helper* helper) { |
| 223 helpers_.erase(helper); |
| 224 } |
| 225 |
| 222 double SiteEngagementService::GetScore(const GURL& url) const { | 226 double SiteEngagementService::GetScore(const GURL& url) const { |
| 223 // Ensure that if engagement is stale, we clean things up before fetching the | 227 // Ensure that if engagement is stale, we clean things up before fetching the |
| 224 // score. | 228 // score. |
| 225 if (IsLastEngagementStale()) | 229 if (IsLastEngagementStale()) |
| 226 CleanupEngagementScores(true); | 230 CleanupEngagementScores(true); |
| 227 | 231 |
| 228 return CreateEngagementScore(url).GetScore(); | 232 return CreateEngagementScore(url).GetScore(); |
| 229 } | 233 } |
| 230 | 234 |
| 231 double SiteEngagementService::GetTotalEngagementPoints() const { | 235 double SiteEngagementService::GetTotalEngagementPoints() const { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 252 if (points == 0) | 256 if (points == 0) |
| 253 return; | 257 return; |
| 254 | 258 |
| 255 // Trigger a cleanup and date adjustment if it has been a substantial length | 259 // Trigger a cleanup and date adjustment if it has been a substantial length |
| 256 // of time since *any* engagement was recorded by the service. This will | 260 // of time since *any* engagement was recorded by the service. This will |
| 257 // ensure that we do not decay scores when the user did not use the browser. | 261 // ensure that we do not decay scores when the user did not use the browser. |
| 258 if (IsLastEngagementStale()) | 262 if (IsLastEngagementStale()) |
| 259 CleanupEngagementScores(true); | 263 CleanupEngagementScores(true); |
| 260 | 264 |
| 261 SiteEngagementScore score = CreateEngagementScore(url); | 265 SiteEngagementScore score = CreateEngagementScore(url); |
| 266 blink::mojom::EngagementLevel old_level = score.GetEngagementLevel(); |
| 267 |
| 262 score.AddPoints(points); | 268 score.AddPoints(points); |
| 263 score.Commit(); | 269 score.Commit(); |
| 264 | 270 |
| 265 SetLastEngagementTime(score.last_engagement_time()); | 271 SetLastEngagementTime(score.last_engagement_time()); |
| 272 |
| 273 blink::mojom::EngagementLevel new_level = score.GetEngagementLevel(); |
| 274 if (old_level != new_level) |
| 275 SendLevelChangeToHelpers(url, new_level); |
| 266 } | 276 } |
| 267 | 277 |
| 268 void SiteEngagementService::AfterStartupTask() { | 278 void SiteEngagementService::AfterStartupTask() { |
| 269 // Check if we need to reset last engagement times on startup - we want to | 279 // Check if we need to reset last engagement times on startup - we want to |
| 270 // avoid doing this in AddPoints() if possible. It is still necessary to check | 280 // avoid doing this in AddPoints() if possible. It is still necessary to check |
| 271 // in AddPoints for people who never restart Chrome, but leave it open and | 281 // in AddPoints for people who never restart Chrome, but leave it open and |
| 272 // their computer on standby. | 282 // their computer on standby. |
| 273 CleanupEngagementScores(IsLastEngagementStale()); | 283 CleanupEngagementScores(IsLastEngagementStale()); |
| 274 RecordMetrics(); | 284 RecordMetrics(); |
| 275 } | 285 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 return; | 487 return; |
| 478 | 488 |
| 479 SiteEngagementMetrics::RecordEngagement(type); | 489 SiteEngagementMetrics::RecordEngagement(type); |
| 480 AddPoints(url, SiteEngagementScore::GetUserInputPoints()); | 490 AddPoints(url, SiteEngagementScore::GetUserInputPoints()); |
| 481 | 491 |
| 482 RecordMetrics(); | 492 RecordMetrics(); |
| 483 for (SiteEngagementObserver& observer : observer_list_) | 493 for (SiteEngagementObserver& observer : observer_list_) |
| 484 observer.OnEngagementIncreased(web_contents, url, GetScore(url)); | 494 observer.OnEngagementIncreased(web_contents, url, GetScore(url)); |
| 485 } | 495 } |
| 486 | 496 |
| 497 void SiteEngagementService::SendLevelChangeToHelpers( |
| 498 const GURL& url, |
| 499 blink::mojom::EngagementLevel level) { |
| 500 for (SiteEngagementService::Helper* helper : helpers_) |
| 501 helper->OnEngagementLevelChanged(url, level); |
| 502 } |
| 503 |
| 487 bool SiteEngagementService::IsLastEngagementStale() const { | 504 bool SiteEngagementService::IsLastEngagementStale() const { |
| 488 // Only happens on first run when no engagement has ever been recorded. | 505 // Only happens on first run when no engagement has ever been recorded. |
| 489 base::Time last_engagement_time = GetLastEngagementTime(); | 506 base::Time last_engagement_time = GetLastEngagementTime(); |
| 490 if (last_engagement_time.is_null()) | 507 if (last_engagement_time.is_null()) |
| 491 return false; | 508 return false; |
| 492 | 509 |
| 493 // Stale is either too *far* back, or any amount *forward* in time. This could | 510 // Stale is either too *far* back, or any amount *forward* in time. This could |
| 494 // occur due to a changed clock, or extended non-use of the browser. | 511 // occur due to a changed clock, or extended non-use of the browser. |
| 495 return (clock_->Now() - last_engagement_time) >= GetStalePeriod() || | 512 return (clock_->Now() - last_engagement_time) >= GetStalePeriod() || |
| 496 (clock_->Now() < last_engagement_time); | 513 (clock_->Now() < last_engagement_time); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 if (!engagement_score.last_shortcut_launch_time().is_null() && | 633 if (!engagement_score.last_shortcut_launch_time().is_null() && |
| 617 engagement_score.last_shortcut_launch_time() > last_visit) { | 634 engagement_score.last_shortcut_launch_time() > last_visit) { |
| 618 engagement_score.set_last_shortcut_launch_time(last_visit); | 635 engagement_score.set_last_shortcut_launch_time(last_visit); |
| 619 } | 636 } |
| 620 | 637 |
| 621 engagement_score.Commit(); | 638 engagement_score.Commit(); |
| 622 } | 639 } |
| 623 | 640 |
| 624 SetLastEngagementTime(now); | 641 SetLastEngagementTime(now); |
| 625 } | 642 } |
| OLD | NEW |