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

Side by Side Diff: chrome/browser/banners/app_banner_settings_helper.cc

Issue 2024953005: Allow app banners to be triggered by increases in site engagement. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@site-engagement-callback
Patch Set: Address reviewer comments. Rebase Created 4 years, 5 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/banners/app_banner_settings_helper.h" 5 #include "chrome/browser/banners/app_banner_settings_helper.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
11 #include <utility> 11 #include <utility>
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_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
18 #include "chrome/browser/banners/app_banner_data_fetcher.h" 18 #include "chrome/browser/banners/app_banner_data_fetcher.h"
19 #include "chrome/browser/banners/app_banner_metrics.h" 19 #include "chrome/browser/banners/app_banner_metrics.h"
20 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 21 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
22 #include "chrome/browser/engagement/site_engagement_service.h"
23 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/common/chrome_switches.h" 23 #include "chrome/common/chrome_switches.h"
25 #include "components/content_settings/core/browser/host_content_settings_map.h" 24 #include "components/content_settings/core/browser/host_content_settings_map.h"
26 #include "components/content_settings/core/common/content_settings_pattern.h" 25 #include "components/content_settings/core/common/content_settings_pattern.h"
27 #include "components/rappor/rappor_utils.h" 26 #include "components/rappor/rappor_utils.h"
28 #include "components/variations/variations_associated_data.h" 27 #include "components/variations/variations_associated_data.h"
29 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
30 #include "net/base/escape.h" 29 #include "net/base/escape.h"
31 #include "url/gurl.h" 30 #include "url/gurl.h"
32 31
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 // Keys to use when storing BannerEvent structs. 65 // Keys to use when storing BannerEvent structs.
67 const char kBannerTimeKey[] = "time"; 66 const char kBannerTimeKey[] = "time";
68 const char kBannerEngagementKey[] = "engagement"; 67 const char kBannerEngagementKey[] = "engagement";
69 68
70 // Keys to use when querying the variations params. 69 // Keys to use when querying the variations params.
71 const char kBannerParamsKey[] = "AppBannerTriggering"; 70 const char kBannerParamsKey[] = "AppBannerTriggering";
72 const char kBannerParamsDirectKey[] = "direct"; 71 const char kBannerParamsDirectKey[] = "direct";
73 const char kBannerParamsIndirectKey[] = "indirect"; 72 const char kBannerParamsIndirectKey[] = "indirect";
74 const char kBannerParamsTotalKey[] = "total"; 73 const char kBannerParamsTotalKey[] = "total";
75 const char kBannerParamsMinutesKey[] = "minutes"; 74 const char kBannerParamsMinutesKey[] = "minutes";
76 const char kBannerSiteEngagementParamsKey[] = "app_banner_triggering"; 75 const char kBannerSiteEngagementParamsKey[] = "use_site_engagement";
77 const char kBannerSiteEngagementParamsTotalKey[] =
78 "app_banner_triggering_total";
79 76
80 // Engagement weight assigned to direct and indirect navigations. 77 // Engagement weight assigned to direct and indirect navigations.
81 // By default, a direct navigation is a page visit via ui::PAGE_TRANSITION_TYPED 78 // By default, a direct navigation is a page visit via ui::PAGE_TRANSITION_TYPED
82 // or ui::PAGE_TRANSITION_GENERATED. 79 // or ui::PAGE_TRANSITION_GENERATED.
83 double gDirectNavigationEngagement = kDefaultDirectNavigationEngagement; 80 double gDirectNavigationEngagement = kDefaultDirectNavigationEngagement;
84 double gIndirectNavigationEnagagement = kDefaultIndirectNavigationEngagement; 81 double gIndirectNavigationEnagagement = kDefaultIndirectNavigationEngagement;
85 82
86 // Number of minutes between visits that will trigger a could show banner event. 83 // Number of minutes between visits that will trigger a could show banner event.
87 // Defaults to the number of minutes in a day. 84 // Defaults to the number of minutes in a day.
88 unsigned int gMinimumMinutesBetweenVisits = kNumberOfMinutesInADay; 85 unsigned int gMinimumMinutesBetweenVisits = kNumberOfMinutesInADay;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 return gDirectNavigationEngagement; 126 return gDirectNavigationEngagement;
130 } else { 127 } else {
131 return gIndirectNavigationEnagagement; 128 return gIndirectNavigationEnagagement;
132 } 129 }
133 } 130 }
134 131
135 // Queries variations for the maximum site engagement score required to trigger 132 // Queries variations for the maximum site engagement score required to trigger
136 // the banner showing. 133 // the banner showing.
137 void UpdateSiteEngagementToTrigger() { 134 void UpdateSiteEngagementToTrigger() {
138 std::string total_param = variations::GetVariationParamValue( 135 std::string total_param = variations::GetVariationParamValue(
139 SiteEngagementService::kEngagementParams, 136 kBannerParamsKey, kBannerParamsTotalKey);
140 kBannerSiteEngagementParamsTotalKey);
141 137
142 if (!total_param.empty()) { 138 if (!total_param.empty()) {
143 double total_engagement = -1; 139 double total_engagement = -1;
144 140
145 if (base::StringToDouble(total_param, &total_engagement) && 141 if (base::StringToDouble(total_param, &total_engagement) &&
146 total_engagement > 0) { 142 total_engagement > 0) {
147 AppBannerSettingsHelper::SetTotalEngagementToTrigger(total_engagement); 143 AppBannerSettingsHelper::SetTotalEngagementToTrigger(total_engagement);
148 } 144 }
149 } 145 }
150 } 146 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 void UpdateMinutesBetweenVisits() { 182 void UpdateMinutesBetweenVisits() {
187 std::string param = variations::GetVariationParamValue( 183 std::string param = variations::GetVariationParamValue(
188 kBannerParamsKey, kBannerParamsMinutesKey); 184 kBannerParamsKey, kBannerParamsMinutesKey);
189 if (!param.empty()) { 185 if (!param.empty()) {
190 int minimum_minutes = 0; 186 int minimum_minutes = 0;
191 if (base::StringToInt(param, &minimum_minutes)) 187 if (base::StringToInt(param, &minimum_minutes))
192 AppBannerSettingsHelper::SetMinimumMinutesBetweenVisits(minimum_minutes); 188 AppBannerSettingsHelper::SetMinimumMinutesBetweenVisits(minimum_minutes);
193 } 189 }
194 } 190 }
195 191
196 // Returns the site engagement karma score for the given origin URL under the
197 // current profile.
198 double GetSiteEngagementScoreForOrigin(
199 content::WebContents* web_contents,
200 const GURL& origin_url) {
201 SiteEngagementService* service = SiteEngagementService::Get(
202 Profile::FromBrowserContext(web_contents->GetBrowserContext()));
203 return service ? service->GetScore(origin_url) : 0;
204 }
205
206 } // namespace 192 } // namespace
207 193
208 void AppBannerSettingsHelper::ClearHistoryForURLs( 194 void AppBannerSettingsHelper::ClearHistoryForURLs(
209 Profile* profile, 195 Profile* profile,
210 const std::set<GURL>& origin_urls) { 196 const std::set<GURL>& origin_urls) {
211 HostContentSettingsMap* settings = 197 HostContentSettingsMap* settings =
212 HostContentSettingsMapFactory::GetForProfile(profile); 198 HostContentSettingsMapFactory::GetForProfile(profile);
213 for (const GURL& origin_url : origin_urls) { 199 for (const GURL& origin_url : origin_urls) {
214 settings->SetWebsiteSettingDefaultScope(origin_url, GURL(), 200 settings->SetWebsiteSettingDefaultScope(origin_url, GURL(),
215 CONTENT_SETTINGS_TYPE_APP_BANNER, 201 CONTENT_SETTINGS_TYPE_APP_BANNER,
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 407
422 base::Time shown_time = 408 base::Time shown_time =
423 GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url, 409 GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url,
424 APP_BANNER_EVENT_DID_SHOW); 410 APP_BANNER_EVENT_DID_SHOW);
425 if (time - shown_time < 411 if (time - shown_time <
426 base::TimeDelta::FromDays(kMinimumDaysBetweenBannerShows)) { 412 base::TimeDelta::FromDays(kMinimumDaysBetweenBannerShows)) {
427 banners::TrackDisplayEvent(banners::DISPLAY_EVENT_IGNORED_PREVIOUSLY); 413 banners::TrackDisplayEvent(banners::DISPLAY_EVENT_IGNORED_PREVIOUSLY);
428 return false; 414 return false;
429 } 415 }
430 416
417 // If we have gotten this far and want to use site engagement, the banner flow
418 // was triggered by the site engagement service informing the banner manager
419 // that sufficient engagement has been accumulated. Hence there is no need to
420 // check the total amount of engagement.
421 // TODO(dominickn): just return true here and remove all of the following code
422 // in this method when app banners have fully migrated to using site
423 // engagement as a trigger condition. See crbug.com/616322.
424 if (ShouldUseSiteEngagementScore())
425 return true;
426
431 double total_engagement = 0; 427 double total_engagement = 0;
432 if (ShouldUseSiteEngagementScore()) { 428 std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents(
433 total_engagement = 429 web_contents, origin_url, package_name_or_start_url);
434 GetSiteEngagementScoreForOrigin(web_contents, origin_url);
435 } else {
436 std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents(
437 web_contents, origin_url, package_name_or_start_url);
438 430
439 for (const auto& event : could_show_events) 431 for (const auto& event : could_show_events)
440 total_engagement += event.engagement; 432 total_engagement += event.engagement;
441 }
442 433
443 if (total_engagement < gTotalEngagementToTrigger) { 434 if (!HasSufficientEngagement(total_engagement)) {
444 banners::TrackDisplayEvent(banners::DISPLAY_EVENT_NOT_VISITED_ENOUGH); 435 banners::TrackDisplayEvent(banners::DISPLAY_EVENT_NOT_VISITED_ENOUGH);
445 return false; 436 return false;
446 } 437 }
447 438
448 return true; 439 return true;
449 } 440 }
450 441
451 std::vector<AppBannerSettingsHelper::BannerEvent> 442 std::vector<AppBannerSettingsHelper::BannerEvent>
452 AppBannerSettingsHelper::GetCouldShowBannerEvents( 443 AppBannerSettingsHelper::GetCouldShowBannerEvents(
453 content::WebContents* web_contents, 444 content::WebContents* web_contents,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 return base::Time(); 508 return base::Time();
518 509
519 std::string event_key(kBannerEventKeys[event]); 510 std::string event_key(kBannerEventKeys[event]);
520 double internal_time; 511 double internal_time;
521 if (!app_dict->GetDouble(event_key, &internal_time)) 512 if (!app_dict->GetDouble(event_key, &internal_time))
522 return base::Time(); 513 return base::Time();
523 514
524 return base::Time::FromInternalValue(internal_time); 515 return base::Time::FromInternalValue(internal_time);
525 } 516 }
526 517
518 bool AppBannerSettingsHelper::HasSufficientEngagement(double total_engagement) {
519 return (base::CommandLine::ForCurrentProcess()->HasSwitch(
520 switches::kBypassAppBannerEngagementChecks)) ||
521 (total_engagement >= gTotalEngagementToTrigger);
522 }
523
527 void AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( 524 void AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow(
528 content::WebContents* web_contents, 525 content::WebContents* web_contents,
529 const GURL& origin_url, 526 const GURL& origin_url,
530 const std::string& package_name_or_start_url, 527 const std::string& package_name_or_start_url,
531 base::Time time) { 528 base::Time time) {
532 std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents( 529 std::vector<BannerEvent> could_show_events = GetCouldShowBannerEvents(
533 web_contents, origin_url, package_name_or_start_url); 530 web_contents, origin_url, package_name_or_start_url);
534 531
535 int minutes = 0; 532 int minutes = 0;
536 if (could_show_events.size()) 533 if (could_show_events.size())
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 UpdateMinutesBetweenVisits(); 595 UpdateMinutesBetweenVisits();
599 } 596 }
600 } 597 }
601 598
602 bool AppBannerSettingsHelper::ShouldUseSiteEngagementScore() { 599 bool AppBannerSettingsHelper::ShouldUseSiteEngagementScore() {
603 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 600 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
604 switches::kEnableSiteEngagementAppBanner)) { 601 switches::kEnableSiteEngagementAppBanner)) {
605 return true; 602 return true;
606 } 603 }
607 604
608 // This experiment is controlled under the same key as the broader site 605 // Assume any value which is not "0" or "false" indicates that we should use
609 // engagement experiment rather than the banner experiment. This avoids cross 606 // site engagement.
610 // pollution with other site engagement experiments. However, this experiment
611 // must only be active when there is one singular group under the banner
612 // experiment, otherwise the banner and site engagement banner experiments
613 // will conflict.
614 //
615 // Making the experiment active when a variations key is present allows us
616 // to have experiments which enable multiple features under site engagement.
617 std::string param = variations::GetVariationParamValue( 607 std::string param = variations::GetVariationParamValue(
618 SiteEngagementService::kEngagementParams, kBannerSiteEngagementParamsKey); 608 kBannerParamsKey, kBannerSiteEngagementParamsKey);
619 return !param.empty(); 609
610 return (!param.empty() && param != "0" && param != "false");
620 } 611 }
OLDNEW
« no previous file with comments | « chrome/browser/banners/app_banner_settings_helper.h ('k') | chrome/browser/banners/app_banner_settings_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698