19d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner// Copyright 2012 The Chromium Authors. All rights reserved.
29d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner// Use of this source code is governed by a BSD-style license that can be
39d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner// found in the LICENSE file.
49d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
59d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerpackage org.chromium.android_webview.test;
69d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
79d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport android.graphics.Bitmap;
89d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport android.test.suitebuilder.annotation.SmallTest;
99d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
109d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport org.chromium.android_webview.AwContents;
119d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport org.chromium.android_webview.AwSettings;
129d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport org.chromium.android_webview.test.util.CommonResources;
13ac5802bca0285eee49c1c372846552823d819181Benjamin Kramerimport org.chromium.base.test.util.DisabledTest;
149d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport org.chromium.base.test.util.Feature;
15147d9e05116518461653695a6022f6109f0eb936Chandler Carruthimport org.chromium.content.browser.test.util.HistoryUtils;
169d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport org.chromium.content.browser.test.util.TestCallbackHelperContainer;
179d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport org.chromium.content_public.browser.WebContents;
189d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport org.chromium.net.test.util.TestWebServer;
199d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
209d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport java.io.File;
219d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport java.io.FileOutputStream;
229d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerimport java.util.concurrent.Callable;
239d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
249d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner/**
259d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner * Tests for the {@link android.webkit.WebView#loadDataWithBaseURL(String, String, String, String,
269d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner * String)} method.
279d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner */
289d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattnerpublic class LoadDataWithBaseUrlTest extends AwTestBase {
2940dab1059e72d3af59f2523fa8a7d05f40dafca5Chandler Carruth
3040dab1059e72d3af59f2523fa8a7d05f40dafca5Chandler Carruth    private TestAwContentsClient mContentsClient;
319d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    private AwContents mAwContents;
32b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth    private WebContents mWebContents;
339d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
3406bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    @Override
3506bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    public void setUp() throws Exception {
3606bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        super.setUp();
3706bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        mContentsClient = new TestAwContentsClient();
3806bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        final AwTestContainerView testContainerView =
399d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner                createAwTestContainerViewOnMainSync(mContentsClient);
409d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        mAwContents = testContainerView.getAwContents();
419d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        mWebContents = mAwContents.getWebContents();
429d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    }
4306bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth
4406bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    protected void loadDataWithBaseUrlSync(
4506bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        final String data, final String mimeType, final boolean isBase64Encoded,
4606bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        final String baseUrl, final String historyUrl) throws Throwable {
4706bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
4806bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                data, mimeType, isBase64Encoded, baseUrl, historyUrl);
4906bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    }
5006bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth
5106bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    private static final String SCRIPT_FILE = "/script.js";
5206bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    private static final String SCRIPT_LOADED = "Loaded";
5306bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    private static final String SCRIPT_NOT_LOADED = "Not loaded";
5406bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    private static final String SCRIPT_JS = "script_was_loaded = true;";
5506bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth
5606bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    private String getScriptFileTestPageHtml(final String scriptUrl) {
5706bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        return "<html>" +
5806bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "  <head>" +
5906bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "    <title>" + SCRIPT_NOT_LOADED + "</title>" +
6006bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "    <script src='" + scriptUrl + "'></script>" +
6106bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "  </head>" +
6206bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "  <body onload=\"if(script_was_loaded) document.title='" + SCRIPT_LOADED + "'\">" +
6306bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "  </body>" +
6406bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "</html>";
6506bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    }
6606bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth
6706bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    private String getCrossOriginAccessTestPageHtml(final String iframeUrl) {
6806bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        return "<html>" +
6906bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "  <head>" +
7006bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "    <script>" +
71ac5802bca0285eee49c1c372846552823d819181Benjamin Kramer                "      function onload() {" +
72ac5802bca0285eee49c1c372846552823d819181Benjamin Kramer                "        try {" +
73ac5802bca0285eee49c1c372846552823d819181Benjamin Kramer                "          document.title = " +
7406bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "            document.getElementById('frame').contentWindow.location.href;" +
7506bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "        } catch (e) {" +
7606bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "          document.title = 'Exception';" +
7706bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "        }" +
7806bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "      }" +
7906bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "    </script>" +
8006bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "  </head>" +
8106bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "  <body onload='onload()'>" +
8206bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "    <iframe id='frame' src='" + iframeUrl + "'></iframe>" +
8306bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "  </body>" +
8406bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                "</html>";
8506bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    }
8606bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth
8706bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth
8806bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    @SmallTest
8906bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    @Feature({"AndroidWebView"})
9006bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth    public void testImageLoad() throws Throwable {
919d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        TestWebServer webServer = null;
9206bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth        try {
9306bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth            webServer = new TestWebServer(false);
9406bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth            webServer.setResponseBase64("/" + CommonResources.FAVICON_FILENAME,
9506bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth                    CommonResources.FAVICON_DATA_BASE64, CommonResources.getImagePngHeaders(true));
9606bd8ca8c276d9bc20b192188224e1e5215666a0Chandler Carruth
979d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner            AwSettings contentSettings = getAwSettingsOnUiThread(mAwContents);
98b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth            contentSettings.setImagesEnabled(true);
99266451dd95b12323fad9418df9b217918ec7e9e0Chris Lattner            contentSettings.setJavaScriptEnabled(true);
100266451dd95b12323fad9418df9b217918ec7e9e0Chris Lattner
101266451dd95b12323fad9418df9b217918ec7e9e0Chris Lattner            loadDataWithBaseUrlSync(
102266451dd95b12323fad9418df9b217918ec7e9e0Chris Lattner                    CommonResources.getOnImageLoadedHtml(CommonResources.FAVICON_FILENAME),
103266451dd95b12323fad9418df9b217918ec7e9e0Chris Lattner                    "text/html", false, webServer.getBaseUrl(), null);
104bb9dbb7d6b4f39b74b755795e31b219a5518dd77Eli Friedman
105266451dd95b12323fad9418df9b217918ec7e9e0Chris Lattner            assertEquals("5", getTitleOnUiThread(mAwContents));
106266451dd95b12323fad9418df9b217918ec7e9e0Chris Lattner        } finally {
107b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth            if (webServer != null) webServer.shutdown();
1089d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        }
10922e522e08640be459f237796009cf7666d6d75e7Chris Lattner    }
11022e522e08640be459f237796009cf7666d6d75e7Chris Lattner
1119d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    @SmallTest
1129d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    @Feature({"AndroidWebView"})
1139d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    public void testScriptLoad() throws Throwable {
1149d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        TestWebServer webServer = null;
1159d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        try {
116b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth            webServer = new TestWebServer(false);
1179d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
1189d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner            final String scriptUrl = webServer.setResponse(SCRIPT_FILE, SCRIPT_JS,
1199d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner                    CommonResources.getTextJavascriptHeaders(true));
12022e522e08640be459f237796009cf7666d6d75e7Chris Lattner            final String pageHtml = getScriptFileTestPageHtml(scriptUrl);
1219d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
12222e522e08640be459f237796009cf7666d6d75e7Chris Lattner            getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
1239d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner            loadDataWithBaseUrlSync(pageHtml, "text/html", false, webServer.getBaseUrl(), null);
124b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth            assertEquals(SCRIPT_LOADED, getTitleOnUiThread(mAwContents));
125e6f1355c38fb66b0bee35cb4d6ec93f07196d961Benjamin Kramer
126bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        } finally {
127bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis            if (webServer != null) webServer.shutdown();
128bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        }
12979976a40728c8baa8cd16de90173fe2c48937e22Chris Lattner    }
1300db235a2b0ed6ae5c3c870012061906054b6dbc4Argyrios Kyrtzidis
131b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth    @SmallTest
13279976a40728c8baa8cd16de90173fe2c48937e22Chris Lattner    @Feature({"AndroidWebView"})
13379976a40728c8baa8cd16de90173fe2c48937e22Chris Lattner    public void testSameOrigin() throws Throwable {
13479976a40728c8baa8cd16de90173fe2c48937e22Chris Lattner        TestWebServer webServer = null;
135bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        try {
13679976a40728c8baa8cd16de90173fe2c48937e22Chris Lattner            webServer = new TestWebServer(false);
13740dab1059e72d3af59f2523fa8a7d05f40dafca5Chandler Carruth            final String frameUrl = webServer.setResponse("/" + CommonResources.ABOUT_FILENAME,
138b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth                    CommonResources.ABOUT_HTML, CommonResources.getTextHtmlHeaders(true));
13979976a40728c8baa8cd16de90173fe2c48937e22Chris Lattner            final String html = getCrossOriginAccessTestPageHtml(frameUrl);
14079976a40728c8baa8cd16de90173fe2c48937e22Chris Lattner
14179976a40728c8baa8cd16de90173fe2c48937e22Chris Lattner            getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
142bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis            loadDataWithBaseUrlSync(html, "text/html", false, webServer.getBaseUrl(), null);
143bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis            assertEquals(frameUrl, getTitleOnUiThread(mAwContents));
144bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis
145bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        } finally {
146bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis            if (webServer != null) webServer.shutdown();
147bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        }
148bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis    }
149bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis
1509d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    @SmallTest
1519d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    @Feature({"AndroidWebView"})
1529d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    public void testCrossOrigin() throws Throwable {
1539d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        TestWebServer webServer = null;
1549d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        try {
1559d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner            webServer = new TestWebServer(false);
156b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth            final String frameUrl = webServer.setResponse("/" + CommonResources.ABOUT_FILENAME,
157b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth                    CommonResources.ABOUT_HTML, CommonResources.getTextHtmlHeaders(true));
1589d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner            final String html = getCrossOriginAccessTestPageHtml(frameUrl);
15922e522e08640be459f237796009cf7666d6d75e7Chris Lattner            final String baseUrl = webServer.getBaseUrl().replaceFirst("localhost", "127.0.0.1");
1609d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
161b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth            getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
1629d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner            loadDataWithBaseUrlSync(html, "text/html", false, baseUrl, null);
1639d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
1649d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner            assertEquals("Exception", getTitleOnUiThread(mAwContents));
1659d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
1669d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        } finally {
1679d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner            if (webServer != null) webServer.shutdown();
168b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth        }
1692edc74aa1fb541253f4286a70194960dab69506bChris Lattner    }
1702edc74aa1fb541253f4286a70194960dab69506bChris Lattner
1712edc74aa1fb541253f4286a70194960dab69506bChris Lattner    @SmallTest
1722edc74aa1fb541253f4286a70194960dab69506bChris Lattner    @Feature({"AndroidWebView"})
1732edc74aa1fb541253f4286a70194960dab69506bChris Lattner    public void testNullBaseUrl() throws Throwable {
1742edc74aa1fb541253f4286a70194960dab69506bChris Lattner        getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
1752edc74aa1fb541253f4286a70194960dab69506bChris Lattner        final String pageHtml = "<html><body onload='document.title=document.location.href'>" +
1769d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner                "</body></html>";
1779d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        loadDataWithBaseUrlSync(pageHtml, "text/html", false, null, null);
178b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth        assertEquals("about:blank", getTitleOnUiThread(mAwContents));
1799d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    }
1809d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
1819d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    @SmallTest
1829d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    @Feature({"AndroidWebView"})
1839d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    public void testloadDataWithBaseUrlCallsOnPageStarted() throws Throwable {
184b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth        final String baseUrl = "http://base.com/";
1859d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        TestCallbackHelperContainer.OnPageStartedHelper onPageStartedHelper =
18622e522e08640be459f237796009cf7666d6d75e7Chris Lattner                mContentsClient.getOnPageStartedHelper();
1879d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        final int callCount = onPageStartedHelper.getCallCount();
1889d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        loadDataWithBaseUrlAsync(mAwContents, CommonResources.ABOUT_HTML, "text/html", false,
1899d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner                baseUrl, "about:blank");
190b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth        onPageStartedHelper.waitForCallback(callCount);
1919d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        assertEquals(baseUrl, onPageStartedHelper.getUrl());
1929d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    }
1939d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
194b4c28fc93f5149a0bd7967af44c429412e751c56Chandler Carruth    @SmallTest
1952edc74aa1fb541253f4286a70194960dab69506bChris Lattner    @Feature({"AndroidWebView"})
1962edc74aa1fb541253f4286a70194960dab69506bChris Lattner    public void testHistoryUrl() throws Throwable {
1972edc74aa1fb541253f4286a70194960dab69506bChris Lattner
1982edc74aa1fb541253f4286a70194960dab69506bChris Lattner        final String pageHtml = "<html><body>Hello, world!</body></html>";
1992edc74aa1fb541253f4286a70194960dab69506bChris Lattner        final String baseUrl = "http://example.com";
2002edc74aa1fb541253f4286a70194960dab69506bChris Lattner        // TODO(mnaganov): Use the same string as Android CTS suite uses
2012edc74aa1fb541253f4286a70194960dab69506bChris Lattner        // once GURL issue is resolved (http://code.google.com/p/google-url/issues/detail?id=29)
2022edc74aa1fb541253f4286a70194960dab69506bChris Lattner        final String historyUrl = "http://history.com/";
2039d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, historyUrl);
2049d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        assertEquals(historyUrl, HistoryUtils.getUrlOnUiThread(
205840635741f132a9a10f052cbf3b21e14bc74835aChris Lattner                getInstrumentation(), mWebContents));
2069d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
2079d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, null);
2089d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        assertEquals("about:blank", HistoryUtils.getUrlOnUiThread(
2099d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner                getInstrumentation(), mWebContents));
2109d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    }
2119d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
2129d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner    @SmallTest
213bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis    @Feature({"AndroidWebView"})
214bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis    public void testOnPageFinishedUrlIsBaseUrl() throws Throwable {
2150b1bcbf6b87f19402d8aef1ef9f6e527a07de9d4Chandler Carruth        final String pageHtml = "<html><body>Hello, world!</body></html>";
2160b1bcbf6b87f19402d8aef1ef9f6e527a07de9d4Chandler Carruth        final String baseUrl = "http://example.com/";
2170b1bcbf6b87f19402d8aef1ef9f6e527a07de9d4Chandler Carruth        loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, baseUrl);
218bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, baseUrl);
219bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
220bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis                mContentsClient.getOnPageFinishedHelper();
221bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        assertEquals(baseUrl, onPageFinishedHelper.getUrl());
222bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis    }
223bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis
224bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis    @SmallTest
225bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis    @Feature({"AndroidWebView"})
226bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis    public void testHistoryUrlIgnoredWithDataSchemeBaseUrl() throws Throwable {
22740dab1059e72d3af59f2523fa8a7d05f40dafca5Chandler Carruth        final String pageHtml = "<html><body>bar</body></html>";
228bb07f21c76f011d8dde491104ff242af30bfb4abArgyrios Kyrtzidis        final String historyUrl = "http://history.com/";
229147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        loadDataWithBaseUrlSync(pageHtml, "text/html", false, "data:foo", historyUrl);
230147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        assertEquals("data:text/html," + pageHtml, HistoryUtils.getUrlOnUiThread(
231147d9e05116518461653695a6022f6109f0eb936Chandler Carruth                getInstrumentation(), mWebContents));
232147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    }
233147d9e05116518461653695a6022f6109f0eb936Chandler Carruth
234147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    /*
235147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    @SmallTest
236147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    @Feature({"AndroidWebView"})
237147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    http://crbug.com/173274
238147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    */
239147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    @DisabledTest
240147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    public void testHistoryUrlNavigation() throws Throwable {
241147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        TestWebServer webServer = null;
242147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        try {
243147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            webServer = new TestWebServer(false);
244147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            final String historyUrl = webServer.setResponse("/" + CommonResources.ABOUT_FILENAME,
245147d9e05116518461653695a6022f6109f0eb936Chandler Carruth                    CommonResources.ABOUT_HTML, CommonResources.getTextHtmlHeaders(true));
246147d9e05116518461653695a6022f6109f0eb936Chandler Carruth
247147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            final String page1Title = "Page1";
248147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            final String page1Html = "<html><head><title>" + page1Title + "</title>" +
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    "<body>" + page1Title + "</body></html>";
250147d9e05116518461653695a6022f6109f0eb936Chandler Carruth
251147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            loadDataWithBaseUrlSync(page1Html, "text/html", false, null, historyUrl);
252147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            assertEquals(page1Title, getTitleOnUiThread(mAwContents));
253147d9e05116518461653695a6022f6109f0eb936Chandler Carruth
254147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            final String page2Title = "Page2";
255147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            final String page2Html = "<html><head><title>" + page2Title + "</title>" +
256147d9e05116518461653695a6022f6109f0eb936Chandler Carruth                    "<body>" + page2Title + "</body></html>";
257147d9e05116518461653695a6022f6109f0eb936Chandler Carruth
258147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
259147d9e05116518461653695a6022f6109f0eb936Chandler Carruth                    mContentsClient.getOnPageFinishedHelper();
260147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            loadDataSync(mAwContents, onPageFinishedHelper, page2Html, "text/html", false);
261147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            assertEquals(page2Title, getTitleOnUiThread(mAwContents));
262147d9e05116518461653695a6022f6109f0eb936Chandler Carruth
263147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            HistoryUtils.goBackSync(getInstrumentation(), mWebContents, onPageFinishedHelper);
264147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            // The title of the 'about.html' specified via historyUrl.
265147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            assertEquals(CommonResources.ABOUT_TITLE, getTitleOnUiThread(mAwContents));
266147d9e05116518461653695a6022f6109f0eb936Chandler Carruth
267147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        } finally {
268147d9e05116518461653695a6022f6109f0eb936Chandler Carruth            if (webServer != null) webServer.shutdown();
269147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        }
270147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    }
271147d9e05116518461653695a6022f6109f0eb936Chandler Carruth
27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /**
273147d9e05116518461653695a6022f6109f0eb936Chandler Carruth     * @return true if |fileUrl| was accessible from a data url with |baseUrl| as it's
274147d9e05116518461653695a6022f6109f0eb936Chandler Carruth     * base URL.
275147d9e05116518461653695a6022f6109f0eb936Chandler Carruth     */
276147d9e05116518461653695a6022f6109f0eb936Chandler Carruth    private boolean canAccessFileFromData(String baseUrl, String fileUrl) throws Throwable {
277147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        final String imageLoaded = "LOADED";
278147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        final String imageNotLoaded = "NOT_LOADED";
279147d9e05116518461653695a6022f6109f0eb936Chandler Carruth        String data = "<html><body>" +
280147d9e05116518461653695a6022f6109f0eb936Chandler Carruth                "<img src=\"" + fileUrl + "\" " +
281147d9e05116518461653695a6022f6109f0eb936Chandler Carruth                "onload=\"document.title=\'" + imageLoaded + "\';\" " +
282147d9e05116518461653695a6022f6109f0eb936Chandler Carruth                "onerror=\"document.title=\'" + imageNotLoaded + "\';\" />" +
283147d9e05116518461653695a6022f6109f0eb936Chandler Carruth                "</body></html>";
2849d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
2859d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        loadDataWithBaseUrlSync(data, "text/html", false, baseUrl, null);
2869d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner
2879d69d4aadd4a58aba5634d5c3d2c2a6d8d284134Chris Lattner        poll(new Callable<Boolean>() {
288            @Override
289            public Boolean call() throws Exception {
290                String title = getTitleOnUiThread(mAwContents);
291                return imageLoaded.equals(title) || imageNotLoaded.equals(title);
292            }
293        });
294
295        return imageLoaded.equals(getTitleOnUiThread(mAwContents));
296    }
297
298    @SmallTest
299    @Feature({"AndroidWebView"})
300    public void testLoadDataWithBaseUrlAccessingFile() throws Throwable {
301        // Create a temporary file on the filesystem we can try to read.
302        File cacheDir = getActivity().getCacheDir();
303        File tempImage = File.createTempFile("test_image", ".png", cacheDir);
304        Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565);
305        FileOutputStream fos = new FileOutputStream(tempImage);
306        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
307        fos.close();
308        String imagePath = tempImage.getAbsolutePath();
309
310        AwSettings contentSettings = getAwSettingsOnUiThread(mAwContents);
311        contentSettings.setImagesEnabled(true);
312        contentSettings.setJavaScriptEnabled(true);
313
314        try {
315            final String dataBaseUrl = "data:";
316            final String nonDataBaseUrl = "http://example.com";
317
318            mAwContents.getSettings().setAllowFileAccess(false);
319            String token = "" + System.currentTimeMillis();
320            // All access to file://, including android_asset and android_res is blocked
321            // with a data: base URL, regardless of AwSettings.getAllowFileAccess().
322            assertFalse(canAccessFileFromData(dataBaseUrl,
323                  "file:///android_asset/asset_icon.png?" + token));
324            assertFalse(canAccessFileFromData(dataBaseUrl,
325                  "file:///android_res/raw/resource_icon.png?" + token));
326            assertFalse(canAccessFileFromData(dataBaseUrl, "file://" + imagePath + "?" + token));
327
328            // WebView always has access to android_asset and android_res for non-data
329            // base URLs and can access other file:// URLs based on the value of
330            // AwSettings.getAllowFileAccess().
331            assertTrue(canAccessFileFromData(nonDataBaseUrl,
332                  "file:///android_asset/asset_icon.png?" + token));
333            assertTrue(canAccessFileFromData(nonDataBaseUrl,
334                  "file:///android_res/raw/resource_icon.png?" + token));
335            assertFalse(canAccessFileFromData(nonDataBaseUrl,
336                  "file://" + imagePath + "?" + token));
337
338            token += "a";
339            mAwContents.getSettings().setAllowFileAccess(true);
340            // We should still be unable to access any file:// with when loading with a
341            // data: base URL, but we should now be able to access the wider file system
342            // (still restricted by OS-level permission checks) with a non-data base URL.
343            assertFalse(canAccessFileFromData(dataBaseUrl,
344                  "file:///android_asset/asset_icon.png?" + token));
345            assertFalse(canAccessFileFromData(dataBaseUrl,
346                  "file:///android_res/raw/resource_icon.png?" + token));
347            assertFalse(canAccessFileFromData(dataBaseUrl, "file://" + imagePath + "?" + token));
348
349            assertTrue(canAccessFileFromData(nonDataBaseUrl,
350                  "file:///android_asset/asset_icon.png?" + token));
351            assertTrue(canAccessFileFromData(nonDataBaseUrl,
352                  "file:///android_res/raw/resource_icon.png?" + token));
353            assertTrue(canAccessFileFromData(nonDataBaseUrl,
354                  "file://" + imagePath + "?" + token));
355        } finally {
356            if (!tempImage.delete()) throw new AssertionError();
357        }
358    }
359}
360