1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.browser;
6
7import android.test.suitebuilder.annotation.LargeTest;
8
9import org.chromium.base.ThreadUtils;
10import org.chromium.base.test.util.Feature;
11import org.chromium.base.test.util.UrlUtils;
12import org.chromium.content.browser.test.util.Criteria;
13import org.chromium.content.browser.test.util.CriteriaHelper;
14import org.chromium.content.browser.test.util.TouchCommon;
15import org.chromium.content_public.browser.WebContents;
16import org.chromium.content_shell_apk.ContentShellActivity;
17import org.chromium.content_shell_apk.ContentShellTestBase;
18
19import java.util.concurrent.Callable;
20import java.util.concurrent.ExecutionException;
21
22/**
23 * Tests for interstitial pages.
24 */
25public class InterstitialPageTest extends ContentShellTestBase {
26
27    private static final String URL = UrlUtils.encodeHtmlDataUri(
28            "<html><head></head><body>test</body></html>");
29
30    private static class TestWebContentsObserverAndroid extends WebContentsObserverAndroid {
31        private boolean mInterstitialShowing;
32
33        public TestWebContentsObserverAndroid(WebContents webContents) {
34            super(webContents);
35        }
36
37        public boolean isInterstitialShowing() throws ExecutionException {
38            return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
39                @Override
40                public Boolean call() throws Exception {
41                    return mInterstitialShowing;
42                }
43            }).booleanValue();
44        }
45
46        @Override
47        public void didAttachInterstitialPage() {
48            mInterstitialShowing = true;
49        }
50
51        @Override
52        public void didDetachInterstitialPage() {
53            mInterstitialShowing = false;
54        }
55    }
56
57    @Override
58    protected void setUp() throws Exception {
59        super.setUp();
60        ContentShellActivity activity = launchContentShellWithUrl(URL);
61        assertNotNull(activity);
62        waitForActiveShellToBeDoneLoading();
63    }
64
65    private boolean waitForInterstitial(final boolean shouldBeShown) throws InterruptedException {
66        return CriteriaHelper.pollForCriteria(new Criteria() {
67            @Override
68            public boolean isSatisfied() {
69                try {
70                    return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
71                        @Override
72                        public Boolean call() throws Exception {
73                            return shouldBeShown
74                                    == getContentViewCore().isShowingInterstitialPage();
75                        }
76                    });
77                } catch (ExecutionException e) {
78                    return false;
79                }
80            }
81        });
82    }
83
84    /**
85     * Tests that showing and hiding an interstitial works.
86     */
87    @LargeTest
88    @Feature({"Navigation"})
89    public void testCloseInterstitial() throws InterruptedException, ExecutionException {
90        final String proceedCommand = "PROCEED";
91        final String htmlContent =
92                "<html>" +
93                        "<head>" +
94                        "<script>" +
95                                "function sendCommand(command) {" +
96                                        "window.domAutomationController.setAutomationId(1);" +
97                                        "window.domAutomationController.send(command);" +
98                                "}" +
99                        "</script>" +
100                        "</head>" +
101                        "<body style='background-color:#FF0000' " +
102                                "onclick='sendCommand(\"" + proceedCommand + "\");'>" +
103                                "<h1>This is a scary interstitial page</h1>" +
104                        "</body>" +
105                "</html>";
106        final InterstitialPageDelegateAndroid delegate =
107                new InterstitialPageDelegateAndroid(htmlContent) {
108            @Override
109            protected void commandReceived(String command) {
110                assertEquals(command, proceedCommand);
111                proceed();
112            }
113        };
114        TestWebContentsObserverAndroid observer = ThreadUtils.runOnUiThreadBlocking(
115                new Callable<TestWebContentsObserverAndroid>() {
116                    @Override
117                    public TestWebContentsObserverAndroid call() throws Exception {
118                        getContentViewCore().showInterstitialPage(URL, delegate);
119                        return new TestWebContentsObserverAndroid(
120                                getContentViewCore().getWebContents());
121                    }
122                });
123
124        assertTrue("Interstitial never shown.", waitForInterstitial(true));
125        assertTrue("WebContentsObserver not notified of interstitial showing",
126                observer.isInterstitialShowing());
127        TouchCommon touchCommon = new TouchCommon(this);
128        touchCommon.singleClickViewRelative(getContentViewCore().getContainerView(), 10, 10);
129        assertTrue("Interstitial never hidden.", waitForInterstitial(false));
130        assertTrue("WebContentsObserver not notified of interstitial hiding",
131                !observer.isInterstitialShowing());
132    }
133}
134