Chromium Code Reviews| Index: android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java |
| diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..76e6364516ec2b9869c00c2cfb22a3cba68d0552 |
| --- /dev/null |
| +++ b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java |
| @@ -0,0 +1,148 @@ |
| +// Copyright 2017 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.android_webview.test; |
| + |
| +import android.content.Context; |
| +import android.content.SharedPreferences; |
| +import android.graphics.Bitmap; |
| +import android.graphics.Color; |
| +import android.support.test.filters.SmallTest; |
| + |
| +import org.chromium.android_webview.AwBrowserContext; |
| +import org.chromium.android_webview.AwContents; |
| +import org.chromium.android_webview.test.util.GraphicsTestUtils; |
| +import org.chromium.base.test.util.Feature; |
| +import org.chromium.base.test.util.InMemorySharedPreferences; |
| +import org.chromium.components.safe_browsing.SafeBrowsingApiBridge; |
| +import org.chromium.components.safe_browsing.SafeBrowsingApiHandler; |
| +import org.chromium.net.test.EmbeddedTestServer; |
| + |
| +import java.util.concurrent.Callable; |
| + |
| +/** |
| + * Test suite for SafeBrowsing. |
| + * |
| + * Ensures that interstitials can be successfully created for malicous pages. |
| + */ |
| +public class SafeBrowsingTest extends AwTestBase { |
| + private TestAwContentsClient mContentsClient; |
| + private AwTestContainerView mContainerView; |
| + private AwContents mAwContents; |
| + |
| + private EmbeddedTestServer mTestServer; |
| + |
| + // The background color of the safebrowsing interstitial HTML |
| + // See components/security_interstitials/core/browser/resources/interstitial_v2.css |
| + private static final int INTERSTITIAL_COLOR = Color.rgb(206, 52, 38); |
| + |
| + private static final String RESOURCE_PATH = "/android_webview/test/data"; |
| + private static final String SAFE_HTML_PATH = RESOURCE_PATH + "/safe.html"; |
| + private static final String MALWARE_HTML_PATH = RESOURCE_PATH + "/malware.html"; |
| + private static final String IFRAME_HTML_PATH = RESOURCE_PATH + "/iframe.html"; |
| + |
| + /** |
| + * A fake SafeBrowsingApiHandler which treats URLs ending in MALWARE_HTML_PATH as malicious URLs |
| + * that should be blocked. |
| + */ |
| + public static class MockSafeBrowsingApiHandler implements SafeBrowsingApiHandler { |
| + private Observer mObserver; |
| + private static final String SAFE_METADATA = "{}"; |
| + private static final String MALWARE_METADATA = "{\"matches\":[{\"threat_type\":\"5\"}]}"; |
| + |
| + @Override |
| + public boolean init(Context context, Observer result) { |
| + mObserver = result; |
| + return true; |
| + } |
| + |
| + @Override |
| + public void startUriLookup(long callbackId, String uri, int[] threatsOfInterest) { |
| + int resultStatus = STATUS_SUCCESS; |
| + String metadata = isMaliciousUrl(uri) ? MALWARE_METADATA : SAFE_METADATA; |
| + |
| + mObserver.onUrlCheckDone(callbackId, resultStatus, metadata); |
| + } |
| + |
| + private static boolean isMaliciousUrl(String uri) { |
| + return uri.endsWith(MALWARE_HTML_PATH); |
| + } |
| + } |
| + |
| + /** |
| + * A fake AwBrowserContext which loads the MockSafeBrowsingApiHandler instead of the real one. |
| + */ |
| + private static class MockAwBrowserContext extends AwBrowserContext { |
| + public MockAwBrowserContext( |
| + SharedPreferences sharedPreferences, Context applicationContext) { |
| + super(sharedPreferences, applicationContext); |
| + SafeBrowsingApiBridge.setSafeBrowsingHandlerType(MockSafeBrowsingApiHandler.class); |
| + } |
| + } |
| + |
| + @Override |
| + public void setUp() throws Exception { |
| + super.setUp(); |
| + mContentsClient = new TestAwContentsClient(); |
| + mContainerView = createAwTestContainerViewOnMainSync(mContentsClient); |
| + mAwContents = mContainerView.getAwContents(); |
| + |
| + mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext()); |
| + } |
| + |
| + @Override |
| + public void tearDown() throws Exception { |
| + mTestServer.stopAndDestroyServer(); |
| + super.tearDown(); |
| + } |
| + |
| + /** |
| + * Creates a special BrowserContext that has a safebrowsing api handler which always says |
| + * sites are malicious |
| + */ |
| + @Override |
| + protected void createAwBrowserContextHelper( |
| + InMemorySharedPreferences prefs, Context appContext) { |
| + setBrowserContext(new MockAwBrowserContext(prefs, appContext)); |
| + } |
| + |
| + private boolean isShowingInterstitial() { |
| + Bitmap bitmap = GraphicsTestUtils.drawAwContentsOnUiThread( |
| + mAwContents, mContainerView.getWidth(), mContainerView.getHeight()); |
| + return (bitmap.getPixel(0, 0) == INTERSTITIAL_COLOR); |
| + } |
| + |
| + private void waitForInterstitial() throws Exception { |
| + pollUiThread(new Callable<Boolean>() { |
|
boliu
2017/02/14 18:31:40
Always prefer the CallbackHelper pattern, which ju
Nate Fischer
2017/02/14 19:42:55
Ack. If I've understood you correctly, polling is
boliu
2017/02/14 22:26:57
Yep that's all correct
|
| + @Override |
| + public Boolean call() throws Exception { |
| + return isShowingInterstitial(); |
| + } |
| + }); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"AndroidWebView"}) |
| + public void testSafeBrowsingDoesNotBlockSafePages() throws Throwable { |
| + final String responseUrl = mTestServer.getURL(SAFE_HTML_PATH); |
| + loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), responseUrl); |
| + assertFalse("Should not create an interstitial", isShowingInterstitial()); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"AndroidWebView"}) |
| + public void testSafeBrowsingShowsInterstitialForMalware() throws Throwable { |
| + final String responseUrl = mTestServer.getURL(MALWARE_HTML_PATH); |
| + loadUrlAsync(mAwContents, responseUrl); |
| + waitForInterstitial(); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"AndroidWebView"}) |
| + public void testSafeBrowsingMaliciousSubresourceShowsInterstitial() throws Throwable { |
| + final String responseUrl = mTestServer.getURL(IFRAME_HTML_PATH); |
| + loadUrlAsync(mAwContents, responseUrl); |
| + waitForInterstitial(); |
| + } |
| +} |