Commit b423ee3e authored by Dominick Ng's avatar Dominick Ng Committed by Commit Bot

Hide the ambient install infobar for 90 days if it has been dismissed.

This CL reduces the annoyingness of the ambient badge infobar on Android
when browsing a PWA. If the infobar is dismissed, it will not be shown
for 90 days, mirroring the existing block time for infobar app banners.
The infobar will continue to be shown on navigations until it is
dismissed.

BUG=782120,834259

Change-Id: Idbbb9e9451fd01f639e859a1b65470330929f993
Reviewed-on: https://chromium-review.googlesource.com/1068903Reviewed-by: default avatarBen Wells <benwells@chromium.org>
Commit-Queue: Dominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560977}
parent e8c01db4
......@@ -48,6 +48,7 @@ import org.chromium.chrome.browser.infobar.InfoBar;
import org.chromium.chrome.browser.infobar.InfoBarContainer;
import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationListener;
import org.chromium.chrome.browser.infobar.InfoBarContainerLayout.Item;
import org.chromium.chrome.browser.infobar.InstallableAmbientBadgeInfoBar;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.webapps.AddToHomescreenDialog;
......@@ -272,6 +273,18 @@ public class AppBannerManagerTest {
});
}
private void waitUntilAmbientBadgeInfoBarAppears(
ChromeActivityTestRule<? extends ChromeActivity> rule) {
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
List<InfoBar> infobars = rule.getInfoBars();
if (infobars.size() != 1) return false;
return infobars.get(0) instanceof InstallableAmbientBadgeInfoBar;
}
});
}
private void runFullNativeInstallPathway(
String url, String expectedReferrer, String expectedTitle) throws Exception {
// Visit a site that requests a banner.
......@@ -435,6 +448,7 @@ public class AppBannerManagerTest {
resetEngagementForUrl(url, 10);
rule.loadUrlInNewTab(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
navigateToUrlAndWaitForBannerManager(rule, url);
waitUntilAmbientBadgeInfoBarAppears(rule);
Tab tab = rule.getActivity().getActivityTab();
tapAndWaitForModalBanner(tab);
......@@ -451,6 +465,7 @@ public class AppBannerManagerTest {
rule.loadUrlInNewTab(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
navigateToUrlAndWaitForBannerManager(rule, url);
waitUntilAppDetailsRetrieved(rule, 1);
waitUntilAmbientBadgeInfoBarAppears(rule);
Assert.assertEquals(mDetailsDelegate.mReferrer, expectedReferrer);
final Tab tab = rule.getActivity().getActivityTab();
......@@ -489,6 +504,7 @@ public class AppBannerManagerTest {
waitUntilAppDetailsRetrieved(rule, 1);
}
waitUntilAmbientBadgeInfoBarAppears(rule);
Tab tab = rule.getActivity().getActivityTab();
tapAndWaitForModalBanner(tab);
......@@ -667,6 +683,49 @@ public class AppBannerManagerTest {
false);
}
@Test
@MediumTest
@Feature({"AppBanners"})
public void testBlockedAmbientBadgeDoesNotAppearAgainForMonths() throws Exception {
// Visit a site that is a PWA. The ambient badge should show.
String webBannerUrl = WebappTestPage.getServiceWorkerUrl(mTestServer);
Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab();
new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl);
waitUntilAmbientBadgeInfoBarAppears(mTabbedActivityTestRule);
InfoBarContainer container = tab.getInfoBarContainer();
final InfobarListener listener = new InfobarListener();
container.addAnimationListener(listener);
// Explicitly dismiss the ambient badge.
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
return listener.mDoneAnimating;
}
});
ArrayList<InfoBar> infobars = container.getInfoBarsForTesting();
View close = infobars.get(0).getView().findViewById(R.id.infobar_close_button);
TouchCommon.singleClickView(close);
InfoBarUtil.waitUntilNoInfoBarsExist(mTabbedActivityTestRule.getInfoBars());
// Waiting two months shouldn't be long enough.
AppBannerManager.setTimeDeltaForTesting(61);
new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl);
InfoBarUtil.waitUntilNoInfoBarsExist(mTabbedActivityTestRule.getInfoBars());
AppBannerManager.setTimeDeltaForTesting(62);
new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl);
InfoBarUtil.waitUntilNoInfoBarsExist(mTabbedActivityTestRule.getInfoBars());
// Waiting three months should allow the ambient badge to reappear.
AppBannerManager.setTimeDeltaForTesting(91);
new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl);
waitUntilAmbientBadgeInfoBarAppears(mTabbedActivityTestRule);
}
@Test
@SmallTest
@Feature({"AppBanners"})
......
......@@ -157,6 +157,7 @@ class AppBannerManager : public content::WebContentsObserver,
// InstallableAmbientBadgeInfoBarDelegate::Client overrides. Further
// overridden on Android.
void AddToHomescreenFromBadge() override {}
void BadgeDismissed() override {}
protected:
explicit AppBannerManager(content::WebContents* web_contents);
......
......@@ -130,7 +130,7 @@ void AppBannerManagerAndroid::SendBannerDismissed() {
// If we are dismissing the banner, the site can't be installed.
if (IsExperimentalAppBannersEnabled())
ShowAmbientBadge();
MaybeShowAmbientBadge();
}
void AppBannerManagerAndroid::AddToHomescreenFromBadge() {
......@@ -143,6 +143,14 @@ void AppBannerManagerAndroid::AddToHomescreenFromBadge() {
ResetBindings();
}
void AppBannerManagerAndroid::BadgeDismissed() {
banners::TrackDismissEvent(banners::DISMISS_EVENT_AMBIENT_INFOBAR_DISMISSED);
AppBannerSettingsHelper::RecordBannerEvent(
web_contents(), validated_url_, GetAppIdentifier(),
AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, GetCurrentTime());
}
std::string AppBannerManagerAndroid::GetAppIdentifier() {
return native_app_data_.is_null() ? AppBannerManager::GetAppIdentifier()
: native_app_package_;
......@@ -156,7 +164,7 @@ std::string AppBannerManagerAndroid::GetBannerType() {
bool AppBannerManagerAndroid::CheckIfInstalled() {
bool is_installed = AppBannerManager::CheckIfInstalled();
if (IsExperimentalAppBannersEnabled() && !is_installed)
ShowAmbientBadge();
MaybeShowAmbientBadge();
return is_installed;
}
......@@ -242,7 +250,7 @@ void AppBannerManagerAndroid::OnAppIconFetched(const SkBitmap& bitmap) {
// We will not reach this point if the app is already installed since querying
// for native app details will return nothing.
if (IsExperimentalAppBannersEnabled())
ShowAmbientBadge();
MaybeShowAmbientBadge();
// If we triggered the installability check on page load, then it's possible
// we don't have enough engagement yet. If that's the case, return here but
......@@ -372,7 +380,14 @@ base::string16 AppBannerManagerAndroid::GetAppName() const {
return native_app_title_;
}
void AppBannerManagerAndroid::ShowAmbientBadge() {
void AppBannerManagerAndroid::MaybeShowAmbientBadge() {
// Do not show the ambient badge if it was recently dismissed.
if (AppBannerSettingsHelper::WasBannerRecentlyBlocked(
web_contents(), validated_url_, GetAppIdentifier(),
GetCurrentTime())) {
return;
}
InfoBarService* infobar_service =
InfoBarService::FromWebContents(web_contents());
if (GetVisibleAmbientBadgeInfoBar(infobar_service) == nullptr) {
......
......@@ -88,6 +88,7 @@ class AppBannerManagerAndroid
// InstallableAmbientBadgeInfoBarAndroid::Client overrides.
void AddToHomescreenFromBadge() override;
void BadgeDismissed() override;
protected:
// AppBannerManager overrides.
......@@ -130,7 +131,7 @@ class AppBannerManagerAndroid
// Shows the ambient badge if the current page advertises a native app or is
// a PWA.
void ShowAmbientBadge();
void MaybeShowAmbientBadge();
// Hides the ambient badge if it is showing.
void HideAmbientBadge();
......
......@@ -48,7 +48,8 @@ enum DismissEvent {
DISMISS_EVENT_CLOSE_BUTTON = 45,
DISMISS_EVENT_INSTALL_TIMEOUT = 46,
DISMISS_EVENT_DISMISSED = 47,
DISMISS_EVENT_MAX = 48,
DISMISS_EVENT_AMBIENT_INFOBAR_DISMISSED = 48,
DISMISS_EVENT_MAX = 49,
};
// This enum backs a UMA histogram, so it should be treated as append-only.
......
......@@ -59,3 +59,10 @@ infobars::InfoBarDelegate::InfoBarIdentifier
InstallableAmbientBadgeInfoBarDelegate::GetIdentifier() const {
return INSTALLABLE_AMBIENT_BADGE_INFOBAR_DELEGATE;
}
void InstallableAmbientBadgeInfoBarDelegate::InfoBarDismissed() {
if (!weak_client_.get())
return;
weak_client_->BadgeDismissed();
}
......@@ -26,6 +26,9 @@ class InstallableAmbientBadgeInfoBarDelegate
// Called to trigger the add to home screen flow.
virtual void AddToHomescreenFromBadge() = 0;
// Called to inform the client that the badge was dismissed.
virtual void BadgeDismissed() = 0;
virtual ~Client() {}
};
......@@ -51,6 +54,7 @@ class InstallableAmbientBadgeInfoBarDelegate
// InfoBarDelegate overrides:
infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
void InfoBarDismissed() override;
base::WeakPtr<Client> weak_client_;
const base::string16 app_name_;
......
......@@ -1081,6 +1081,7 @@ uploading your change for review. These are checked by presubmit scripts.
<int value="45" label="User hit the X button"/>
<int value="46" label="User began app install, but it didn't finish in time"/>
<int value="47" label="Banner was dismissed for any reason"/>
<int value="48" label="Ambient badge infobar was dismissed"/>
</enum>
<enum name="AppBannersDisplayEvent">
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