@MediumTest
  @Feature({"AppBanners"})
  public void testBlockedBannerDoesNotAppearAgainForMonths() throws Exception {
    // Visit a site that requests a banner.
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL)));
    assertTrue(waitUntilAppDetailsRetrieved(1));
    assertTrue(waitUntilNoInfoBarsExist());

    // Indicate a day has passed, then revisit the page.
    InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
    final InfobarListener listener = new InfobarListener();
    container.setAnimationListener(listener);
    AppBannerManager.setTimeDeltaForTesting(1);
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL)));
    assertTrue(waitUntilAppDetailsRetrieved(2));
    assertTrue(waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE));

    // Explicitly dismiss the banner.
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                return listener.mDoneAnimating;
              }
            }));
    ArrayList<InfoBar> infobars = container.getInfoBars();
    View close = infobars.get(0).getContentWrapper().findViewById(R.id.infobar_close_button);
    TouchCommon.singleClickView(close);
    assertTrue(waitUntilNoInfoBarsExist());

    // Waiting two months shouldn't be long enough.
    AppBannerManager.setTimeDeltaForTesting(61);
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL)));
    assertTrue(waitUntilAppDetailsRetrieved(3));
    assertTrue(waitUntilNoInfoBarsExist());

    AppBannerManager.setTimeDeltaForTesting(62);
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL)));
    assertTrue(waitUntilAppDetailsRetrieved(4));
    assertTrue(waitUntilNoInfoBarsExist());

    // Waiting three months should allow banners to reappear.
    AppBannerManager.setTimeDeltaForTesting(91);
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL)));
    assertTrue(waitUntilAppDetailsRetrieved(5));
    assertTrue(waitUntilNoInfoBarsExist());

    AppBannerManager.setTimeDeltaForTesting(92);
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new TabLoadObserver(getActivity().getActivityTab(), NATIVE_APP_URL)));
    assertTrue(waitUntilAppDetailsRetrieved(6));
    assertTrue(waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE));
  }
  private void runFullNativeInstallPathway(String url, String expectedReferrer) throws Exception {
    // Visit a site that requests a banner.
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new TabLoadObserver(getActivity().getActivityTab(), url)));
    assertTrue(waitUntilAppDetailsRetrieved(1));
    assertEquals(mDetailsDelegate.mReferrer, expectedReferrer);
    assertTrue(waitUntilNoInfoBarsExist());

    // Indicate a day has passed, then revisit the page to get the banner to appear.
    InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
    final InfobarListener listener = new InfobarListener();
    container.setAnimationListener(listener);
    AppBannerManager.setTimeDeltaForTesting(1);
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new TabLoadObserver(getActivity().getActivityTab(), url)));
    assertTrue(waitUntilAppDetailsRetrieved(2));
    assertTrue(waitUntilAppBannerInfoBarAppears(NATIVE_APP_TITLE));
    assertTrue(
        CriteriaHelper.pollForUIThreadCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                return listener.mDoneAnimating;
              }
            }));

    // Check that the button asks if the user wants to install the app.
    InfoBar infobar = container.getInfoBars().get(0);
    final Button button = (Button) infobar.getContentWrapper().findViewById(R.id.button_primary);
    assertEquals(NATIVE_APP_INSTALL_TEXT, button.getText());

    // Click the button to trigger the install.
    final ActivityMonitor activityMonitor =
        new ActivityMonitor(
            new IntentFilter(INSTALL_ACTION), new ActivityResult(Activity.RESULT_OK, null), true);
    getInstrumentation().addMonitor(activityMonitor);
    TouchCommon.singleClickView(button);

    // Wait for the infobar to register that the app is installing.
    final String installingText =
        getInstrumentation().getTargetContext().getString(R.string.app_banner_installing);
    assertTrue(
        CriteriaHelper.pollForCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                return getInstrumentation().checkMonitorHit(activityMonitor, 1)
                    && TextUtils.equals(button.getText(), installingText);
              }
            }));

    // Say that the package is installed.  Infobar should say that the app is ready to open.
    mPackageManager.isInstalled = true;
    final String openText =
        getInstrumentation().getTargetContext().getString(R.string.app_banner_open);
    assertTrue(
        CriteriaHelper.pollForCriteria(
            new Criteria() {
              @Override
              public boolean isSatisfied() {
                return TextUtils.equals(button.getText(), openText);
              }
            }));
  }