WebViewCompatTest.java revision eab2c96c81d8081fa56f8ca44a271633a0836ea3
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.assertNull; 23import static org.junit.Assert.assertTrue; 24import static org.junit.Assert.fail; 25import static org.junit.Assume.assumeTrue; 26 27import android.content.Context; 28import android.content.ContextWrapper; 29import android.os.Build; 30import android.os.Looper; 31import android.support.test.InstrumentationRegistry; 32import android.support.test.filters.MediumTest; 33import android.support.test.runner.AndroidJUnit4; 34import android.webkit.ValueCallback; 35import android.webkit.WebResourceRequest; 36import android.webkit.WebView; 37 38import androidx.core.os.BuildCompat; 39 40import org.junit.Assert; 41import org.junit.Before; 42import org.junit.Test; 43import org.junit.runner.RunWith; 44 45import java.net.MalformedURLException; 46import java.net.URL; 47import java.util.ArrayList; 48import java.util.List; 49import java.util.concurrent.CountDownLatch; 50import java.util.concurrent.TimeUnit; 51 52@MediumTest 53@RunWith(AndroidJUnit4.class) 54public class WebViewCompatTest { 55 WebViewOnUiThread mWebViewOnUiThread; 56 57 private static final long TEST_TIMEOUT = 20000L; 58 59 @Before 60 public void setUp() { 61 mWebViewOnUiThread = new androidx.webkit.WebViewOnUiThread(); 62 } 63 64 @Test 65 public void testVisualStateCallbackCalled() throws Exception { 66 // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK 67 // containing support for the WebView Support Library, see b/73454652. 68 if (!BuildCompat.isAtLeastP()) return; 69 70 final CountDownLatch callbackLatch = new CountDownLatch(1); 71 final long kRequest = 100; 72 73 mWebViewOnUiThread.loadUrl("about:blank"); 74 75 mWebViewOnUiThread.postVisualStateCallbackCompat(kRequest, 76 new WebViewCompat.VisualStateCallback() { 77 public void onComplete(long requestId) { 78 assertEquals(kRequest, requestId); 79 callbackLatch.countDown(); 80 } 81 }); 82 83 assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS)); 84 } 85 86 @Test 87 public void testCheckThread() { 88 if (!WebViewFeature.isFeatureSupported(WebViewFeature.VISUAL_STATE_CALLBACK)) { 89 // Skip this test if VisualStateCallback is not supported. 90 return; 91 } 92 try { 93 WebViewCompat.postVisualStateCallback(mWebViewOnUiThread.getWebViewOnCurrentThread(), 5, 94 new WebViewCompat.VisualStateCallback() { 95 @Override 96 public void onComplete(long requestId) { 97 } 98 }); 99 } catch (RuntimeException e) { 100 return; 101 } 102 fail("Calling a WebViewCompat method on the wrong thread must cause a run-time exception"); 103 } 104 105 private static class MockContext extends ContextWrapper { 106 private boolean mGetApplicationContextWasCalled; 107 108 MockContext(Context context) { 109 super(context); 110 } 111 112 public Context getApplicationContext() { 113 mGetApplicationContextWasCalled = true; 114 return super.getApplicationContext(); 115 } 116 117 public boolean wasGetApplicationContextCalled() { 118 return mGetApplicationContextWasCalled; 119 } 120 } 121 122 @Test 123 public void testStartSafeBrowsingUseApplicationContext() throws Exception { 124 // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK 125 // containing support for the WebView Support Library, see b/73454652. 126 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return; 127 128 final MockContext ctx = 129 new MockContext(InstrumentationRegistry.getTargetContext().getApplicationContext()); 130 final CountDownLatch resultLatch = new CountDownLatch(1); 131 WebViewCompat.startSafeBrowsing(ctx, new ValueCallback<Boolean>() { 132 @Override 133 public void onReceiveValue(Boolean value) { 134 assertTrue(ctx.wasGetApplicationContextCalled()); 135 resultLatch.countDown(); 136 return; 137 } 138 }); 139 assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS)); 140 } 141 142 @Test 143 public void testStartSafeBrowsingWithNullCallbackDoesntCrash() throws Exception { 144 // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK 145 // containing support for the WebView Support Library, see b/73454652. 146 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return; 147 148 WebViewCompat.startSafeBrowsing(InstrumentationRegistry.getTargetContext(), null); 149 } 150 151 @Test 152 public void testStartSafeBrowsingInvokesCallback() throws Exception { 153 // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK 154 // containing support for the WebView Support Library, see b/73454652. 155 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return; 156 157 final CountDownLatch resultLatch = new CountDownLatch(1); 158 WebViewCompat.startSafeBrowsing( 159 InstrumentationRegistry.getTargetContext().getApplicationContext(), 160 new ValueCallback<Boolean>() { 161 @Override 162 public void onReceiveValue(Boolean value) { 163 assertTrue(Looper.getMainLooper().isCurrentThread()); 164 resultLatch.countDown(); 165 return; 166 } 167 }); 168 assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS)); 169 } 170 171 @Test 172 public void testSetSafeBrowsingWhitelistWithMalformedList() throws Exception { 173 // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK 174 // containing support for the WebView Support Library, see b/73454652. 175 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return; 176 177 List whitelist = new ArrayList<String>(); 178 // Protocols are not supported in the whitelist 179 whitelist.add("http://google.com"); 180 final CountDownLatch resultLatch = new CountDownLatch(1); 181 WebViewCompat.setSafeBrowsingWhitelist(whitelist, new ValueCallback<Boolean>() { 182 @Override 183 public void onReceiveValue(Boolean success) { 184 assertFalse(success); 185 resultLatch.countDown(); 186 } 187 }); 188 assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS)); 189 } 190 191 @Test 192 public void testSetSafeBrowsingWhitelistWithValidList() throws Exception { 193 // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK 194 // containing support for the WebView Support Library, see b/73454652. 195 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return; 196 // This test relies on the onSafeBrowsingHit callback to verify correctness. 197 assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_HIT)); 198 199 List whitelist = new ArrayList<String>(); 200 whitelist.add("safe-browsing"); 201 final CountDownLatch resultLatch = new CountDownLatch(1); 202 WebViewCompat.setSafeBrowsingWhitelist(whitelist, new ValueCallback<Boolean>() { 203 @Override 204 public void onReceiveValue(Boolean success) { 205 assertTrue(success); 206 resultLatch.countDown(); 207 } 208 }); 209 assertTrue(resultLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS)); 210 211 final CountDownLatch resultLatch2 = new CountDownLatch(1); 212 mWebViewOnUiThread.setWebViewClient(new WebViewClientCompat() { 213 @Override 214 public void onPageFinished(WebView view, String url) { 215 resultLatch2.countDown(); 216 } 217 218 @Override 219 public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType, 220 SafeBrowsingResponseCompat callback) { 221 Assert.fail("Should not invoke onSafeBrowsingHit"); 222 } 223 }); 224 225 mWebViewOnUiThread.loadUrl("chrome://safe-browsing/match?type=malware"); 226 227 // Wait until page load has completed 228 assertTrue(resultLatch2.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS)); 229 } 230 231 @Test 232 public void testGetSafeBrowsingPrivacyPolicyUrl() throws Exception { 233 // TODO(gsennton) activate this test for pre-P devices when we can pre-install a WebView APK 234 // containing support for the WebView Support Library, see b/73454652. 235 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) return; 236 237 assertNotNull(WebViewCompat.getSafeBrowsingPrivacyPolicyUrl()); 238 try { 239 new URL(WebViewCompat.getSafeBrowsingPrivacyPolicyUrl().toString()); 240 } catch (MalformedURLException e) { 241 Assert.fail("The privacy policy URL should be a well-formed URL"); 242 } 243 } 244 245 /** 246 * WebViewCompat.getCurrentWebViewPackage should be null on pre-L devices. 247 * On L+ devices WebViewCompat.getCurrentWebViewPackage should be null only in exceptional 248 * circumstances - like when the WebView APK is being updated, or for Wear devices. The L+ 249 * devices used in support library testing should have a non-null WebView package. 250 */ 251 @Test 252 public void testGetCurrentWebViewPackage() { 253 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 254 assertNull(WebViewCompat.getCurrentWebViewPackage( 255 InstrumentationRegistry.getTargetContext())); 256 } else { 257 assertNotNull( 258 WebViewCompat.getCurrentWebViewPackage( 259 InstrumentationRegistry.getTargetContext())); 260 } 261 } 262} 263