| 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_helper.h" |
| 23 #include "chrome/browser/engagement/site_engagement_metrics.h" | 24 #include "chrome/browser/engagement/site_engagement_metrics.h" |
| 24 #include "chrome/browser/engagement/site_engagement_score.h" | 25 #include "chrome/browser/engagement/site_engagement_score.h" |
| 25 #include "chrome/browser/engagement/site_engagement_service_factory.h" | 26 #include "chrome/browser/engagement/site_engagement_service_factory.h" |
| 26 #include "chrome/browser/history/history_service_factory.h" | 27 #include "chrome/browser/history/history_service_factory.h" |
| 27 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
| 28 #include "chrome/common/chrome_switches.h" | 29 #include "chrome/common/chrome_switches.h" |
| 29 #include "chrome/common/pref_names.h" | 30 #include "chrome/common/pref_names.h" |
| 30 #include "components/content_settings/core/browser/host_content_settings_map.h" | 31 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 31 #include "components/content_settings/core/common/content_settings_pattern.h" | 32 #include "components/content_settings/core/common/content_settings_pattern.h" |
| 32 #include "components/history/core/browser/history_service.h" | 33 #include "components/history/core/browser/history_service.h" |
| 33 #include "components/prefs/pref_service.h" | 34 #include "components/prefs/pref_service.h" |
| 34 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
| 36 #include "content/public/browser/render_frame_host.h" |
| 35 #include "content/public/browser/web_contents.h" | 37 #include "content/public/browser/web_contents.h" |
| 38 #include "content/public/common/associated_interface_provider.h" |
| 36 #include "url/gurl.h" | 39 #include "url/gurl.h" |
| 37 | 40 |
| 38 #if defined(OS_ANDROID) | 41 #if defined(OS_ANDROID) |
| 39 #include "chrome/browser/engagement/site_engagement_service_android.h" | 42 #include "chrome/browser/engagement/site_engagement_service_android.h" |
| 40 #endif | 43 #endif |
| 41 | 44 |
| 42 namespace { | 45 namespace { |
| 43 | 46 |
| 44 const int FOUR_WEEKS_IN_DAYS = 28; | 47 const int FOUR_WEEKS_IN_DAYS = 28; |
| 45 | 48 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 } | 122 } |
| 120 } | 123 } |
| 121 | 124 |
| 122 SiteEngagementService::~SiteEngagementService() { | 125 SiteEngagementService::~SiteEngagementService() { |
| 123 history::HistoryService* history = HistoryServiceFactory::GetForProfile( | 126 history::HistoryService* history = HistoryServiceFactory::GetForProfile( |
| 124 profile_, ServiceAccessType::IMPLICIT_ACCESS); | 127 profile_, ServiceAccessType::IMPLICIT_ACCESS); |
| 125 if (history) | 128 if (history) |
| 126 history->RemoveObserver(this); | 129 history->RemoveObserver(this); |
| 127 } | 130 } |
| 128 | 131 |
| 129 SiteEngagementService::EngagementLevel | 132 blink::mojom::EngagementLevel |
| 130 SiteEngagementService::GetEngagementLevel(const GURL& url) const { | 133 SiteEngagementService::GetEngagementLevel(const GURL& url) const { |
| 131 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(), | 134 if (IsLastEngagementStale()) |
| 132 SiteEngagementScore::GetHighEngagementBoundary()); | 135 CleanupEngagementScores(true); |
| 133 double score = GetScore(url); | |
| 134 if (score == 0) | |
| 135 return ENGAGEMENT_LEVEL_NONE; | |
| 136 | 136 |
| 137 if (score < SiteEngagementScore::GetMediumEngagementBoundary()) | 137 return CreateEngagementScore(url).GetEngagementLevel(); |
| 138 return ENGAGEMENT_LEVEL_LOW; | |
| 139 | |
| 140 if (score < SiteEngagementScore::GetHighEngagementBoundary()) | |
| 141 return ENGAGEMENT_LEVEL_MEDIUM; | |
| 142 | |
| 143 if (score < SiteEngagementScore::kMaxPoints) | |
| 144 return ENGAGEMENT_LEVEL_HIGH; | |
| 145 | |
| 146 return ENGAGEMENT_LEVEL_MAX; | |
| 147 } | 138 } |
| 148 | 139 |
| 149 std::map<GURL, double> SiteEngagementService::GetScoreMap() const { | 140 std::map<GURL, double> SiteEngagementService::GetScoreMap() const { |
| 150 HostContentSettingsMap* settings_map = | 141 HostContentSettingsMap* settings_map = |
| 151 HostContentSettingsMapFactory::GetForProfile(profile_); | 142 HostContentSettingsMapFactory::GetForProfile(profile_); |
| 152 std::unique_ptr<ContentSettingsForOneType> engagement_settings = | 143 std::unique_ptr<ContentSettingsForOneType> engagement_settings = |
| 153 GetEngagementContentSettings(settings_map); | 144 GetEngagementContentSettings(settings_map); |
| 154 | 145 |
| 155 std::map<GURL, double> score_map; | 146 std::map<GURL, double> score_map; |
| 156 for (const auto& site : *engagement_settings) { | 147 for (const auto& site : *engagement_settings) { |
| 157 GURL origin(site.primary_pattern.ToString()); | 148 GURL origin(site.primary_pattern.ToString()); |
| 158 if (!origin.is_valid()) | 149 if (!origin.is_valid()) |
| 159 continue; | 150 continue; |
| 160 | 151 |
| 161 score_map[origin] = GetScore(origin); | 152 score_map[origin] = GetScore(origin); |
| 162 } | 153 } |
| 163 | 154 |
| 164 return score_map; | 155 return score_map; |
| 165 } | 156 } |
| 166 | 157 |
| 167 bool SiteEngagementService::IsBootstrapped() const { | 158 bool SiteEngagementService::IsBootstrapped() const { |
| 168 return GetTotalEngagementPoints() >= | 159 return GetTotalEngagementPoints() >= |
| 169 SiteEngagementScore::GetBootstrapPoints(); | 160 SiteEngagementScore::GetBootstrapPoints(); |
| 170 } | 161 } |
| 171 | 162 |
| 172 bool SiteEngagementService::IsEngagementAtLeast(const GURL& url, | 163 bool SiteEngagementService::IsEngagementAtLeast( |
| 173 EngagementLevel level) const { | 164 const GURL& url, |
| 165 blink::mojom::EngagementLevel level) const { |
| 174 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(), | 166 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(), |
| 175 SiteEngagementScore::GetHighEngagementBoundary()); | 167 SiteEngagementScore::GetHighEngagementBoundary()); |
| 176 double score = GetScore(url); | 168 double score = GetScore(url); |
| 177 switch (level) { | 169 switch (level) { |
| 178 case ENGAGEMENT_LEVEL_NONE: | 170 case blink::mojom::EngagementLevel::NONE: |
| 179 return true; | 171 return true; |
| 180 case ENGAGEMENT_LEVEL_LOW: | 172 case blink::mojom::EngagementLevel::MINIMAL: |
| 181 return score > 0; | 173 return score > 0; |
| 182 case ENGAGEMENT_LEVEL_MEDIUM: | 174 case blink::mojom::EngagementLevel::LOW: |
| 175 return score >= 1; |
| 176 case blink::mojom::EngagementLevel::MEDIUM: |
| 183 return score >= SiteEngagementScore::GetMediumEngagementBoundary(); | 177 return score >= SiteEngagementScore::GetMediumEngagementBoundary(); |
| 184 case ENGAGEMENT_LEVEL_HIGH: | 178 case blink::mojom::EngagementLevel::HIGH: |
| 185 return score >= SiteEngagementScore::GetHighEngagementBoundary(); | 179 return score >= SiteEngagementScore::GetHighEngagementBoundary(); |
| 186 case ENGAGEMENT_LEVEL_MAX: | 180 case blink::mojom::EngagementLevel::MAX: |
| 187 return score == SiteEngagementScore::kMaxPoints; | 181 return score == SiteEngagementScore::kMaxPoints; |
| 188 } | 182 } |
| 189 NOTREACHED(); | 183 NOTREACHED(); |
| 190 return false; | 184 return false; |
| 191 } | 185 } |
| 192 | 186 |
| 193 void SiteEngagementService::AddObserver(SiteEngagementObserver* observer) { | 187 void SiteEngagementService::AddObserver(SiteEngagementObserver* observer) { |
| 194 observer_list_.AddObserver(observer); | 188 observer_list_.AddObserver(observer); |
| 195 } | 189 } |
| 196 | 190 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 215 SiteEngagementMetrics::RecordDaysSinceLastShortcutLaunch( | 209 SiteEngagementMetrics::RecordDaysSinceLastShortcutLaunch( |
| 216 std::max(0, (now - last_launch).InDays())); | 210 std::max(0, (now - last_launch).InDays())); |
| 217 } | 211 } |
| 218 SiteEngagementMetrics::RecordEngagement( | 212 SiteEngagementMetrics::RecordEngagement( |
| 219 SiteEngagementMetrics::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH); | 213 SiteEngagementMetrics::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH); |
| 220 | 214 |
| 221 score.set_last_shortcut_launch_time(now); | 215 score.set_last_shortcut_launch_time(now); |
| 222 score.Commit(); | 216 score.Commit(); |
| 223 } | 217 } |
| 224 | 218 |
| 219 void SiteEngagementService::HelperCreated( |
| 220 SiteEngagementService::Helper* helper) { |
| 221 helpers_.insert(helper); |
| 222 } |
| 223 |
| 224 void SiteEngagementService::HelperDeleted( |
| 225 SiteEngagementService::Helper* helper) { |
| 226 helpers_.erase(helper); |
| 227 } |
| 228 |
| 225 double SiteEngagementService::GetScore(const GURL& url) const { | 229 double SiteEngagementService::GetScore(const GURL& url) const { |
| 226 // Ensure that if engagement is stale, we clean things up before fetching the | 230 // Ensure that if engagement is stale, we clean things up before fetching the |
| 227 // score. | 231 // score. |
| 228 if (IsLastEngagementStale()) | 232 if (IsLastEngagementStale()) |
| 229 CleanupEngagementScores(true); | 233 CleanupEngagementScores(true); |
| 230 | 234 |
| 231 return CreateEngagementScore(url).GetScore(); | 235 return CreateEngagementScore(url).GetScore(); |
| 232 } | 236 } |
| 233 | 237 |
| 234 double SiteEngagementService::GetTotalEngagementPoints() const { | 238 double SiteEngagementService::GetTotalEngagementPoints() const { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 if (points == 0) | 270 if (points == 0) |
| 267 return; | 271 return; |
| 268 | 272 |
| 269 // Trigger a cleanup and date adjustment if it has been a substantial length | 273 // Trigger a cleanup and date adjustment if it has been a substantial length |
| 270 // of time since *any* engagement was recorded by the service. This will | 274 // of time since *any* engagement was recorded by the service. This will |
| 271 // ensure that we do not decay scores when the user did not use the browser. | 275 // ensure that we do not decay scores when the user did not use the browser. |
| 272 if (IsLastEngagementStale()) | 276 if (IsLastEngagementStale()) |
| 273 CleanupEngagementScores(true); | 277 CleanupEngagementScores(true); |
| 274 | 278 |
| 275 SiteEngagementScore score = CreateEngagementScore(url); | 279 SiteEngagementScore score = CreateEngagementScore(url); |
| 280 blink::mojom::EngagementLevel old_level = score.GetEngagementLevel(); |
| 281 |
| 276 score.AddPoints(points); | 282 score.AddPoints(points); |
| 277 score.Commit(); | 283 score.Commit(); |
| 278 | 284 |
| 279 SetLastEngagementTime(score.last_engagement_time()); | 285 SetLastEngagementTime(score.last_engagement_time()); |
| 286 |
| 287 blink::mojom::EngagementLevel new_level = score.GetEngagementLevel(); |
| 288 if (old_level != new_level) |
| 289 SendLevelChangeToHelpers(url, new_level); |
| 280 } | 290 } |
| 281 | 291 |
| 282 void SiteEngagementService::AfterStartupTask() { | 292 void SiteEngagementService::AfterStartupTask() { |
| 283 // Check if we need to reset last engagement times on startup - we want to | 293 // Check if we need to reset last engagement times on startup - we want to |
| 284 // avoid doing this in AddPoints() if possible. It is still necessary to check | 294 // avoid doing this in AddPoints() if possible. It is still necessary to check |
| 285 // in AddPoints for people who never restart Chrome, but leave it open and | 295 // in AddPoints for people who never restart Chrome, but leave it open and |
| 286 // their computer on standby. | 296 // their computer on standby. |
| 287 CleanupEngagementScores(IsLastEngagementStale()); | 297 CleanupEngagementScores(IsLastEngagementStale()); |
| 288 RecordMetrics(); | 298 RecordMetrics(); |
| 289 } | 299 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 return; | 501 return; |
| 492 | 502 |
| 493 SiteEngagementMetrics::RecordEngagement(type); | 503 SiteEngagementMetrics::RecordEngagement(type); |
| 494 AddPoints(url, SiteEngagementScore::GetUserInputPoints()); | 504 AddPoints(url, SiteEngagementScore::GetUserInputPoints()); |
| 495 | 505 |
| 496 RecordMetrics(); | 506 RecordMetrics(); |
| 497 for (SiteEngagementObserver& observer : observer_list_) | 507 for (SiteEngagementObserver& observer : observer_list_) |
| 498 observer.OnEngagementIncreased(web_contents, url, GetScore(url)); | 508 observer.OnEngagementIncreased(web_contents, url, GetScore(url)); |
| 499 } | 509 } |
| 500 | 510 |
| 511 void SiteEngagementService::SendLevelChangeToHelpers( |
| 512 const GURL& url, |
| 513 blink::mojom::EngagementLevel level) { |
| 514 for (SiteEngagementService::Helper* helper : helpers_) |
| 515 helper->OnEngagementLevelChanged(url, level); |
| 516 } |
| 517 |
| 501 bool SiteEngagementService::IsLastEngagementStale() const { | 518 bool SiteEngagementService::IsLastEngagementStale() const { |
| 502 // Only happens on first run when no engagement has ever been recorded. | 519 // Only happens on first run when no engagement has ever been recorded. |
| 503 base::Time last_engagement_time = GetLastEngagementTime(); | 520 base::Time last_engagement_time = GetLastEngagementTime(); |
| 504 if (last_engagement_time.is_null()) | 521 if (last_engagement_time.is_null()) |
| 505 return false; | 522 return false; |
| 506 | 523 |
| 507 // Stale is either too *far* back, or any amount *forward* in time. This could | 524 // Stale is either too *far* back, or any amount *forward* in time. This could |
| 508 // occur due to a changed clock, or extended non-use of the browser. | 525 // occur due to a changed clock, or extended non-use of the browser. |
| 509 return (clock_->Now() - last_engagement_time) >= GetStalePeriod() || | 526 return (clock_->Now() - last_engagement_time) >= GetStalePeriod() || |
| 510 (clock_->Now() < last_engagement_time); | 527 (clock_->Now() < last_engagement_time); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 if (!engagement_score.last_shortcut_launch_time().is_null() && | 647 if (!engagement_score.last_shortcut_launch_time().is_null() && |
| 631 engagement_score.last_shortcut_launch_time() > last_visit) { | 648 engagement_score.last_shortcut_launch_time() > last_visit) { |
| 632 engagement_score.set_last_shortcut_launch_time(last_visit); | 649 engagement_score.set_last_shortcut_launch_time(last_visit); |
| 633 } | 650 } |
| 634 | 651 |
| 635 engagement_score.Commit(); | 652 engagement_score.Commit(); |
| 636 } | 653 } |
| 637 | 654 |
| 638 SetLastEngagementTime(now); | 655 SetLastEngagementTime(now); |
| 639 } | 656 } |
| OLD | NEW |