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