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(); |
+ } |
+} |