Commit 4a144829 authored by benwells's avatar benwells Committed by Commit bot

Use heuristic to work out when to prompt for app install banners.

The heuristic ensures that the user is not prompted too much, and is only
prompted after showing sustained engagement with a site.

BUG=452825

Review URL: https://codereview.chromium.org/886643003

Cr-Commit-Position: refs/heads/master@{#315055}
parent f14f8f0e
...@@ -69,7 +69,9 @@ void AppBannerManager::BlockBanner(JNIEnv* env, ...@@ -69,7 +69,9 @@ void AppBannerManager::BlockBanner(JNIEnv* env,
GURL url(ConvertJavaStringToUTF8(env, jurl)); GURL url(ConvertJavaStringToUTF8(env, jurl));
std::string package_name = ConvertJavaStringToUTF8(env, jpackage); std::string package_name = ConvertJavaStringToUTF8(env, jpackage);
AppBannerSettingsHelper::Block(web_contents(), url, package_name); AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, package_name,
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now());
} }
void AppBannerManager::Block() const { void AppBannerManager::Block() const {
...@@ -77,9 +79,10 @@ void AppBannerManager::Block() const { ...@@ -77,9 +79,10 @@ void AppBannerManager::Block() const {
return; return;
if (!web_app_data_.IsEmpty()) { if (!web_app_data_.IsEmpty()) {
AppBannerSettingsHelper::Block(web_contents(), AppBannerSettingsHelper::RecordBannerEvent(
web_contents()->GetURL(), web_contents(), web_contents()->GetURL(),
web_app_data_.start_url.spec()); web_app_data_.start_url.spec(),
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now());
} }
} }
...@@ -92,6 +95,12 @@ bool AppBannerManager::OnButtonClicked() const { ...@@ -92,6 +95,12 @@ bool AppBannerManager::OnButtonClicked() const {
return true; return true;
if (!web_app_data_.IsEmpty()) { if (!web_app_data_.IsEmpty()) {
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), web_contents()->GetURL(),
web_app_data_.start_url.spec(),
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
base::Time::Now());
InstallManifestApp(web_app_data_, *app_icon_.get()); InstallManifestApp(web_app_data_, *app_icon_.get());
return true; return true;
} }
...@@ -183,10 +192,35 @@ void AppBannerManager::OnDidCheckHasServiceWorker(bool has_service_worker) { ...@@ -183,10 +192,35 @@ void AppBannerManager::OnDidCheckHasServiceWorker(bool has_service_worker) {
if (icon_url.is_empty()) if (icon_url.is_empty())
return; return;
RecordCouldShowBanner(web_app_data_.start_url.spec());
if (!CheckIfShouldShow(web_app_data_.start_url.spec()))
return;
FetchIcon(icon_url); FetchIcon(icon_url);
} }
} }
void AppBannerManager::RecordCouldShowBanner(
const std::string& package_or_start_url) {
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), validated_url_, package_or_start_url,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, base::Time::Now());
}
bool AppBannerManager::CheckIfShouldShow(
const std::string& package_or_start_url) {
if (!AppBannerSettingsHelper::ShouldShowBanner(web_contents(), validated_url_,
package_or_start_url,
base::Time::Now())) {
return false;
}
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), validated_url_, package_or_start_url,
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW, base::Time::Now());
return true;
}
bool AppBannerManager::OnMessageReceived(const IPC::Message& message) { bool AppBannerManager::OnMessageReceived(const IPC::Message& message) {
bool handled = true; bool handled = true;
IPC_BEGIN_MESSAGE_MAP(AppBannerManager, message) IPC_BEGIN_MESSAGE_MAP(AppBannerManager, message)
...@@ -237,11 +271,9 @@ void AppBannerManager::OnDidRetrieveMetaTagContent( ...@@ -237,11 +271,9 @@ void AppBannerManager::OnDidRetrieveMetaTagContent(
banners::TrackDisplayEvent(DISPLAY_BANNER_REQUESTED); banners::TrackDisplayEvent(DISPLAY_BANNER_REQUESTED);
if (!AppBannerSettingsHelper::IsAllowed(web_contents(), RecordCouldShowBanner(tag_content);
expected_url, if (!CheckIfShouldShow(tag_content))
tag_content)) {
return; return;
}
// Send the info to the Java side to get info about the app. // Send the info to the Java side to get info about the app.
JNIEnv* env = base::android::AttachCurrentThread(); JNIEnv* env = base::android::AttachCurrentThread();
......
...@@ -138,6 +138,13 @@ class AppBannerManager : public chrome::BitmapFetcherDelegate, ...@@ -138,6 +138,13 @@ class AppBannerManager : public chrome::BitmapFetcherDelegate,
// Called when the result of the CheckHasServiceWorker query has completed. // Called when the result of the CheckHasServiceWorker query has completed.
void OnDidCheckHasServiceWorker(bool has_service_worker); void OnDidCheckHasServiceWorker(bool has_service_worker);
// Record that the banner could be shown at this point, if the triggering
// heuristic allowed.
void RecordCouldShowBanner(const std::string& package_or_start_url);
// Check if the banner should be shown.
bool CheckIfShouldShow(const std::string& package_or_start_url);
// Fetches the icon for an app. // Fetches the icon for an app.
scoped_ptr<chrome::BitmapFetcher> fetcher_; scoped_ptr<chrome::BitmapFetcher> fetcher_;
GURL validated_url_; GURL validated_url_;
......
...@@ -23,21 +23,28 @@ const size_t kMaxAppsPerSite = 3; ...@@ -23,21 +23,28 @@ const size_t kMaxAppsPerSite = 3;
// Oldest could show banner event we care about, in days. // Oldest could show banner event we care about, in days.
const unsigned int kOldestCouldShowBannerEventInDays = 14; const unsigned int kOldestCouldShowBannerEventInDays = 14;
// Dictionary key to use for the 'could show banner' events. // Number of times that the banner could have been shown before the banner will
const char kCouldShowBannerEventsKey[] = "couldShowBannerEvents"; // actually be triggered.
const unsigned int kCouldShowEventsToTrigger = 2;
// Number of days that showing the banner will prevent it being seen again for.
const unsigned int kMinimumDaysBetweenBannerShows = 60;
// Number of days that the banner being blocked will prevent it being seen again
// for.
const unsigned int kMinimumBannerBlockedToBannerShown = 90;
// Dictionary keys to use for the events.
const char* kBannerEventKeys[] = {
"couldShowBannerEvents",
"didShowBannerEvent",
"didBlockBannerEvent",
"didAddToHomescreenEvent",
};
// Dictionary key to use whether the banner has been blocked. // Dictionary key to use whether the banner has been blocked.
const char kHasBlockedKey[] = "hasBlocked"; const char kHasBlockedKey[] = "hasBlocked";
base::Time DateFromTime(base::Time time) {
base::Time::Exploded exploded;
time.LocalExplode(&exploded);
exploded.hour = 0;
exploded.minute = 0;
exploded.second = 0;
return base::Time::FromLocalExploded(exploded);
}
scoped_ptr<base::DictionaryValue> GetOriginDict( scoped_ptr<base::DictionaryValue> GetOriginDict(
HostContentSettingsMap* settings, HostContentSettingsMap* settings,
const GURL& origin_url) { const GURL& origin_url) {
...@@ -72,10 +79,11 @@ base::DictionaryValue* GetAppDict(base::DictionaryValue* origin_dict, ...@@ -72,10 +79,11 @@ base::DictionaryValue* GetAppDict(base::DictionaryValue* origin_dict,
} // namespace } // namespace
void AppBannerSettingsHelper::RecordCouldShowBannerEvent( void AppBannerSettingsHelper::RecordBannerEvent(
content::WebContents* web_contents, content::WebContents* web_contents,
const GURL& origin_url, const GURL& origin_url,
const std::string& package_name_or_start_url, const std::string& package_name_or_start_url,
AppBannerEvent event,
base::Time time) { base::Time time) {
Profile* profile = Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext()); Profile::FromBrowserContext(web_contents->GetBrowserContext());
...@@ -99,22 +107,25 @@ void AppBannerSettingsHelper::RecordCouldShowBannerEvent( ...@@ -99,22 +107,25 @@ void AppBannerSettingsHelper::RecordCouldShowBannerEvent(
if (!app_dict) if (!app_dict)
return; return;
std::string event_key(kBannerEventKeys[event]);
if (event == APP_BANNER_EVENT_COULD_SHOW) {
base::ListValue* could_show_list = nullptr; base::ListValue* could_show_list = nullptr;
if (!app_dict->GetList(kCouldShowBannerEventsKey, &could_show_list)) { if (!app_dict->GetList(event_key, &could_show_list)) {
could_show_list = new base::ListValue(); could_show_list = new base::ListValue();
app_dict->Set(kCouldShowBannerEventsKey, make_scoped_ptr(could_show_list)); app_dict->Set(event_key, make_scoped_ptr(could_show_list));
} }
// Trim any items that are older than we should care about. For comparisons // Trim any items that are older than we should care about. For comparisons
// the times are converted to local dates. // the times are converted to local dates.
base::Time date = DateFromTime(time); base::Time date = time.LocalMidnight();
base::ValueVector::iterator it = could_show_list->begin(); base::ValueVector::iterator it = could_show_list->begin();
while (it != could_show_list->end()) { while (it != could_show_list->end()) {
if ((*it)->IsType(base::Value::TYPE_DOUBLE)) { if ((*it)->IsType(base::Value::TYPE_DOUBLE)) {
double internal_date; double internal_date;
(*it)->GetAsDouble(&internal_date); (*it)->GetAsDouble(&internal_date);
base::Time other_date = base::Time other_date =
DateFromTime(base::Time::FromInternalValue(internal_date)); base::Time::FromInternalValue(internal_date).LocalMidnight();
// This date has already been added. Don't add the date again, and don't // This date has already been added. Don't add the date again, and don't
// bother trimming values as it will have been done the first time the // bother trimming values as it will have been done the first time the
// date was added (unless the local date has changed, which we can live // date was added (unless the local date has changed, which we can live
...@@ -138,11 +149,50 @@ void AppBannerSettingsHelper::RecordCouldShowBannerEvent( ...@@ -138,11 +149,50 @@ void AppBannerSettingsHelper::RecordCouldShowBannerEvent(
// Dates are stored in their raw form (i.e. not local dates) to be resilient // Dates are stored in their raw form (i.e. not local dates) to be resilient
// to time zone changes. // to time zone changes.
could_show_list->AppendDouble(time.ToInternalValue()); could_show_list->AppendDouble(time.ToInternalValue());
} else {
app_dict->SetDouble(event_key, time.ToInternalValue());
}
settings->SetWebsiteSetting(pattern, ContentSettingsPattern::Wildcard(), settings->SetWebsiteSetting(pattern, ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_APP_BANNER, std::string(), CONTENT_SETTINGS_TYPE_APP_BANNER, std::string(),
origin_dict.release()); origin_dict.release());
} }
bool AppBannerSettingsHelper::ShouldShowBanner(
content::WebContents* web_contents,
const GURL& origin_url,
const std::string& package_name_or_start_url,
base::Time time) {
// Don't show if it has been added to the homescreen.
base::Time added_time =
GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url,
APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN);
if (!added_time.is_null())
return false;
base::Time blocked_time =
GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url,
APP_BANNER_EVENT_DID_BLOCK);
// Null times are in the distant past, so the delta between real times and
// null events will always be greater than the limits.
if (time - blocked_time <
base::TimeDelta::FromDays(kMinimumBannerBlockedToBannerShown)) {
return false;
}
base::Time shown_time =
GetSingleBannerEvent(web_contents, origin_url, package_name_or_start_url,
APP_BANNER_EVENT_DID_SHOW);
if (time - shown_time <
base::TimeDelta::FromDays(kMinimumDaysBetweenBannerShows)) {
return false;
}
std::vector<base::Time> could_show_events = GetCouldShowBannerEvents(
web_contents, origin_url, package_name_or_start_url);
return could_show_events.size() >= kCouldShowEventsToTrigger;
}
std::vector<base::Time> AppBannerSettingsHelper::GetCouldShowBannerEvents( std::vector<base::Time> AppBannerSettingsHelper::GetCouldShowBannerEvents(
content::WebContents* web_contents, content::WebContents* web_contents,
const GURL& origin_url, const GURL& origin_url,
...@@ -165,8 +215,9 @@ std::vector<base::Time> AppBannerSettingsHelper::GetCouldShowBannerEvents( ...@@ -165,8 +215,9 @@ std::vector<base::Time> AppBannerSettingsHelper::GetCouldShowBannerEvents(
if (!app_dict) if (!app_dict)
return result; return result;
std::string event_key(kBannerEventKeys[APP_BANNER_EVENT_COULD_SHOW]);
base::ListValue* could_show_list = nullptr; base::ListValue* could_show_list = nullptr;
if (!app_dict->GetList(kCouldShowBannerEventsKey, &could_show_list)) if (!app_dict->GetList(event_key, &could_show_list))
return result; return result;
for (auto value : *could_show_list) { for (auto value : *could_show_list) {
...@@ -181,6 +232,39 @@ std::vector<base::Time> AppBannerSettingsHelper::GetCouldShowBannerEvents( ...@@ -181,6 +232,39 @@ std::vector<base::Time> AppBannerSettingsHelper::GetCouldShowBannerEvents(
return result; return result;
} }
base::Time AppBannerSettingsHelper::GetSingleBannerEvent(
content::WebContents* web_contents,
const GURL& origin_url,
const std::string& package_name_or_start_url,
AppBannerEvent event) {
DCHECK(event != APP_BANNER_EVENT_COULD_SHOW);
DCHECK(event < APP_BANNER_EVENT_NUM_EVENTS);
if (package_name_or_start_url.empty())
return base::Time();
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
scoped_ptr<base::DictionaryValue> origin_dict =
GetOriginDict(settings, origin_url);
if (!origin_dict)
return base::Time();
base::DictionaryValue* app_dict =
GetAppDict(origin_dict.get(), package_name_or_start_url);
if (!app_dict)
return base::Time();
std::string event_key(kBannerEventKeys[event]);
double internal_time;
if (!app_dict->GetDouble(event_key, &internal_time))
return base::Time();
return base::Time::FromInternalValue(internal_time);
}
bool AppBannerSettingsHelper::IsAllowed( bool AppBannerSettingsHelper::IsAllowed(
content::WebContents* web_contents, content::WebContents* web_contents,
const GURL& origin_url, const GURL& origin_url,
......
...@@ -17,37 +17,62 @@ class WebContents; ...@@ -17,37 +17,62 @@ class WebContents;
class GURL; class GURL;
// Utility class for reading and updating ContentSettings for app banners. // Utility class to record banner events for the given package or start url.
//
// These events are used to decide when banners should be shown, using a
// heuristic based on how many different days in a recent period of time (for
// example the past two weeks) the banner could have been shown, when it was
// last shown, when it was last blocked, and when it was last installed (for
// ServiceWorker style apps - native apps can query whether the app was
// installed directly).
//
// The desired effect is to have banners appear once a user has demonstrated
// an ongoing relationship with the app, and not to pester the user too much.
//
// For most events only the last event is recorded. The exception are the
// could show events. For these a list of the events is maintained. At most
// one event is stored per day, and events outside the window the heuristic
// uses are discarded. Local times are used to enforce these rules, to ensure
// what we count as a day matches what the user perceives to be days.
class AppBannerSettingsHelper { class AppBannerSettingsHelper {
public: public:
// TODO(benwells): Use this method to implement smarter triggering logic. enum AppBannerEvent {
// See http://crbug.com/452825. APP_BANNER_EVENT_COULD_SHOW,
// Records that a banner could have been shown for the given package or start APP_BANNER_EVENT_DID_SHOW,
// url. APP_BANNER_EVENT_DID_BLOCK,
// APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
// These events are used to decide when banners should be shown, using a APP_BANNER_EVENT_NUM_EVENTS,
// heuristic based on how many different days in a recent period of time (for };
// example the past two weeks) the banner could have been shown. The desired
// effect is to have banners appear once a user has demonstrated an ongoing static void RecordBannerEvent(content::WebContents* web_contents,
// relationship with the app. const GURL& origin_url,
// const std::string& package_name_or_start_url,
// At most one event is stored per day, and events outside the window the AppBannerEvent event,
// heuristic uses are discarded. Local times are used to enforce these rules, base::Time time);
// to ensure what we count as a day matches what the user perceives to be
// days. // Determine if the banner should be shown, given the recorded events for the
static void RecordCouldShowBannerEvent( // supplied app.
content::WebContents* web_contents, static bool ShouldShowBanner(content::WebContents* web_contents,
const GURL& origin_url, const GURL& origin_url,
const std::string& package_name_or_start_url, const std::string& package_name_or_start_url,
base::Time time); base::Time time);
// Gets the could have been shown events that are stored for the given package // Gets the could have been shown events that are stored for the given package
// or start url. This is only used for testing. // or start url. This is only exposed for testing.
static std::vector<base::Time> GetCouldShowBannerEvents( static std::vector<base::Time> GetCouldShowBannerEvents(
content::WebContents* web_contents, content::WebContents* web_contents,
const GURL& origin_url, const GURL& origin_url,
const std::string& package_name_or_start_url); const std::string& package_name_or_start_url);
// Get the recorded event for an event type that only records the last event.
// Should not be used with APP_BANNER_EVENT_COULD_SHOW. This is only exposed
// for testing.
static base::Time GetSingleBannerEvent(
content::WebContents* web_contents,
const GURL& origin_url,
const std::string& package_name_or_start_url,
AppBannerEvent event);
// Checks if a URL is allowed to show a banner for the given package or start // Checks if a URL is allowed to show a banner for the given package or start
// url. // url.
static bool IsAllowed(content::WebContents* web_contents, static bool IsAllowed(content::WebContents* web_contents,
......
...@@ -12,6 +12,20 @@ namespace { ...@@ -12,6 +12,20 @@ namespace {
const char kTestURL[] = "http://www.google.com"; const char kTestURL[] = "http://www.google.com";
const char kTestPackageName[] = "test.package"; const char kTestPackageName[] = "test.package";
base::Time GetReferenceTime() {
base::Time::Exploded exploded_reference_time;
exploded_reference_time.year = 2015;
exploded_reference_time.month = 1;
exploded_reference_time.day_of_month = 30;
exploded_reference_time.day_of_week = 5;
exploded_reference_time.hour = 11;
exploded_reference_time.minute = 0;
exploded_reference_time.second = 0;
exploded_reference_time.millisecond = 0;
return base::Time::FromLocalExploded(exploded_reference_time);
}
bool IsWithinDay(base::Time time1, base::Time time2) { bool IsWithinDay(base::Time time1, base::Time time2) {
return time1 - time2 < base::TimeDelta::FromDays(1) || return time1 - time2 < base::TimeDelta::FromDays(1) ||
time2 - time1 < base::TimeDelta::FromDays(1); time2 - time1 < base::TimeDelta::FromDays(1);
...@@ -45,26 +59,16 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) { ...@@ -45,26 +59,16 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) {
kTestPackageName); kTestPackageName);
EXPECT_TRUE(events.empty()); EXPECT_TRUE(events.empty());
base::Time::Exploded exploded_reference_time; base::Time reference_time = GetReferenceTime();
exploded_reference_time.year = 2015;
exploded_reference_time.month = 1;
exploded_reference_time.day_of_month = 30;
exploded_reference_time.day_of_week = 5;
exploded_reference_time.hour = 11;
exploded_reference_time.minute = 0;
exploded_reference_time.second = 0;
exploded_reference_time.millisecond = 0;
base::Time reference_time =
base::Time::FromLocalExploded(exploded_reference_time);
base::Time same_day = reference_time + base::TimeDelta::FromHours(2); base::Time same_day = reference_time + base::TimeDelta::FromHours(2);
base::Time three_days_prior = reference_time - base::TimeDelta::FromDays(3); base::Time three_days_prior = reference_time - base::TimeDelta::FromDays(3);
base::Time previous_fortnight = base::Time previous_fortnight =
reference_time - base::TimeDelta::FromDays(14); reference_time - base::TimeDelta::FromDays(14);
// Test adding the first date. // Test adding the first date.
AppBannerSettingsHelper::RecordCouldShowBannerEvent( AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName, previous_fortnight); web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, previous_fortnight);
// It should be the only date recorded. // It should be the only date recorded.
events = AppBannerSettingsHelper::GetCouldShowBannerEvents( events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
...@@ -73,8 +77,9 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) { ...@@ -73,8 +77,9 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) {
EXPECT_TRUE(IsWithinDay(events[0], previous_fortnight)); EXPECT_TRUE(IsWithinDay(events[0], previous_fortnight));
// Now add the next date. // Now add the next date.
AppBannerSettingsHelper::RecordCouldShowBannerEvent( AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName, three_days_prior); web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, three_days_prior);
// Now there should be two days. // Now there should be two days.
events = AppBannerSettingsHelper::GetCouldShowBannerEvents( events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
...@@ -84,8 +89,9 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) { ...@@ -84,8 +89,9 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) {
EXPECT_TRUE(IsWithinDay(events[1], three_days_prior)); EXPECT_TRUE(IsWithinDay(events[1], three_days_prior));
// Now add the reference date. // Now add the reference date.
AppBannerSettingsHelper::RecordCouldShowBannerEvent( AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName, reference_time); web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time);
// Now there should still be two days, but the first date should have been // Now there should still be two days, but the first date should have been
// removed. // removed.
...@@ -96,8 +102,9 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) { ...@@ -96,8 +102,9 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) {
EXPECT_TRUE(IsWithinDay(events[1], reference_time)); EXPECT_TRUE(IsWithinDay(events[1], reference_time));
// Now add the the other day on the reference date. // Now add the the other day on the reference date.
AppBannerSettingsHelper::RecordCouldShowBannerEvent( AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName, same_day); web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, same_day);
// Now there should still be the same two days. // Now there should still be the same two days.
events = AppBannerSettingsHelper::GetCouldShowBannerEvents( events = AppBannerSettingsHelper::GetCouldShowBannerEvents(
...@@ -106,3 +113,180 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) { ...@@ -106,3 +113,180 @@ TEST_F(AppBannerSettingsHelperTest, CouldShowEvents) {
EXPECT_TRUE(IsWithinDay(events[0], three_days_prior)); EXPECT_TRUE(IsWithinDay(events[0], three_days_prior));
EXPECT_TRUE(IsWithinDay(events[1], reference_time)); EXPECT_TRUE(IsWithinDay(events[1], reference_time));
} }
TEST_F(AppBannerSettingsHelperTest, SingleEvents) {
GURL url(kTestURL);
NavigateAndCommit(url);
base::Time reference_time = GetReferenceTime();
base::Time other_time = reference_time - base::TimeDelta::FromDays(3);
for (int event = AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW;
event < AppBannerSettingsHelper::APP_BANNER_EVENT_NUM_EVENTS; ++event) {
// Check that by default, there is no event.
base::Time event_time = AppBannerSettingsHelper::GetSingleBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::AppBannerEvent(event));
EXPECT_TRUE(event_time.is_null());
// Check that a time can be recorded.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::AppBannerEvent(event), reference_time);
event_time = AppBannerSettingsHelper::GetSingleBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::AppBannerEvent(event));
EXPECT_EQ(reference_time, event_time);
// Check that another time can be recorded.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::AppBannerEvent(event), other_time);
event_time = AppBannerSettingsHelper::GetSingleBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::AppBannerEvent(event));
EXPECT_EQ(other_time, event_time);
}
}
TEST_F(AppBannerSettingsHelperTest, ShouldShowFromEngagement) {
GURL url(kTestURL);
NavigateAndCommit(url);
base::Time reference_time = GetReferenceTime();
base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366);
// By default the banner should not be shown.
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Visit the site once, it still should not be shown.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_year_ago);
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Visit the site again after a long delay, it still should not be shown.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_day_ago);
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Visit the site again; now it should be shown.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time);
EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
}
TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterBlocking) {
GURL url(kTestURL);
NavigateAndCommit(url);
base::Time reference_time = GetReferenceTime();
base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
base::Time two_months_ago = reference_time - base::TimeDelta::FromDays(60);
base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366);
// By default the banner should not be shown.
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Record events such that the banner should show.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_day_ago);
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time);
EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Block the site a long time ago. It should still be shown.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, one_year_ago);
EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Block the site more recently. Now it should not be shown.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, two_months_ago);
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
}
TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterShowing) {
GURL url(kTestURL);
NavigateAndCommit(url);
base::Time reference_time = GetReferenceTime();
base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
base::Time three_weeks_ago = reference_time - base::TimeDelta::FromDays(21);
base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366);
// By default the banner should not be shown.
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Record events such that the banner should show.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_day_ago);
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time);
EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Show the banner a long time ago. It should still be shown.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW, one_year_ago);
EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Show the site more recently. Now it should not be shown.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW, three_weeks_ago);
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
}
TEST_F(AppBannerSettingsHelperTest, ShouldNotShowAfterAdding) {
GURL url(kTestURL);
NavigateAndCommit(url);
base::Time reference_time = GetReferenceTime();
base::Time one_day_ago = reference_time - base::TimeDelta::FromDays(1);
base::Time one_year_ago = reference_time - base::TimeDelta::FromDays(366);
// By default the banner should not be shown.
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Record events such that the banner should show.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, one_day_ago);
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, reference_time);
EXPECT_TRUE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
// Add the site a long time ago. It should not be shown.
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), url, kTestPackageName,
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
one_year_ago);
EXPECT_FALSE(AppBannerSettingsHelper::ShouldShowBanner(
web_contents(), url, kTestPackageName, reference_time));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment