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

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

Issue 1986033002: Implement an observer interface for the site engagement service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@site-engagement-refactor
Patch Set: Addressing reviewer comments Created 4 years, 6 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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <utility> 10 #include <utility>
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 } 160 }
161 161
162 return score_map; 162 return score_map;
163 } 163 }
164 164
165 bool SiteEngagementService::IsBootstrapped() const { 165 bool SiteEngagementService::IsBootstrapped() const {
166 return GetTotalEngagementPoints() >= 166 return GetTotalEngagementPoints() >=
167 SiteEngagementScore::GetBootstrapPoints(); 167 SiteEngagementScore::GetBootstrapPoints();
168 } 168 }
169 169
170 bool SiteEngagementService::IsEngagementAtLeast( 170 bool SiteEngagementService::IsEngagementAtLeast(const GURL& url,
171 const GURL& url, 171 EngagementLevel level) const {
172 EngagementLevel level) const {
173 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(), 172 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(),
174 SiteEngagementScore::GetHighEngagementBoundary()); 173 SiteEngagementScore::GetHighEngagementBoundary());
175 double score = GetScore(url); 174 double score = GetScore(url);
176 switch (level) { 175 switch (level) {
177 case ENGAGEMENT_LEVEL_NONE: 176 case ENGAGEMENT_LEVEL_NONE:
178 return true; 177 return true;
179 case ENGAGEMENT_LEVEL_LOW: 178 case ENGAGEMENT_LEVEL_LOW:
180 return score > 0; 179 return score > 0;
181 case ENGAGEMENT_LEVEL_MEDIUM: 180 case ENGAGEMENT_LEVEL_MEDIUM:
182 return score >= SiteEngagementScore::GetMediumEngagementBoundary(); 181 return score >= SiteEngagementScore::GetMediumEngagementBoundary();
183 case ENGAGEMENT_LEVEL_HIGH: 182 case ENGAGEMENT_LEVEL_HIGH:
184 return score >= SiteEngagementScore::GetHighEngagementBoundary(); 183 return score >= SiteEngagementScore::GetHighEngagementBoundary();
185 case ENGAGEMENT_LEVEL_MAX: 184 case ENGAGEMENT_LEVEL_MAX:
186 return score == SiteEngagementScore::kMaxPoints; 185 return score == SiteEngagementScore::kMaxPoints;
187 } 186 }
188 NOTREACHED(); 187 NOTREACHED();
189 return false; 188 return false;
190 } 189 }
191 190
191 void SiteEngagementService::AddObserver(SiteEngagementObserver* observer) {
192 observer_list_.AddObserver(observer);
193 }
194
195 void SiteEngagementService::RemoveObserver(SiteEngagementObserver* observer) {
196 observer_list_.RemoveObserver(observer);
197 }
198
192 void SiteEngagementService::ResetScoreForURL(const GURL& url, double score) { 199 void SiteEngagementService::ResetScoreForURL(const GURL& url, double score) {
193 SiteEngagementScore engagement_score = CreateEngagementScore(url); 200 SiteEngagementScore engagement_score = CreateEngagementScore(url);
194 engagement_score.Reset(score, clock_->Now()); 201 engagement_score.Reset(score, clock_->Now());
195 engagement_score.Commit(); 202 engagement_score.Commit();
196 } 203 }
197 204
198 void SiteEngagementService::SetLastShortcutLaunchTime(const GURL& url) { 205 void SiteEngagementService::SetLastShortcutLaunchTime(const GURL& url) {
199 SiteEngagementScore score = CreateEngagementScore(url); 206 SiteEngagementScore score = CreateEngagementScore(url);
200 207
201 // Record the number of days since the last launch in UMA. If the user's clock 208 // Record the number of days since the last launch in UMA. If the user's clock
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 score.Commit(); 251 score.Commit();
245 } 252 }
246 253
247 void SiteEngagementService::AfterStartupTask() { 254 void SiteEngagementService::AfterStartupTask() {
248 CleanupEngagementScores(); 255 CleanupEngagementScores();
249 RecordMetrics(); 256 RecordMetrics();
250 } 257 }
251 258
252 void SiteEngagementService::CleanupEngagementScores() { 259 void SiteEngagementService::CleanupEngagementScores() {
253 HostContentSettingsMap* settings_map = 260 HostContentSettingsMap* settings_map =
254 HostContentSettingsMapFactory::GetForProfile(profile_); 261 HostContentSettingsMapFactory::GetForProfile(profile_);
255 std::unique_ptr<ContentSettingsForOneType> engagement_settings = 262 std::unique_ptr<ContentSettingsForOneType> engagement_settings =
256 GetEngagementContentSettings(settings_map); 263 GetEngagementContentSettings(settings_map);
257 264
258 for (const auto& site : *engagement_settings) { 265 for (const auto& site : *engagement_settings) {
259 GURL origin(site.primary_pattern.ToString()); 266 GURL origin(site.primary_pattern.ToString());
260 if (origin.is_valid() && GetScore(origin) != 0) 267 if (origin.is_valid() && GetScore(origin) != 0)
261 continue; 268 continue;
262 269
263 settings_map->SetWebsiteSettingDefaultScope( 270 settings_map->SetWebsiteSettingDefaultScope(
264 origin, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), 271 origin, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
265 nullptr); 272 nullptr);
266 } 273 }
267 } 274 }
268 275
269 void SiteEngagementService::RecordMetrics() { 276 void SiteEngagementService::RecordMetrics() {
270 base::Time now = clock_->Now(); 277 base::Time now = clock_->Now();
271 if (last_metrics_time_.is_null() || 278 if (last_metrics_time_.is_null() ||
272 (now - last_metrics_time_).InMinutes() >= kMetricsIntervalInMinutes) { 279 (now - last_metrics_time_).InMinutes() >= kMetricsIntervalInMinutes) {
273 last_metrics_time_ = now; 280 last_metrics_time_ = now;
274 std::map<GURL, double> score_map = GetScoreMap(); 281 std::map<GURL, double> score_map = GetScoreMap();
275 282
276 int origins_with_max_engagement = OriginsWithMaxEngagement(score_map); 283 int origins_with_max_engagement = OriginsWithMaxEngagement(score_map);
277 int total_origins = score_map.size(); 284 int total_origins = score_map.size();
278 int percent_origins_with_max_engagement = 285 int percent_origins_with_max_engagement =
279 (total_origins == 0 ? 0 : (origins_with_max_engagement * 100) / 286 (total_origins == 0
280 total_origins); 287 ? 0
288 : (origins_with_max_engagement * 100) / total_origins);
281 289
282 double total_engagement = GetTotalEngagementPoints(); 290 double total_engagement = GetTotalEngagementPoints();
283 double mean_engagement = 291 double mean_engagement =
284 (total_origins == 0 ? 0 : total_engagement / total_origins); 292 (total_origins == 0 ? 0 : total_engagement / total_origins);
285 293
286 SiteEngagementMetrics::RecordTotalOriginsEngaged(total_origins); 294 SiteEngagementMetrics::RecordTotalOriginsEngaged(total_origins);
287 SiteEngagementMetrics::RecordTotalSiteEngagement(total_engagement); 295 SiteEngagementMetrics::RecordTotalSiteEngagement(total_engagement);
288 SiteEngagementMetrics::RecordMeanEngagement(mean_engagement); 296 SiteEngagementMetrics::RecordMeanEngagement(mean_engagement);
289 SiteEngagementMetrics::RecordMedianEngagement( 297 SiteEngagementMetrics::RecordMedianEngagement(
290 GetMedianEngagement(score_map)); 298 GetMedianEngagement(score_map));
(...skipping 23 matching lines...) Expand all
314 // scores otherwise. 322 // scores otherwise.
315 std::sort(scores.begin(), scores.end()); 323 std::sort(scores.begin(), scores.end());
316 size_t mid = scores.size() / 2; 324 size_t mid = scores.size() / 2;
317 if (scores.size() % 2 == 1) 325 if (scores.size() % 2 == 1)
318 return scores[mid]; 326 return scores[mid];
319 else 327 else
320 return (scores[mid - 1] + scores[mid]) / 2; 328 return (scores[mid - 1] + scores[mid]) / 2;
321 } 329 }
322 330
323 void SiteEngagementService::HandleMediaPlaying( 331 void SiteEngagementService::HandleMediaPlaying(
324 content::WebContents* web_contents, bool is_hidden) { 332 content::WebContents* web_contents,
333 bool is_hidden) {
334 const GURL& url = web_contents->GetVisibleURL();
325 SiteEngagementMetrics::RecordEngagement( 335 SiteEngagementMetrics::RecordEngagement(
326 is_hidden ? SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN 336 is_hidden ? SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN
327 : SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE); 337 : SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE);
328 AddPoints(web_contents->GetVisibleURL(), 338 AddPoints(url, is_hidden ? SiteEngagementScore::GetHiddenMediaPoints()
329 is_hidden ? SiteEngagementScore::GetHiddenMediaPoints() 339 : SiteEngagementScore::GetVisibleMediaPoints());
330 : SiteEngagementScore::GetVisibleMediaPoints()); 340
331 RecordMetrics(); 341 RecordMetrics();
342 FOR_EACH_OBSERVER(
343 SiteEngagementObserver, observer_list_,
344 OnEngagementIncreased(web_contents, url, GetScore(url)));
332 } 345 }
333 346
334 void SiteEngagementService::HandleNavigation(content::WebContents* web_contents, 347 void SiteEngagementService::HandleNavigation(content::WebContents* web_contents,
335 ui::PageTransition transition) { 348 ui::PageTransition transition) {
336 if (IsEngagementNavigation(transition)) { 349 if (IsEngagementNavigation(transition)) {
350 const GURL& url = web_contents->GetLastCommittedURL();
337 SiteEngagementMetrics::RecordEngagement( 351 SiteEngagementMetrics::RecordEngagement(
338 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION); 352 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION);
339 AddPoints(web_contents->GetLastCommittedURL(), 353 AddPoints(url, SiteEngagementScore::GetNavigationPoints());
340 SiteEngagementScore::GetNavigationPoints()); 354
341 RecordMetrics(); 355 RecordMetrics();
356 FOR_EACH_OBSERVER(
357 SiteEngagementObserver, observer_list_,
358 OnEngagementIncreased(web_contents, url, GetScore(url)));
342 } 359 }
343 } 360 }
344 361
345 void SiteEngagementService::HandleUserInput( 362 void SiteEngagementService::HandleUserInput(
346 content::WebContents* web_contents, 363 content::WebContents* web_contents,
347 SiteEngagementMetrics::EngagementType type) { 364 SiteEngagementMetrics::EngagementType type) {
365 const GURL& url = web_contents->GetVisibleURL();
348 SiteEngagementMetrics::RecordEngagement(type); 366 SiteEngagementMetrics::RecordEngagement(type);
349 AddPoints(web_contents->GetVisibleURL(), 367 AddPoints(url, SiteEngagementScore::GetUserInputPoints());
350 SiteEngagementScore::GetUserInputPoints()); 368
351 RecordMetrics(); 369 RecordMetrics();
370 FOR_EACH_OBSERVER(
371 SiteEngagementObserver, observer_list_,
372 OnEngagementIncreased(web_contents, url, GetScore(url)));
352 } 373 }
353 374
354 void SiteEngagementService::OnURLsDeleted( 375 void SiteEngagementService::OnURLsDeleted(
355 history::HistoryService* history_service, 376 history::HistoryService* history_service,
356 bool all_history, 377 bool all_history,
357 bool expired, 378 bool expired,
358 const history::URLRows& deleted_rows, 379 const history::URLRows& deleted_rows,
359 const std::set<GURL>& favicon_urls) { 380 const std::set<GURL>& favicon_urls) {
360 std::multiset<GURL> origins; 381 std::multiset<GURL> origins;
361 for (const history::URLRow& row : deleted_rows) 382 for (const history::URLRow& row : deleted_rows)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 ++total_origins; 435 ++total_origins;
415 436
416 return total_origins; 437 return total_origins;
417 } 438 }
418 439
419 void SiteEngagementService::GetCountsAndLastVisitForOriginsComplete( 440 void SiteEngagementService::GetCountsAndLastVisitForOriginsComplete(
420 history::HistoryService* history_service, 441 history::HistoryService* history_service,
421 const std::multiset<GURL>& deleted_origins, 442 const std::multiset<GURL>& deleted_origins,
422 bool expired, 443 bool expired,
423 const history::OriginCountAndLastVisitMap& remaining_origins) { 444 const history::OriginCountAndLastVisitMap& remaining_origins) {
424
425 // The most in-the-past option in the Clear Browsing Dialog aside from "all 445 // The most in-the-past option in the Clear Browsing Dialog aside from "all
426 // time" is 4 weeks ago. Set the last updated date to 4 weeks ago for origins 446 // time" is 4 weeks ago. Set the last updated date to 4 weeks ago for origins
427 // where we can't find a valid last visit date. 447 // where we can't find a valid last visit date.
428 base::Time now = clock_->Now(); 448 base::Time now = clock_->Now();
429 base::Time four_weeks_ago = 449 base::Time four_weeks_ago =
430 now - base::TimeDelta::FromDays(FOUR_WEEKS_IN_DAYS); 450 now - base::TimeDelta::FromDays(FOUR_WEEKS_IN_DAYS);
431 451
432 for (const auto& origin_to_count : remaining_origins) { 452 for (const auto& origin_to_count : remaining_origins) {
433 GURL origin = origin_to_count.first; 453 GURL origin = origin_to_count.first;
434 // It appears that the history service occasionally sends bad URLs to us. 454 // It appears that the history service occasionally sends bad URLs to us.
(...skipping 23 matching lines...) Expand all
458 // in the past, the next time the origin's engagement is accessed the 478 // in the past, the next time the origin's engagement is accessed the
459 // automatic decay will kick in - i.e. a double decay will have occurred. 479 // automatic decay will kick in - i.e. a double decay will have occurred.
460 // To prevent this, compute the decay that would have taken place since the 480 // To prevent this, compute the decay that would have taken place since the
461 // new last visit and add it to the engagement at this point. When the 481 // new last visit and add it to the engagement at this point. When the
462 // engagement is next accessed, it will decay back to the proportionally 482 // engagement is next accessed, it will decay back to the proportionally
463 // reduced value rather than being decayed once here, and then once again 483 // reduced value rather than being decayed once here, and then once again
464 // when it is next accessed. 484 // when it is next accessed.
465 int undecay = 0; 485 int undecay = 0;
466 int days_since_engagement = (now - last_visit).InDays(); 486 int days_since_engagement = (now - last_visit).InDays();
467 if (days_since_engagement > 0) { 487 if (days_since_engagement > 0) {
468 int periods = days_since_engagement / 488 int periods =
469 SiteEngagementScore::GetDecayPeriodInDays(); 489 days_since_engagement / SiteEngagementScore::GetDecayPeriodInDays();
470 undecay = periods * SiteEngagementScore::GetDecayPoints(); 490 undecay = periods * SiteEngagementScore::GetDecayPoints();
471 } 491 }
472 492
473 SiteEngagementScore engagement_score = CreateEngagementScore(origin); 493 SiteEngagementScore engagement_score = CreateEngagementScore(origin);
474 494
475 double score = std::min( 495 double score = std::min(
476 SiteEngagementScore::kMaxPoints, 496 SiteEngagementScore::kMaxPoints,
477 (proportion_remaining * engagement_score.GetScore()) + undecay); 497 (proportion_remaining * engagement_score.GetScore()) + undecay);
478 engagement_score.Reset(score, last_visit); 498 engagement_score.Reset(score, last_visit);
479 if (!engagement_score.last_shortcut_launch_time().is_null() 499 if (!engagement_score.last_shortcut_launch_time().is_null() &&
480 && engagement_score.last_shortcut_launch_time() > last_visit) { 500 engagement_score.last_shortcut_launch_time() > last_visit) {
481 engagement_score.set_last_shortcut_launch_time(last_visit); 501 engagement_score.set_last_shortcut_launch_time(last_visit);
482 } 502 }
483 503
484 engagement_score.Commit(); 504 engagement_score.Commit();
485 } 505 }
486 } 506 }
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