WebViewCompatTest.java revision ac5fe7c617c66850fff75a9fce9979c6e5674b0f
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.webkit;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertNotNull;
22import static org.junit.Assert.assertTrue;
23import static org.junit.Assert.fail;
24
25import android.content.Context;
26import android.content.ContextWrapper;
27import android.os.Build;
28import android.os.Looper;
29import android.support.test.InstrumentationRegistry;
30import android.support.test.filters.MediumTest;
31import android.support.test.runner.AndroidJUnit4;
32import androidx.core.os.BuildCompat;
33import android.webkit.SafeBrowsingResponse;
34import android.webkit.ValueCallback;
35import android.webkit.WebResourceRequest;
36import android.webkit.WebView;
37import android.webkit.WebViewClient;
38
39import org.junit.Assert;
40import org.junit.Before;
41import org.junit.Test;
42import org.junit.runner.RunWith;
43
44import java.net.MalformedURLException;
45import java.net.URL;
46import java.util.ArrayList;
47import java.util.List;
48import java.util.concurrent.CountDownLatch;
49import java.util.concurrent.TimeUnit;
50
51@MediumTest
52@RunWith(AndroidJUnit4.class)
53public class WebViewCompatTest {
54    WebViewOnUiThread mWebViewOnUiThread;
55
56    private static final long TEST_TIMEOUT = 20000L;
57
58    @Before
59    public void setUp() {
60        mWebViewOnUiThread = new androidx.webkit.WebViewOnUiThread();
61    }
62
63    @Test
64    public void testVisualStateCallbackCalled() throws Exception {
65        // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
66        // containing support for the WebView Support Library, see b/73454652.
67        if (!BuildCompat.isAtLeastP()) return;
68
69        final CountDownLatch callbackLatch = new CountDownLatch(1);
70        final long kRequest = 100;
71
72        mWebViewOnUiThread.loadUrl("about:blank");
73
74        mWebViewOnUiThread.postVisualStateCallbackCompat(kRequest,
75                new WebViewCompat.VisualStateCallback() {
76                        public void onComplete(long requestId) {
77                            assertEquals(kRequest, requestId);
78                            callbackLatch.countDown();
79                        }
80                });
81
82        assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
83    }
84
85    @Test
86    public void testCheckThread() {
87        try {
88            WebViewCompat.postVisualStateCallback(mWebViewOnUiThread.getWebViewOnCurrentThread(), 5,
89                    new WebViewCompat.VisualStateCallback() {
90                        @Override
91                        public void onComplete(long requestId) {
92                        }
93                    });
94        } catch (RuntimeException e) {
95            return;
96        }
97        fail("Calling a WebViewCompat method on the wrong thread must cause a run-time exception");
98    }
99
100    private static class MockContext extends ContextWrapper {
101        private boolean mGetApplicationContextWasCalled;
102
103        MockContext(Context context) {
104            super(context);
105        }
106
107        public Context getApplicationContext() {
108            mGetApplicationContextWasCalled = true;
109            return super.getApplicationContext();
110        }
111
112        public boolean wasGetApplicationContextCalled() {
113            return mGetApplicationContextWasCalled;
114        }
115    }
116
117    @Test
118    public void testStartSafeBrowsingUseApplicationContext() throws Exception {
119        // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
120        // containing support for the WebView Support Library, see b/73454652.
121        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
122
123        final MockContext ctx =
124                new MockContext(InstrumentationRegistry.getTargetContext().getApplicationContext());
125        final CountDownLatch resultLatch = new CountDownLatch(1);
126        WebViewCompat.startSafeBrowsing(ctx, new ValueCallback<Boolean>() {
127            @Override
128            public void onReceiveValue(Boolean value) {
129                assertTrue(ctx.wasGetApplicationContextCalled());
130                resultLatch.countDown();
131                return;
132            }
133        });
134        assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
135    }
136
137    @Test
138    public void testStartSafeBrowsingWithNullCallbackDoesntCrash() throws Exception {
139        // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
140        // containing support for the WebView Support Library, see b/73454652.
141        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
142
143        WebViewCompat.startSafeBrowsing(InstrumentationRegistry.getTargetContext(), null);
144    }
145
146    @Test
147    public void testStartSafeBrowsingInvokesCallback() throws Exception {
148        // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
149        // containing support for the WebView Support Library, see b/73454652.
150        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
151
152        final CountDownLatch resultLatch = new CountDownLatch(1);
153        WebViewCompat.startSafeBrowsing(
154                InstrumentationRegistry.getTargetContext().getApplicationContext(),
155                new ValueCallback<Boolean>() {
156                    @Override
157                    public void onReceiveValue(Boolean value) {
158                        assertTrue(Looper.getMainLooper().isCurrentThread());
159                        resultLatch.countDown();
160                        return;
161                    }
162                });
163        assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
164    }
165
166    @Test
167    public void testSetSafeBrowsingWhitelistWithMalformedList() throws Exception {
168        // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
169        // containing support for the WebView Support Library, see b/73454652.
170        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
171
172        List whitelist = new ArrayList<String>();
173        // Protocols are not supported in the whitelist
174        whitelist.add("http://google.com");
175        final CountDownLatch resultLatch = new CountDownLatch(1);
176        WebViewCompat.setSafeBrowsingWhitelist(whitelist, new ValueCallback<Boolean>() {
177            @Override
178            public void onReceiveValue(Boolean success) {
179                assertFalse(success);
180                resultLatch.countDown();
181            }
182        });
183        assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
184    }
185
186    @Test
187    public void testSetSafeBrowsingWhitelistWithValidList() throws Exception {
188        // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
189        // containing support for the WebView Support Library, see b/73454652.
190        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
191
192        List whitelist = new ArrayList<String>();
193        whitelist.add("safe-browsing");
194        final CountDownLatch resultLatch = new CountDownLatch(1);
195        WebViewCompat.setSafeBrowsingWhitelist(whitelist, new ValueCallback<Boolean>() {
196            @Override
197            public void onReceiveValue(Boolean success) {
198                assertTrue(success);
199                resultLatch.countDown();
200            }
201        });
202        assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
203
204        final CountDownLatch resultLatch2 = new CountDownLatch(1);
205        mWebViewOnUiThread.setWebViewClient(new WebViewClient() {
206            @Override
207            public void onPageFinished(WebView view, String url) {
208                resultLatch2.countDown();
209            }
210
211            @Override
212            public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType,
213                    SafeBrowsingResponse callback) {
214                Assert.fail("Should not invoke onSafeBrowsingHit");
215            }
216        });
217
218        mWebViewOnUiThread.loadUrl("chrome://safe-browsing/match?type=malware");
219
220        // Wait until page load has completed
221        assertTrue(resultLatch2.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
222    }
223
224    @Test
225    public void testGetSafeBrowsingPrivacyPolicyUrl() throws Exception {
226        // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK
227        // containing support for the WebView Support Library, see b/73454652.
228        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return;
229
230        assertNotNull(WebViewCompat.getSafeBrowsingPrivacyPolicyUrl());
231        try {
232            new URL(WebViewCompat.getSafeBrowsingPrivacyPolicyUrl().toString());
233        } catch (MalformedURLException e) {
234            Assert.fail("The privacy policy URL should be a well-formed URL");
235        }
236    }
237}
238