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

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

Issue 1919383005: Small cleanup of SiteEngagementService. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments Created 4 years, 7 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
« no previous file with comments | « chrome/browser/engagement/site_engagement_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 44
45 std::unique_ptr<ContentSettingsForOneType> GetEngagementContentSettings( 45 std::unique_ptr<ContentSettingsForOneType> GetEngagementContentSettings(
46 HostContentSettingsMap* settings_map) { 46 HostContentSettingsMap* settings_map) {
47 std::unique_ptr<ContentSettingsForOneType> engagement_settings( 47 std::unique_ptr<ContentSettingsForOneType> engagement_settings(
48 new ContentSettingsForOneType); 48 new ContentSettingsForOneType);
49 settings_map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, 49 settings_map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT,
50 std::string(), engagement_settings.get()); 50 std::string(), engagement_settings.get());
51 return engagement_settings; 51 return engagement_settings;
52 } 52 }
53 53
54 std::unique_ptr<base::DictionaryValue> GetScoreDictForOrigin(
55 HostContentSettingsMap* settings,
56 const GURL& origin_url) {
57 if (!settings)
58 return std::unique_ptr<base::DictionaryValue>();
59
60 std::unique_ptr<base::Value> value = settings->GetWebsiteSetting(
61 origin_url, origin_url, CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT,
62 std::string(), NULL);
63 if (!value.get())
64 return base::WrapUnique(new base::DictionaryValue());
65
66 if (!value->IsType(base::Value::TYPE_DICTIONARY))
67 return base::WrapUnique(new base::DictionaryValue());
68
69 return base::WrapUnique(static_cast<base::DictionaryValue*>(value.release()));
70 }
71
72 // Only accept a navigation event for engagement if it is one of: 54 // Only accept a navigation event for engagement if it is one of:
73 // a. direct typed navigation 55 // a. direct typed navigation
74 // b. clicking on an omnibox suggestion brought up by typing a keyword 56 // b. clicking on an omnibox suggestion brought up by typing a keyword
75 // c. clicking on a bookmark or opening a bookmark app 57 // c. clicking on a bookmark or opening a bookmark app
76 // d. a custom search engine keyword search (e.g. Wikipedia search box added as 58 // d. a custom search engine keyword search (e.g. Wikipedia search box added as
77 // search engine). 59 // search engine).
78 bool IsEngagementNavigation(ui::PageTransition transition) { 60 bool IsEngagementNavigation(ui::PageTransition transition) {
79 return ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) || 61 return ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) ||
80 ui::PageTransitionCoreTypeIs(transition, 62 ui::PageTransitionCoreTypeIs(transition,
81 ui::PAGE_TRANSITION_GENERATED) || 63 ui::PAGE_TRANSITION_GENERATED) ||
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 HostContentSettingsMapFactory::GetForProfile(profile_); 148 HostContentSettingsMapFactory::GetForProfile(profile_);
167 std::unique_ptr<ContentSettingsForOneType> engagement_settings = 149 std::unique_ptr<ContentSettingsForOneType> engagement_settings =
168 GetEngagementContentSettings(settings_map); 150 GetEngagementContentSettings(settings_map);
169 151
170 std::map<GURL, double> score_map; 152 std::map<GURL, double> score_map;
171 for (const auto& site : *engagement_settings) { 153 for (const auto& site : *engagement_settings) {
172 GURL origin(site.primary_pattern.ToString()); 154 GURL origin(site.primary_pattern.ToString());
173 if (!origin.is_valid()) 155 if (!origin.is_valid())
174 continue; 156 continue;
175 157
176 std::unique_ptr<base::DictionaryValue> score_dict = 158 score_map[origin] = GetScore(origin);
177 GetScoreDictForOrigin(settings_map, origin);
178 SiteEngagementScore score(clock_.get(), *score_dict);
179 score_map[origin] = score.GetScore();
180 } 159 }
181 160
182 return score_map; 161 return score_map;
183 } 162 }
184 163
185 bool SiteEngagementService::IsBootstrapped() { 164 bool SiteEngagementService::IsBootstrapped() const {
186 return GetTotalEngagementPoints() >= 165 return GetTotalEngagementPoints() >=
187 SiteEngagementScore::GetBootstrapPoints(); 166 SiteEngagementScore::GetBootstrapPoints();
188 } 167 }
189 168
190 bool SiteEngagementService::IsEngagementAtLeast( 169 bool SiteEngagementService::IsEngagementAtLeast(
191 const GURL& url, 170 const GURL& url,
192 EngagementLevel level) const { 171 EngagementLevel level) const {
193 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(), 172 DCHECK_LT(SiteEngagementScore::GetMediumEngagementBoundary(),
194 SiteEngagementScore::GetHighEngagementBoundary()); 173 SiteEngagementScore::GetHighEngagementBoundary());
195 double score = GetScore(url); 174 double score = GetScore(url);
196 switch (level) { 175 switch (level) {
197 case ENGAGEMENT_LEVEL_NONE: 176 case ENGAGEMENT_LEVEL_NONE:
198 return true; 177 return true;
199 case ENGAGEMENT_LEVEL_LOW: 178 case ENGAGEMENT_LEVEL_LOW:
200 return score > 0; 179 return score > 0;
201 case ENGAGEMENT_LEVEL_MEDIUM: 180 case ENGAGEMENT_LEVEL_MEDIUM:
202 return score >= SiteEngagementScore::GetMediumEngagementBoundary(); 181 return score >= SiteEngagementScore::GetMediumEngagementBoundary();
203 case ENGAGEMENT_LEVEL_HIGH: 182 case ENGAGEMENT_LEVEL_HIGH:
204 return score >= SiteEngagementScore::GetHighEngagementBoundary(); 183 return score >= SiteEngagementScore::GetHighEngagementBoundary();
205 case ENGAGEMENT_LEVEL_MAX: 184 case ENGAGEMENT_LEVEL_MAX:
206 return score == SiteEngagementScore::kMaxPoints; 185 return score == SiteEngagementScore::kMaxPoints;
207 } 186 }
208 NOTREACHED(); 187 NOTREACHED();
209 return false; 188 return false;
210 } 189 }
211 190
212 void SiteEngagementService::ResetScoreForURL(const GURL& url, double score) { 191 void SiteEngagementService::ResetScoreForURL(const GURL& url, double score) {
213 ResetScoreAndAccessTimesForURL(url, score, nullptr); 192 SiteEngagementScore engagement_score = CreateEngagementScore(url);
193 engagement_score.Reset(score, clock_->Now());
194 engagement_score.Commit();
214 } 195 }
215 196
216 void SiteEngagementService::SetLastShortcutLaunchTime(const GURL& url) { 197 void SiteEngagementService::SetLastShortcutLaunchTime(const GURL& url) {
217 HostContentSettingsMap* settings_map = 198 SiteEngagementScore score = CreateEngagementScore(url);
218 HostContentSettingsMapFactory::GetForProfile(profile_);
219 std::unique_ptr<base::DictionaryValue> score_dict =
220 GetScoreDictForOrigin(settings_map, url);
221 SiteEngagementScore score(clock_.get(), *score_dict);
222 199
223 // Record the number of days since the last launch in UMA. If the user's clock 200 // Record the number of days since the last launch in UMA. If the user's clock
224 // has changed back in time, set this to 0. 201 // has changed back in time, set this to 0.
225 base::Time now = clock_->Now(); 202 base::Time now = clock_->Now();
226 base::Time last_launch = score.last_shortcut_launch_time(); 203 base::Time last_launch = score.last_shortcut_launch_time();
227 if (!last_launch.is_null()) { 204 if (!last_launch.is_null()) {
228 SiteEngagementMetrics::RecordDaysSinceLastShortcutLaunch( 205 SiteEngagementMetrics::RecordDaysSinceLastShortcutLaunch(
229 std::max(0, (now - last_launch).InDays())); 206 std::max(0, (now - last_launch).InDays()));
230 } 207 }
231 SiteEngagementMetrics::RecordEngagement( 208 SiteEngagementMetrics::RecordEngagement(
232 SiteEngagementMetrics::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH); 209 SiteEngagementMetrics::ENGAGEMENT_WEBAPP_SHORTCUT_LAUNCH);
233 210
234 score.set_last_shortcut_launch_time(now); 211 score.set_last_shortcut_launch_time(now);
235 if (score.UpdateScoreDict(score_dict.get())) { 212 score.Commit();
236 settings_map->SetWebsiteSettingDefaultScope(
237 url, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
238 score_dict.release());
239 }
240 } 213 }
241 214
242 double SiteEngagementService::GetScore(const GURL& url) const { 215 double SiteEngagementService::GetScore(const GURL& url) const {
243 HostContentSettingsMap* settings_map = 216 return CreateEngagementScore(url).GetScore();
244 HostContentSettingsMapFactory::GetForProfile(profile_);
245 std::unique_ptr<base::DictionaryValue> score_dict =
246 GetScoreDictForOrigin(settings_map, url);
247 SiteEngagementScore score(clock_.get(), *score_dict);
248
249 return score.GetScore();
250 } 217 }
251 218
252 double SiteEngagementService::GetTotalEngagementPoints() const { 219 double SiteEngagementService::GetTotalEngagementPoints() const {
253 std::map<GURL, double> score_map = GetScoreMap(); 220 std::map<GURL, double> score_map = GetScoreMap();
254 221
255 double total_score = 0; 222 double total_score = 0;
256 for (const auto& value : score_map) 223 for (const auto& value : score_map)
257 total_score += value.second; 224 total_score += value.second;
258 225
259 return total_score; 226 return total_score;
260 } 227 }
261 228
262 SiteEngagementService::SiteEngagementService(Profile* profile, 229 SiteEngagementService::SiteEngagementService(Profile* profile,
263 std::unique_ptr<base::Clock> clock) 230 std::unique_ptr<base::Clock> clock)
264 : profile_(profile), clock_(std::move(clock)), weak_factory_(this) { 231 : profile_(profile), clock_(std::move(clock)), weak_factory_(this) {
265 // May be null in tests. 232 // May be null in tests.
266 history::HistoryService* history = HistoryServiceFactory::GetForProfile( 233 history::HistoryService* history = HistoryServiceFactory::GetForProfile(
267 profile, ServiceAccessType::IMPLICIT_ACCESS); 234 profile, ServiceAccessType::IMPLICIT_ACCESS);
268 if (history) 235 if (history)
269 history->AddObserver(this); 236 history->AddObserver(this);
270 } 237 }
271 238
272 void SiteEngagementService::AddPoints(const GURL& url, double points) { 239 void SiteEngagementService::AddPoints(const GURL& url, double points) {
273 HostContentSettingsMap* settings_map = 240 SiteEngagementScore score = CreateEngagementScore(url);
274 HostContentSettingsMapFactory::GetForProfile(profile_);
275 std::unique_ptr<base::DictionaryValue> score_dict =
276 GetScoreDictForOrigin(settings_map, url);
277 SiteEngagementScore score(clock_.get(), *score_dict);
278 241
279 score.AddPoints(points); 242 score.AddPoints(points);
280 if (score.UpdateScoreDict(score_dict.get())) { 243 score.Commit();
281 settings_map->SetWebsiteSettingDefaultScope(
282 url, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
283 score_dict.release());
284 }
285 } 244 }
286 245
287 void SiteEngagementService::AfterStartupTask() { 246 void SiteEngagementService::AfterStartupTask() {
288 CleanupEngagementScores(); 247 CleanupEngagementScores();
289 RecordMetrics(); 248 RecordMetrics();
290 } 249 }
291 250
292 void SiteEngagementService::CleanupEngagementScores() { 251 void SiteEngagementService::CleanupEngagementScores() {
293 HostContentSettingsMap* settings_map = 252 HostContentSettingsMap* settings_map =
294 HostContentSettingsMapFactory::GetForProfile(profile_); 253 HostContentSettingsMapFactory::GetForProfile(profile_);
295 std::unique_ptr<ContentSettingsForOneType> engagement_settings = 254 std::unique_ptr<ContentSettingsForOneType> engagement_settings =
296 GetEngagementContentSettings(settings_map); 255 GetEngagementContentSettings(settings_map);
297 256
298 for (const auto& site : *engagement_settings) { 257 for (const auto& site : *engagement_settings) {
299 GURL origin(site.primary_pattern.ToString()); 258 GURL origin(site.primary_pattern.ToString());
300 if (origin.is_valid()) { 259 if (origin.is_valid()) {
dominickn 2016/05/26 09:33:20 Strictly speaking this could be one if statement,
calamity 2016/05/31 05:44:15 Done.
301 std::unique_ptr<base::DictionaryValue> score_dict = 260 if (GetScore(origin) != 0)
302 GetScoreDictForOrigin(settings_map, origin);
303 SiteEngagementScore score(clock_.get(), *score_dict);
304 if (score.GetScore() != 0)
305 continue; 261 continue;
306 } 262 }
307 263
308 settings_map->SetWebsiteSettingDefaultScope( 264 settings_map->SetWebsiteSettingDefaultScope(
309 origin, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(), 265 origin, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
310 nullptr); 266 nullptr);
311 } 267 }
312 } 268 }
313 269
314 void SiteEngagementService::RecordMetrics() { 270 void SiteEngagementService::RecordMetrics() {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 361
406 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( 362 history::HistoryService* hs = HistoryServiceFactory::GetForProfile(
407 profile_, ServiceAccessType::EXPLICIT_ACCESS); 363 profile_, ServiceAccessType::EXPLICIT_ACCESS);
408 hs->GetCountsAndLastVisitForOrigins( 364 hs->GetCountsAndLastVisitForOrigins(
409 std::set<GURL>(origins.begin(), origins.end()), 365 std::set<GURL>(origins.begin(), origins.end()),
410 base::Bind( 366 base::Bind(
411 &SiteEngagementService::GetCountsAndLastVisitForOriginsComplete, 367 &SiteEngagementService::GetCountsAndLastVisitForOriginsComplete,
412 weak_factory_.GetWeakPtr(), hs, origins, expired)); 368 weak_factory_.GetWeakPtr(), hs, origins, expired));
413 } 369 }
414 370
371 const SiteEngagementScore SiteEngagementService::CreateEngagementScore(
372 const GURL& origin) const {
373 return SiteEngagementScore(
374 clock_.get(), origin,
375 HostContentSettingsMapFactory::GetForProfile(profile_));
376 }
377
378 SiteEngagementScore SiteEngagementService::CreateEngagementScore(
379 const GURL& origin) {
380 return SiteEngagementScore(
381 clock_.get(), origin,
382 HostContentSettingsMapFactory::GetForProfile(profile_));
383 }
384
415 int SiteEngagementService::OriginsWithMaxDailyEngagement() const { 385 int SiteEngagementService::OriginsWithMaxDailyEngagement() const {
416 HostContentSettingsMap* settings_map = 386 HostContentSettingsMap* settings_map =
417 HostContentSettingsMapFactory::GetForProfile(profile_); 387 HostContentSettingsMapFactory::GetForProfile(profile_);
418 std::unique_ptr<ContentSettingsForOneType> engagement_settings = 388 std::unique_ptr<ContentSettingsForOneType> engagement_settings =
419 GetEngagementContentSettings(settings_map); 389 GetEngagementContentSettings(settings_map);
420 390
421 int total_origins = 0; 391 int total_origins = 0;
422 392
423 // We cannot call GetScoreMap as we need the score objects, not raw scores. 393 // We cannot call GetScoreMap as we need the score objects, not raw scores.
424 for (const auto& site : *engagement_settings) { 394 for (const auto& site : *engagement_settings) {
425 GURL origin(site.primary_pattern.ToString()); 395 GURL origin(site.primary_pattern.ToString());
426 if (!origin.is_valid()) 396 if (!origin.is_valid())
427 continue; 397 continue;
428 398
429 std::unique_ptr<base::DictionaryValue> score_dict = 399 if (CreateEngagementScore(origin).MaxPointsPerDayAdded())
430 GetScoreDictForOrigin(settings_map, origin);
431 SiteEngagementScore score(clock_.get(), *score_dict);
432 if (score.MaxPointsPerDayAdded())
433 ++total_origins; 400 ++total_origins;
434 } 401 }
435 402
436 return total_origins; 403 return total_origins;
437 } 404 }
438 405
439 int SiteEngagementService::OriginsWithMaxEngagement( 406 int SiteEngagementService::OriginsWithMaxEngagement(
440 const std::map<GURL, double>& score_map) const { 407 const std::map<GURL, double>& score_map) const {
441 int total_origins = 0; 408 int total_origins = 0;
442 409
(...skipping 12 matching lines...) Expand all
455 422
456 // The most in-the-past option in the Clear Browsing Dialog aside from "all 423 // The most in-the-past option in the Clear Browsing Dialog aside from "all
457 // time" is 4 weeks ago. Set the last updated date to 4 weeks ago for origins 424 // time" is 4 weeks ago. Set the last updated date to 4 weeks ago for origins
458 // where we can't find a valid last visit date. 425 // where we can't find a valid last visit date.
459 base::Time now = clock_->Now(); 426 base::Time now = clock_->Now();
460 base::Time four_weeks_ago = 427 base::Time four_weeks_ago =
461 now - base::TimeDelta::FromDays(FOUR_WEEKS_IN_DAYS); 428 now - base::TimeDelta::FromDays(FOUR_WEEKS_IN_DAYS);
462 429
463 for (const auto& origin_to_count : remaining_origins) { 430 for (const auto& origin_to_count : remaining_origins) {
464 GURL origin = origin_to_count.first; 431 GURL origin = origin_to_count.first;
432 // It appears that the history service occasionally sends bad URLs to us.
433 // See crbug.com/612881.
434 if (!origin.is_valid())
435 continue;
436
465 int remaining = origin_to_count.second.first; 437 int remaining = origin_to_count.second.first;
466 base::Time last_visit = origin_to_count.second.second; 438 base::Time last_visit = origin_to_count.second.second;
467 int deleted = deleted_origins.count(origin); 439 int deleted = deleted_origins.count(origin);
468 440
469 // Do not update engagement scores if the deletion was an expiry, but the 441 // Do not update engagement scores if the deletion was an expiry, but the
470 // URL still has entries in history. 442 // URL still has entries in history.
471 if ((expired && remaining != 0) || deleted == 0) 443 if ((expired && remaining != 0) || deleted == 0)
472 continue; 444 continue;
473 445
474 // Remove engagement proportional to the urls expired from the origin's 446 // Remove engagement proportional to the urls expired from the origin's
(...skipping 14 matching lines...) Expand all
489 // reduced value rather than being decayed once here, and then once again 461 // reduced value rather than being decayed once here, and then once again
490 // when it is next accessed. 462 // when it is next accessed.
491 int undecay = 0; 463 int undecay = 0;
492 int days_since_engagement = (now - last_visit).InDays(); 464 int days_since_engagement = (now - last_visit).InDays();
493 if (days_since_engagement > 0) { 465 if (days_since_engagement > 0) {
494 int periods = days_since_engagement / 466 int periods = days_since_engagement /
495 SiteEngagementScore::GetDecayPeriodInDays(); 467 SiteEngagementScore::GetDecayPeriodInDays();
496 undecay = periods * SiteEngagementScore::GetDecayPoints(); 468 undecay = periods * SiteEngagementScore::GetDecayPoints();
497 } 469 }
498 470
499 double score = 471 SiteEngagementScore engagement_score = CreateEngagementScore(origin);
500 std::min(SiteEngagementScore::kMaxPoints, 472
501 (proportion_remaining * GetScore(origin)) + undecay); 473 double score = std::min(
502 ResetScoreAndAccessTimesForURL(origin, score, &last_visit); 474 SiteEngagementScore::kMaxPoints,
475 (proportion_remaining * engagement_score.GetScore()) + undecay);
476 engagement_score.Reset(score, last_visit);
477 if (!engagement_score.last_shortcut_launch_time().is_null()
478 && engagement_score.last_shortcut_launch_time() > last_visit) {
479 engagement_score.set_last_shortcut_launch_time(last_visit);
480 }
481
482 engagement_score.Commit();
503 } 483 }
504 } 484 }
505
506 void SiteEngagementService::ResetScoreAndAccessTimesForURL(
507 const GURL& url, double score, const base::Time* updated_time) {
508 // It appears that the history service occassionally sends bad URLs to us.
509 // See crbug.com/612881.
510 if (!url.is_valid())
511 return;
512
513 DCHECK_GE(score, 0);
514 DCHECK_LE(score, SiteEngagementScore::kMaxPoints);
515
516 HostContentSettingsMap* settings_map =
517 HostContentSettingsMapFactory::GetForProfile(profile_);
518 std::unique_ptr<base::DictionaryValue> score_dict =
519 GetScoreDictForOrigin(settings_map, url);
520 SiteEngagementScore engagement_score(clock_.get(), *score_dict);
521
522 engagement_score.Reset(score, updated_time);
523 if (score == 0) {
524 settings_map->SetWebsiteSettingDefaultScope(
525 url, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
526 nullptr);
527 return;
528 }
529
530 if (engagement_score.UpdateScoreDict(score_dict.get())) {
531 settings_map->SetWebsiteSettingDefaultScope(
532 url, GURL(), CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
533 score_dict.release());
534 }
535 }
OLDNEW
« no previous file with comments | « chrome/browser/engagement/site_engagement_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698