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

Unified Diff: chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 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 side-by-side diff with in-line comments
Download patch
Index: chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java
new file mode 100644
index 0000000000000000000000000000000000000000..00b1caa68df8a563e0b364d97e23cc5faf5fd6ed
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java
@@ -0,0 +1,450 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.infobar;
+
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.test.FlakyTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.Tab;
+import org.chromium.chrome.browser.preferences.NetworkPredictionOptions;
+import org.chromium.chrome.browser.preferences.PrefServiceBridge;
+import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.util.InfoBarTestAnimationListener;
+import org.chromium.chrome.test.util.InfoBarUtil;
+import org.chromium.chrome.test.util.TestHttpServerClient;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+
+import java.util.ArrayList;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Tests for InfoBars.
+ *
+ * TODO(newt): merge this with InfoBarTest after upstreaming.
+ */
+public class InfoBarTest2 extends ChromeActivityTestCaseBase<ChromeActivity> {
+ static class MutableBoolean {
+ public boolean mValue = false;
+ }
+
+ private InfoBarTestAnimationListener mListener;
+
+ public InfoBarTest2() {
+ super(ChromeActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Register for animation notifications
+ InfoBarContainer container =
+ getActivity().getActivityTab().getInfoBarContainer();
+ mListener = new InfoBarTestAnimationListener();
+ container.setAnimationListener(mListener);
+ }
+
+ // Adds an infobar to the currrent tab. Blocks until the infobar has been added.
+ protected void addInfoBarToCurrentTab(final InfoBar infoBar) throws InterruptedException {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ Tab tab = getActivity().getActivityTab();
+ assertTrue("Failed to find tab.", tab != null);
+ tab.getInfoBarContainer().addInfoBar(infoBar);
+ }
+ });
+ assertTrue("InfoBar not added.", mListener.addInfoBarAnimationFinished());
+ getInstrumentation().waitForIdleSync();
+ }
+
+ // Removes an infobar from the currrent tab. Blocks until the infobar has been removed.
+ protected void removeInfoBarFromCurrentTab(final InfoBar infoBar) throws InterruptedException {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ Tab tab = getActivity().getActivityTab();
+ assertTrue("Failed to find tab.", tab != null);
+ tab.getInfoBarContainer().removeInfoBar(infoBar);
+ }
+ });
+ assertTrue("InfoBar not removed.", mListener.removeInfoBarAnimationFinished());
+ getInstrumentation().waitForIdleSync();
+ }
+
+ // Dismisses the passed infobar. Blocks until the bar has been removed.
+ protected void dismissInfoBar(final InfoBar infoBar) throws InterruptedException {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ infoBar.dismissJavaOnlyInfoBar();
+ }
+ });
+ assertTrue("InfoBar not removed.", mListener.removeInfoBarAnimationFinished());
+ getInstrumentation().waitForIdleSync();
+ }
+
+ protected ArrayList<Integer> getInfoBarIdsForCurrentTab() {
+ final ArrayList<Integer> infoBarIds = new ArrayList<Integer>();
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ Tab tab = getActivity().getActivityTab();
+ assertTrue("Failed to find tab.", tab != null);
+ for (InfoBar infoBar : tab.getInfoBarContainer().getInfoBars()) {
+ infoBarIds.add(infoBar.getId());
+ }
+ }
+ });
+ return infoBarIds;
+ }
+
+ /**
+ * Verifies that infobars added from Java expire or not as expected.
+ */
+ @MediumTest
+ @Feature({"Browser"})
+ public void testInfoBarExpiration() throws InterruptedException {
+ // First add an infobar that expires.
+ final MutableBoolean dismissed = new MutableBoolean();
+ MessageInfoBar expiringInfoBar = new MessageInfoBar("Hello!");
+ expiringInfoBar.setDismissedListener(new InfoBarListeners.Dismiss() {
+ @Override
+ public void onInfoBarDismissed(InfoBar infoBar) {
+ dismissed.mValue = true;
+ }
+ });
+ expiringInfoBar.setExpireOnNavigation(true);
+ addInfoBarToCurrentTab(expiringInfoBar);
+
+ // Verify it's really there.
+ ArrayList<Integer> infoBarIds = getInfoBarIdsForCurrentTab();
+ assertEquals(1, infoBarIds.size());
+ assertEquals(expiringInfoBar.getId(), infoBarIds.get(0).intValue());
+
+ // Now navigate, it should expire.
+ loadUrl(TestHttpServerClient.getUrl("chrome/test/data/android/google.html"));
+ assertTrue("InfoBar not removed.", mListener.removeInfoBarAnimationFinished());
+ assertTrue("InfoBar did not expire on navigation.", dismissed.mValue);
+ infoBarIds = getInfoBarIdsForCurrentTab();
+ assertTrue(infoBarIds.isEmpty());
+
+ // Now test a non-expiring infobar.
+ MessageInfoBar persistentInfoBar = new MessageInfoBar("Hello!");
+ persistentInfoBar.setDismissedListener(new InfoBarListeners.Dismiss() {
+ @Override
+ public void onInfoBarDismissed(InfoBar infoBar) {
+ dismissed.mValue = true;
+ }
+ });
+ dismissed.mValue = false;
+ persistentInfoBar.setExpireOnNavigation(false);
+ addInfoBarToCurrentTab(persistentInfoBar);
+
+ // Navigate, it should still be there.
+ loadUrl(TestHttpServerClient.getUrl("chrome/test/data/android/google.html"));
+ assertFalse("InfoBar did expire on navigation.", dismissed.mValue);
+ infoBarIds = getInfoBarIdsForCurrentTab();
+ assertEquals(1, infoBarIds.size());
+ assertEquals(persistentInfoBar.getId(), infoBarIds.get(0).intValue());
+
+ // Close the infobar.
+ dismissInfoBar(persistentInfoBar);
+ }
+
+ // Define function to pass parameter to Runnable to be used in testInfoBarExpirationNoPrerender.
+ private Runnable setNetworkPredictionOptions(
+ final NetworkPredictionOptions networkPredictionOptions) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ PrefServiceBridge.getInstance().setNetworkPredictionOptions(
+ networkPredictionOptions);
+ }
+ };
+ };
+
+ /**
+ * Same as testInfoBarExpiration but with prerender turned-off.
+ * The behavior when prerender is on/off is different as in the prerender case the infobars are
+ * added when we swap tabs.
+ * @throws InterruptedException
+ */
+ @MediumTest
+ @Feature({"Browser"})
+ public void testInfoBarExpirationNoPrerender() throws InterruptedException, ExecutionException {
+ // Save prediction preference.
+ NetworkPredictionOptions networkPredictionOption =
+ ThreadUtils.runOnUiThreadBlocking(new Callable<NetworkPredictionOptions>() {
+ @Override
+ public NetworkPredictionOptions call() {
+ return PrefServiceBridge.getInstance().getNetworkPredictionOptions();
+ }
+ });
+ try {
+ ThreadUtils.runOnUiThreadBlocking(setNetworkPredictionOptions(
+ NetworkPredictionOptions.NETWORK_PREDICTION_NEVER));
+ testInfoBarExpiration();
+ } finally {
+ // Make sure we restore prediction preference.
+ ThreadUtils.runOnUiThreadBlocking(setNetworkPredictionOptions(networkPredictionOption));
+ }
+ }
+
+ /**
+ * Tests that adding and then immediately removing an infobar works as expected (and does not
+ * assert).
+ */
+ @MediumTest
+ @Feature({"Browser"})
+ public void testQuickAddOneAndRemove() throws InterruptedException {
+ final InfoBar infoBar = new MessageInfoBar("Hello");
+ addInfoBarToCurrentTab(infoBar);
+ removeInfoBarFromCurrentTab(infoBar);
+ assertTrue(getInfoBarIdsForCurrentTab().isEmpty());
+ }
+
+ /**
+ * Tests that adding and then immediately dismissing an infobar works as expected (and does not
+ * assert).
+ */
+ @MediumTest
+ @Feature({"Browser"})
+ public void testQuickAddOneAndDismiss() throws InterruptedException {
+ final InfoBar infoBar = new MessageInfoBar("Hello");
+ addInfoBarToCurrentTab(infoBar);
+ dismissInfoBar(infoBar);
+ assertTrue(getInfoBarIdsForCurrentTab().isEmpty());
+ }
+
+ /**
+ * Tests that adding 2 infobars and then immediately removing the last one works as expected.
+ * This scenario is special as the 2nd infobar does not even get added to the view hierarchy.
+ */
+ @MediumTest
+ @Feature({"Browser"})
+ public void testAddTwoAndRemoveOneQuick() throws InterruptedException {
+ final InfoBar infoBar1 = new MessageInfoBar("One");
+ final InfoBar infoBar2 = new MessageInfoBar("Two");
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ Tab tab = getActivity().getActivityTab();
+ assertTrue("Failed to find tab.", tab != null);
+ tab.getInfoBarContainer().addInfoBar(infoBar1);
+ tab.getInfoBarContainer().addInfoBar(infoBar2);
+ tab.getInfoBarContainer().removeInfoBar(infoBar2);
+ }
+ });
+
+ // We should get an infobar added event for the first infobar.
+ assertTrue("InfoBar not added.", mListener.addInfoBarAnimationFinished());
+
+ // But no infobar removed event as the 2nd infobar was removed before it got added.
+ assertFalse("InfoBar not removed.", mListener.removeInfoBarAnimationFinished());
+ ArrayList<Integer> infoBarIds = getInfoBarIdsForCurrentTab();
+ assertEquals(1, infoBarIds.size());
+ assertEquals(infoBar1.getId(), infoBarIds.get(0).intValue());
+ }
+
+ /**
+ * Tests that adding 2 infobars and then immediately dismissing the last one works as expected
+ * This scenario is special as the 2nd infobar does not even get added to the view hierarchy.
+ */
+ @MediumTest
+ @Feature({"Browser"})
+ public void testAddTwoAndDismissOneQuick() throws InterruptedException {
+ final InfoBar infoBar1 = new MessageInfoBar("One");
+ final InfoBar infoBar2 = new MessageInfoBar("Two");
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ Tab tab = getActivity().getActivityTab();
+ assertTrue("Failed to find tab.", tab != null);
+ tab.getInfoBarContainer().addInfoBar(infoBar1);
+ tab.getInfoBarContainer().addInfoBar(infoBar2);
+ infoBar2.dismissJavaOnlyInfoBar();
+ }
+ });
+
+ // We should get an infobar added event for the first infobar.
+ assertTrue("InfoBar not added.", mListener.addInfoBarAnimationFinished());
+
+ // But no infobar removed event as the 2nd infobar was removed before it got added.
+ assertFalse("InfoBar not removed.", mListener.removeInfoBarAnimationFinished());
+ ArrayList<Integer> infoBarIds = getInfoBarIdsForCurrentTab();
+ assertEquals(1, infoBarIds.size());
+ assertEquals(infoBar1.getId(), infoBarIds.get(0).intValue());
+ }
+
+ /**
+ * Tests that we don't assert when a tab is getting closed while an infobar is being shown and
+ * had been removed.
+ */
+ @MediumTest
+ @Feature({"Browser"})
+ public void testCloseTabOnAdd() throws InterruptedException {
+ loadUrl(TestHttpServerClient.getUrl(
+ "chrome/test/data/android/google.html"));
+
+ final InfoBar infoBar = new MessageInfoBar("Hello");
+ addInfoBarToCurrentTab(infoBar);
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ Tab tab = getActivity().getActivityTab();
+ assertTrue("Failed to find tab.", tab != null);
+ tab.getInfoBarContainer().removeInfoBar(infoBar);
+ getActivity().getTabModelSelector().closeTab(tab);
+ }
+ });
+ }
+
+ /**
+ * Tests that the x button in the infobar does close the infobar and that the event is not
+ * propagated to the ContentView.
+ * @MediumTest
+ * @Feature({"Browser"})
+ * Bug: http://crbug.com/172427
+ */
+ @FlakyTest
+ public void testCloseButton() throws InterruptedException, TimeoutException {
+ loadUrl(TestHttpServerClient.getUrl(
+ "chrome/test/data/android/click_listener.html"));
+ final InfoBar infoBar = new MessageInfoBar("Hello");
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ Tab tab = getActivity().getActivityTab();
+ assertTrue("Failed to find tab.", tab != null);
+ tab.getInfoBarContainer().addInfoBar(infoBar);
+ }
+ });
+ assertTrue("InfoBar not added", mListener.addInfoBarAnimationFinished());
+
+ // Now press the close button.
+ assertTrue("Close button wasn't found", InfoBarUtil.clickCloseButton(infoBar));
+ assertTrue("Infobar not removed.", mListener.removeInfoBarAnimationFinished());
+
+ // The page should not have received the click.
+ assertTrue("The page recieved the click.",
+ !Boolean.parseBoolean(runJavaScriptCodeInCurrentTab("wasClicked")));
+ }
+
+ /**
+ * Tests that adding and removing correctly manages the transparent region, which allows for
+ * optimizations in SurfaceFlinger (less overlays).
+ */
+ @MediumTest
+ @Feature({"Browser"})
+ public void testAddAndDismissSurfaceFlingerOverlays() throws InterruptedException {
+ final ViewGroup decorView = (ViewGroup) getActivity().getWindow().getDecorView();
+ final InfoBarContainer infoBarContainer =
+ getActivity().getActivityTab().getInfoBarContainer();
+
+ // Detect layouts. Note this doesn't actually need to be atomic (just final).
+ final AtomicInteger layoutCount = new AtomicInteger();
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ decorView.getViewTreeObserver().addOnGlobalLayoutListener(
+ new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ layoutCount.incrementAndGet();
+ }
+ });
+ }
+ });
+
+ // First add an infobar.
+ final InfoBar infoBar = new MessageInfoBar("Hello");
+ addInfoBarToCurrentTab(infoBar);
+
+ // A layout must occur to recalculate the transparent region.
+ boolean layoutOccured = CriteriaHelper.pollForUIThreadCriteria(
+ new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ return layoutCount.get() > 0;
+ }
+ });
+ assertTrue(layoutOccured);
+
+ final Rect fullDisplayFrame = new Rect();
+ final Rect fullDisplayFrameMinusContainer = new Rect();
+ final Rect containerDisplayFrame = new Rect();
+
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ decorView.getWindowVisibleDisplayFrame(fullDisplayFrame);
+ decorView.getWindowVisibleDisplayFrame(fullDisplayFrameMinusContainer);
+ fullDisplayFrameMinusContainer.bottom -= infoBarContainer.getHeight();
+ int windowLocation[] = new int[2];
+ infoBarContainer.getLocationInWindow(windowLocation);
+ containerDisplayFrame.set(
+ windowLocation[0],
+ windowLocation[1],
+ windowLocation[0] + infoBarContainer.getWidth(),
+ windowLocation[1] + infoBarContainer.getHeight());
+
+ // The InfoBarContainer subtracts itself from the transparent region.
+ Region transparentRegion = new Region(fullDisplayFrame);
+ infoBarContainer.gatherTransparentRegion(transparentRegion);
+ assertEquals(transparentRegion.getBounds(), fullDisplayFrameMinusContainer);
+ }
+ });
+
+ // Now remove the infobar.
+ layoutCount.set(0);
+ dismissInfoBar(infoBar);
+
+ // A layout must occur to recalculate the transparent region.
+ layoutOccured = CriteriaHelper.pollForUIThreadCriteria(
+ new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ return layoutCount.get() > 0;
+ }
+ });
+ assertTrue(layoutOccured);
+
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ // The InfoBarContainer should no longer be subtracted from the transparent region.
+ // We really want assertTrue(transparentRegion.contains(containerDisplayFrame)),
+ // but region doesn't have 'contains(Rect)', so we invert the test. So, the old
+ // container rect can't touch the bounding rect of the non-transparent region).
+ Region transparentRegion = new Region();
+ decorView.gatherTransparentRegion(transparentRegion);
+ Region opaqueRegion = new Region(fullDisplayFrame);
+ opaqueRegion.op(transparentRegion, Region.Op.DIFFERENCE);
+ assertFalse(opaqueRegion.getBounds().intersect(containerDisplayFrame));
+ }
+ });
+
+ // Additional manual test that this is working:
+ // - adb shell dumpsys SurfaceFlinger
+ // - Observe that Clank's overlay size changes (or disappears if URLbar is also gone).
+ }
+
+ @Override
+ public void startMainActivity() throws InterruptedException {
+ startMainActivityOnBlankPage();
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698