1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.android_webview.test;
7 import android.content.Context;
8 import android.graphics.Point;
9 import android.net.http.SslError;
10 import android.os.Build;
11 import android.os.SystemClock;
12 import android.test.suitebuilder.annotation.MediumTest;
13 import android.test.suitebuilder.annotation.SmallTest;
14 import android.view.WindowManager;
15 import android.webkit.JavascriptInterface;
16 import android.webkit.ValueCallback;
17 import android.webkit.WebSettings;
19 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
21 import org.apache.http.Header;
22 import org.apache.http.HttpRequest;
23 import org.chromium.android_webview.AwContents;
24 import org.chromium.android_webview.AwContentsClient.ShouldInterceptRequestParams;
25 import org.chromium.android_webview.AwSettings;
26 import org.chromium.android_webview.AwSettings.LayoutAlgorithm;
27 import org.chromium.android_webview.AwWebResourceResponse;
28 import org.chromium.android_webview.test.util.CommonResources;
29 import org.chromium.android_webview.test.util.ImagePageGenerator;
30 import org.chromium.android_webview.test.util.VideoTestUtil;
31 import org.chromium.android_webview.test.util.VideoTestWebServer;
32 import org.chromium.base.test.util.DisabledTest;
33 import org.chromium.base.test.util.Feature;
34 import org.chromium.base.test.util.TestFileUtil;
35 import org.chromium.base.test.util.UrlUtils;
36 import org.chromium.content.browser.ContentViewCore;
37 import org.chromium.content.browser.test.util.CallbackHelper;
38 import org.chromium.content.browser.test.util.HistoryUtils;
39 import org.chromium.net.test.util.TestWebServer;
40 import org.chromium.ui.gfx.DeviceDisplayInfo;
43 import java.util.concurrent.Callable;
44 import java.util.concurrent.TimeUnit;
45 import java.util.regex.Matcher;
46 import java.util.regex.Pattern;
49 * A test suite for AwSettings class. The key objective is to verify that each
50 * settings applies either to each individual view or to all views of the
53 public class AwSettingsTest extends AwTestBase {
54 private static final boolean ENABLED = true;
55 private static final boolean DISABLED = false;
58 * A helper class for testing a particular preference from AwSettings.
59 * The generic type T is the type of the setting. Usually, to test an
60 * effect of the preference, JS code is executed that sets document's title.
61 * In this case, requiresJsEnabled constructor argument must be set to true.
63 abstract class AwSettingsTestHelper<T> {
64 protected final AwContents mAwContents;
65 protected final Context mContext;
66 protected final TestAwContentsClient mContentViewClient;
67 protected final AwSettings mAwSettings;
69 AwSettingsTestHelper(AwTestContainerView containerView,
70 TestAwContentsClient contentViewClient,
71 boolean requiresJsEnabled) throws Throwable {
72 mAwContents = containerView.getAwContents();
73 mContext = containerView.getContext();
74 mContentViewClient = contentViewClient;
75 mAwSettings = AwSettingsTest.this.getAwSettingsOnUiThread(mAwContents);
76 if (requiresJsEnabled) {
77 mAwSettings.setJavaScriptEnabled(true);
81 void ensureSettingHasAlteredValue() throws Throwable {
82 ensureSettingHasValue(getAlteredValue());
85 void ensureSettingHasInitialValue() throws Throwable {
86 ensureSettingHasValue(getInitialValue());
89 void setAlteredSettingValue() throws Throwable {
90 setCurrentValue(getAlteredValue());
93 void setInitialSettingValue() throws Throwable {
94 setCurrentValue(getInitialValue());
97 protected abstract T getAlteredValue();
99 protected abstract T getInitialValue();
101 protected abstract T getCurrentValue();
103 protected abstract void setCurrentValue(T value) throws Throwable;
105 protected abstract void doEnsureSettingHasValue(T value) throws Throwable;
107 protected String getTitleOnUiThread() throws Exception {
108 return AwSettingsTest.this.getTitleOnUiThread(mAwContents);
111 protected void loadDataSync(String data) throws Throwable {
112 AwSettingsTest.this.loadDataSync(
114 mContentViewClient.getOnPageFinishedHelper(),
120 protected void loadUrlSync(String url) throws Throwable {
121 AwSettingsTest.this.loadUrlSync(
123 mContentViewClient.getOnPageFinishedHelper(),
127 protected void loadUrlSyncAndExpectError(String url) throws Throwable {
128 AwSettingsTest.this.loadUrlSyncAndExpectError(
130 mContentViewClient.getOnPageFinishedHelper(),
131 mContentViewClient.getOnReceivedErrorHelper(),
135 protected String executeJavaScriptAndWaitForResult(String script) throws Exception {
136 return AwSettingsTest.this.executeJavaScriptAndWaitForResult(
137 mAwContents, mContentViewClient, script);
140 private void ensureSettingHasValue(T value) throws Throwable {
141 assertEquals(value, getCurrentValue());
142 doEnsureSettingHasValue(value);
146 class AwSettingsJavaScriptTestHelper extends AwSettingsTestHelper<Boolean> {
147 private static final String JS_ENABLED_STRING = "JS Enabled";
148 private static final String JS_DISABLED_STRING = "JS Disabled";
150 AwSettingsJavaScriptTestHelper(AwTestContainerView containerView,
151 TestAwContentsClient contentViewClient) throws Throwable {
152 super(containerView, contentViewClient, false);
156 protected Boolean getAlteredValue() {
161 protected Boolean getInitialValue() {
166 protected Boolean getCurrentValue() {
167 return mAwSettings.getJavaScriptEnabled();
171 protected void setCurrentValue(Boolean value) {
172 mAwSettings.setJavaScriptEnabled(value);
176 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
177 loadDataSync(getData());
179 value == ENABLED ? JS_ENABLED_STRING : JS_DISABLED_STRING,
180 getTitleOnUiThread());
183 private String getData() {
184 return "<html><head><title>" + JS_DISABLED_STRING + "</title>"
185 + "</head><body onload=\"document.title='" + JS_ENABLED_STRING
186 + "';\"></body></html>";
190 // In contrast to AwSettingsJavaScriptTestHelper, doesn't reload the page when testing
192 class AwSettingsJavaScriptDynamicTestHelper extends AwSettingsJavaScriptTestHelper {
193 AwSettingsJavaScriptDynamicTestHelper(
194 AwTestContainerView containerView,
195 TestAwContentsClient contentViewClient) throws Throwable {
196 super(containerView, contentViewClient);
198 super.doEnsureSettingHasValue(getInitialValue());
202 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
203 String oldTitle = getTitleOnUiThread();
204 String newTitle = oldTitle + "_modified";
205 executeJavaScriptAndWaitForResult(getScript(newTitle));
206 assertEquals(value == ENABLED ? newTitle : oldTitle, getTitleOnUiThread());
209 private String getScript(String title) {
210 return "document.title='" + title + "';";
214 class AwSettingsPluginsTestHelper extends AwSettingsTestHelper<Boolean> {
215 private static final String PLUGINS_ENABLED_STRING = "Embed";
216 private static final String PLUGINS_DISABLED_STRING = "NoEmbed";
218 AwSettingsPluginsTestHelper(AwTestContainerView containerView,
219 TestAwContentsClient contentViewClient) throws Throwable {
220 super(containerView, contentViewClient, true);
224 protected Boolean getAlteredValue() {
229 protected Boolean getInitialValue() {
234 protected Boolean getCurrentValue() {
235 return mAwSettings.getPluginsEnabled();
239 protected void setCurrentValue(Boolean value) {
240 mAwSettings.setPluginsEnabled(value);
244 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
245 loadDataSync(getData());
247 value == ENABLED ? PLUGINS_ENABLED_STRING : PLUGINS_DISABLED_STRING,
248 getTitleOnUiThread());
251 private String getData() {
252 return "<html><body onload=\"document.title = document.body.innerText;\">"
253 + "<noembed>No</noembed><span>Embed</span></body></html>";
257 class AwSettingsStandardFontFamilyTestHelper extends AwSettingsTestHelper<String> {
258 AwSettingsStandardFontFamilyTestHelper(
259 AwTestContainerView containerView,
260 TestAwContentsClient contentViewClient) throws Throwable {
261 super(containerView, contentViewClient, true);
265 protected String getAlteredValue() {
270 protected String getInitialValue() {
275 protected String getCurrentValue() {
276 return mAwSettings.getStandardFontFamily();
280 protected void setCurrentValue(String value) {
281 mAwSettings.setStandardFontFamily(value);
285 protected void doEnsureSettingHasValue(String value) throws Throwable {
286 loadDataSync(getData());
287 assertEquals(value, getTitleOnUiThread());
290 private String getData() {
291 return "<html><body onload=\"document.title = " +
292 "getComputedStyle(document.body).getPropertyValue('font-family');\">"
297 class AwSettingsDefaultFontSizeTestHelper extends AwSettingsTestHelper<Integer> {
298 AwSettingsDefaultFontSizeTestHelper(
299 AwTestContainerView containerView,
300 TestAwContentsClient contentViewClient) throws Throwable {
301 super(containerView, contentViewClient, true);
305 protected Integer getAlteredValue() {
310 protected Integer getInitialValue() {
315 protected Integer getCurrentValue() {
316 return mAwSettings.getDefaultFontSize();
320 protected void setCurrentValue(Integer value) {
321 mAwSettings.setDefaultFontSize(value);
325 protected void doEnsureSettingHasValue(Integer value) throws Throwable {
326 loadDataSync(getData());
327 assertEquals(value.toString() + "px", getTitleOnUiThread());
330 private String getData() {
331 return "<html><body onload=\"document.title = " +
332 "getComputedStyle(document.body).getPropertyValue('font-size');\">"
337 class AwSettingsLoadImagesAutomaticallyTestHelper extends AwSettingsTestHelper<Boolean> {
338 private ImagePageGenerator mGenerator;
340 AwSettingsLoadImagesAutomaticallyTestHelper(
341 AwTestContainerView containerView,
342 TestAwContentsClient contentViewClient,
343 ImagePageGenerator generator) throws Throwable {
344 super(containerView, contentViewClient, true);
345 mGenerator = generator;
349 protected Boolean getAlteredValue() {
354 protected Boolean getInitialValue() {
359 protected Boolean getCurrentValue() {
360 return mAwSettings.getLoadsImagesAutomatically();
364 protected void setCurrentValue(Boolean value) {
365 mAwSettings.setLoadsImagesAutomatically(value);
369 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
370 loadDataSync(mGenerator.getPageSource());
371 assertEquals(value == ENABLED ?
372 ImagePageGenerator.IMAGE_LOADED_STRING :
373 ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
374 getTitleOnUiThread());
379 class AwSettingsImagesEnabledHelper extends AwSettingsTestHelper<Boolean> {
381 AwSettingsImagesEnabledHelper(
382 AwTestContainerView containerView,
383 TestAwContentsClient contentViewClient,
384 TestWebServer webServer,
385 ImagePageGenerator generator) throws Throwable {
386 super(containerView, contentViewClient, true);
387 mWebServer = webServer;
388 mGenerator = generator;
392 protected Boolean getAlteredValue() {
397 protected Boolean getInitialValue() {
402 protected Boolean getCurrentValue() {
403 return mAwSettings.getImagesEnabled();
407 protected void setCurrentValue(Boolean value) {
408 mAwSettings.setImagesEnabled(value);
412 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
413 final String httpImageUrl = mGenerator.getPageUrl(mWebServer);
414 AwSettingsTest.this.loadUrlSync(
416 mContentViewClient.getOnPageFinishedHelper(),
418 assertEquals(value == ENABLED ?
419 ImagePageGenerator.IMAGE_LOADED_STRING :
420 ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
421 getTitleOnUiThread());
424 private TestWebServer mWebServer;
425 private ImagePageGenerator mGenerator;
428 class AwSettingsDefaultTextEncodingTestHelper extends AwSettingsTestHelper<String> {
429 AwSettingsDefaultTextEncodingTestHelper(
430 AwTestContainerView containerView,
431 TestAwContentsClient contentViewClient) throws Throwable {
432 super(containerView, contentViewClient, true);
436 protected String getAlteredValue() {
441 protected String getInitialValue() {
446 protected String getCurrentValue() {
447 return mAwSettings.getDefaultTextEncodingName();
451 protected void setCurrentValue(String value) {
452 mAwSettings.setDefaultTextEncodingName(value);
456 protected void doEnsureSettingHasValue(String value) throws Throwable {
457 loadDataSync(getData());
458 assertEquals(value, getTitleOnUiThread());
461 private String getData() {
462 return "<html><body onload='document.title=document.defaultCharset'></body></html>";
466 class AwSettingsUserAgentStringTestHelper extends AwSettingsTestHelper<String> {
467 private final String mDefaultUa;
468 private static final String DEFAULT_UA = "";
469 private static final String CUSTOM_UA = "ChromeViewTest";
471 AwSettingsUserAgentStringTestHelper(
472 AwTestContainerView containerView,
473 TestAwContentsClient contentViewClient) throws Throwable {
474 super(containerView, contentViewClient, true);
475 mDefaultUa = mAwSettings.getUserAgentString();
479 protected String getAlteredValue() {
484 protected String getInitialValue() {
489 protected String getCurrentValue() {
490 // The test framework expects that getXXX() == Z after setXXX(Z).
491 // But setUserAgentString("" / null) resets the UA string to default,
492 // and getUserAgentString returns the default UA string afterwards.
493 // To align with the framework, we return an empty string instead of
495 String currentUa = mAwSettings.getUserAgentString();
496 return mDefaultUa.equals(currentUa) ? DEFAULT_UA : currentUa;
500 protected void setCurrentValue(String value) {
501 mAwSettings.setUserAgentString(value);
505 protected void doEnsureSettingHasValue(String value) throws Throwable {
506 loadDataSync(getData());
508 DEFAULT_UA.equals(value) ? mDefaultUa : value,
509 getTitleOnUiThread());
512 private String getData() {
513 return "<html><body onload='document.title=navigator.userAgent'></body></html>";
517 class AwSettingsDomStorageEnabledTestHelper extends AwSettingsTestHelper<Boolean> {
518 private static final String TEST_FILE = "webview/localStorage.html";
519 private static final String NO_LOCAL_STORAGE = "No localStorage";
520 private static final String HAS_LOCAL_STORAGE = "Has localStorage";
522 AwSettingsDomStorageEnabledTestHelper(
523 AwTestContainerView containerView,
524 TestAwContentsClient contentViewClient) throws Throwable {
525 super(containerView, contentViewClient, true);
526 AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_FILE));
530 protected Boolean getAlteredValue() {
535 protected Boolean getInitialValue() {
540 protected Boolean getCurrentValue() {
541 return mAwSettings.getDomStorageEnabled();
545 protected void setCurrentValue(Boolean value) {
546 mAwSettings.setDomStorageEnabled(value);
550 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
551 // It is not permitted to access localStorage from data URLs in WebKit,
552 // that is why a standalone page must be used.
553 loadUrlSync(UrlUtils.getTestFileUrl(TEST_FILE));
555 value == ENABLED ? HAS_LOCAL_STORAGE : NO_LOCAL_STORAGE,
556 getTitleOnUiThread());
560 class AwSettingsDatabaseTestHelper extends AwSettingsTestHelper<Boolean> {
561 private static final String TEST_FILE = "webview/database_access.html";
562 private static final String NO_DATABASE = "No database";
563 private static final String HAS_DATABASE = "Has database";
565 AwSettingsDatabaseTestHelper(
566 AwTestContainerView containerView,
567 TestAwContentsClient contentViewClient) throws Throwable {
568 super(containerView, contentViewClient, true);
569 AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_FILE));
573 protected Boolean getAlteredValue() {
578 protected Boolean getInitialValue() {
583 protected Boolean getCurrentValue() {
584 return mAwSettings.getDatabaseEnabled();
588 protected void setCurrentValue(Boolean value) {
589 mAwSettings.setDatabaseEnabled(value);
593 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
594 // It seems accessing the database through a data scheme is not
595 // supported, and fails with a DOM exception (likely a cross-domain
597 loadUrlSync(UrlUtils.getTestFileUrl(TEST_FILE));
599 value == ENABLED ? HAS_DATABASE : NO_DATABASE,
600 getTitleOnUiThread());
604 class AwSettingsUniversalAccessFromFilesTestHelper extends AwSettingsTestHelper<Boolean> {
605 private static final String TEST_CONTAINER_FILE = "webview/iframe_access.html";
606 private static final String TEST_FILE = "webview/hello_world.html";
607 private static final String ACCESS_DENIED_TITLE = "Exception";
609 AwSettingsUniversalAccessFromFilesTestHelper(
610 AwTestContainerView containerView,
611 TestAwContentsClient contentViewClient) throws Throwable {
612 super(containerView, contentViewClient, true);
613 AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_CONTAINER_FILE));
614 AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_FILE));
615 mIframeContainerUrl = UrlUtils.getTestFileUrl(TEST_CONTAINER_FILE);
616 mIframeUrl = UrlUtils.getTestFileUrl(TEST_FILE);
617 // The value of the setting depends on the SDK version.
618 mAwSettings.setAllowUniversalAccessFromFileURLs(false);
619 // If universal access is true, the value of file access doesn't
620 // matter. While if universal access is false, having file access
621 // enabled will allow file loading.
622 mAwSettings.setAllowFileAccessFromFileURLs(false);
626 protected Boolean getAlteredValue() {
631 protected Boolean getInitialValue() {
636 protected Boolean getCurrentValue() {
637 return mAwSettings.getAllowUniversalAccessFromFileURLs();
641 protected void setCurrentValue(Boolean value) {
642 mAwSettings.setAllowUniversalAccessFromFileURLs(value);
646 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
647 loadUrlSync(mIframeContainerUrl);
649 value == ENABLED ? mIframeUrl : ACCESS_DENIED_TITLE,
650 getTitleOnUiThread());
653 private final String mIframeContainerUrl;
654 private final String mIframeUrl;
657 class AwSettingsFileAccessFromFilesIframeTestHelper extends AwSettingsTestHelper<Boolean> {
658 private static final String TEST_CONTAINER_FILE = "webview/iframe_access.html";
659 private static final String TEST_FILE = "webview/hello_world.html";
660 private static final String ACCESS_DENIED_TITLE = "Exception";
662 AwSettingsFileAccessFromFilesIframeTestHelper(
663 AwTestContainerView containerView,
664 TestAwContentsClient contentViewClient) throws Throwable {
665 super(containerView, contentViewClient, true);
666 AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_CONTAINER_FILE));
667 AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_FILE));
668 mIframeContainerUrl = UrlUtils.getTestFileUrl(TEST_CONTAINER_FILE);
669 mIframeUrl = UrlUtils.getTestFileUrl(TEST_FILE);
670 mAwSettings.setAllowUniversalAccessFromFileURLs(false);
671 // The value of the setting depends on the SDK version.
672 mAwSettings.setAllowFileAccessFromFileURLs(false);
676 protected Boolean getAlteredValue() {
681 protected Boolean getInitialValue() {
686 protected Boolean getCurrentValue() {
687 return mAwSettings.getAllowFileAccessFromFileURLs();
691 protected void setCurrentValue(Boolean value) {
692 mAwSettings.setAllowFileAccessFromFileURLs(value);
696 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
697 loadUrlSync(mIframeContainerUrl);
699 value == ENABLED ? mIframeUrl : ACCESS_DENIED_TITLE,
700 getTitleOnUiThread());
703 private final String mIframeContainerUrl;
704 private final String mIframeUrl;
707 class AwSettingsFileAccessFromFilesXhrTestHelper extends AwSettingsTestHelper<Boolean> {
708 private static final String TEST_FILE = "webview/xhr_access.html";
709 private static final String ACCESS_GRANTED_TITLE = "Hello, World!";
710 private static final String ACCESS_DENIED_TITLE = "Exception";
712 AwSettingsFileAccessFromFilesXhrTestHelper(
713 AwTestContainerView containerView,
714 TestAwContentsClient contentViewClient) throws Throwable {
715 super(containerView, contentViewClient, true);
716 assertFileIsReadable(UrlUtils.getTestFilePath(TEST_FILE));
717 mXhrContainerUrl = UrlUtils.getTestFileUrl(TEST_FILE);
718 mAwSettings.setAllowUniversalAccessFromFileURLs(false);
719 // The value of the setting depends on the SDK version.
720 mAwSettings.setAllowFileAccessFromFileURLs(false);
724 protected Boolean getAlteredValue() {
729 protected Boolean getInitialValue() {
734 protected Boolean getCurrentValue() {
735 return mAwSettings.getAllowFileAccessFromFileURLs();
739 protected void setCurrentValue(Boolean value) {
740 mAwSettings.setAllowFileAccessFromFileURLs(value);
744 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
745 loadUrlSync(mXhrContainerUrl);
747 value == ENABLED ? ACCESS_GRANTED_TITLE : ACCESS_DENIED_TITLE,
748 getTitleOnUiThread());
751 private final String mXhrContainerUrl;
754 class AwSettingsFileUrlAccessTestHelper extends AwSettingsTestHelper<Boolean> {
755 private static final String TEST_FILE = "webview/hello_world.html";
756 private static final String ACCESS_GRANTED_TITLE = "Hello, World!";
758 AwSettingsFileUrlAccessTestHelper(
759 AwTestContainerView containerView,
760 TestAwContentsClient contentViewClient,
761 int startIndex) throws Throwable {
762 super(containerView, contentViewClient, true);
764 AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_FILE));
768 protected Boolean getAlteredValue() {
773 protected Boolean getInitialValue() {
778 protected Boolean getCurrentValue() {
779 return mAwSettings.getAllowFileAccess();
783 protected void setCurrentValue(Boolean value) {
784 mAwSettings.setAllowFileAccess(value);
788 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
789 // Use query parameters to avoid hitting a cached page.
790 String fileUrl = UrlUtils.getTestFileUrl(TEST_FILE + "?id=" + mIndex);
792 if (value == ENABLED) {
793 loadUrlSync(fileUrl);
794 assertEquals(ACCESS_GRANTED_TITLE, getTitleOnUiThread());
796 loadUrlSyncAndExpectError(fileUrl);
803 class AwSettingsContentUrlAccessTestHelper extends AwSettingsTestHelper<Boolean> {
805 AwSettingsContentUrlAccessTestHelper(
806 AwTestContainerView containerView,
807 TestAwContentsClient contentViewClient,
808 int index) throws Throwable {
809 super(containerView, contentViewClient, true);
810 mTarget = "content_access_" + index;
814 protected Boolean getAlteredValue() {
819 protected Boolean getInitialValue() {
824 protected Boolean getCurrentValue() {
825 return mAwSettings.getAllowContentAccess();
829 protected void setCurrentValue(Boolean value) {
830 mAwSettings.setAllowContentAccess(value);
834 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
835 AwSettingsTest.this.resetResourceRequestCountInContentProvider(mTarget);
836 if (value == ENABLED) {
837 loadUrlSync(AwSettingsTest.this.createContentUrl(mTarget));
838 String title = getTitleOnUiThread();
839 assertTrue(title != null);
840 assertTrue("[" + mTarget + "] Actual title: \"" + title + "\"",
841 title.contains(mTarget));
842 AwSettingsTest.this.ensureResourceRequestCountInContentProvider(mTarget, 1);
844 loadUrlSyncAndExpectError(AwSettingsTest.this.createContentUrl(mTarget));
845 AwSettingsTest.this.ensureResourceRequestCountInContentProvider(mTarget, 0);
849 private final String mTarget;
852 class AwSettingsContentUrlAccessFromFileTestHelper extends AwSettingsTestHelper<Boolean> {
853 private static final String TARGET = "content_from_file";
855 AwSettingsContentUrlAccessFromFileTestHelper(
856 AwTestContainerView containerView,
857 TestAwContentsClient contentViewClient,
858 int index) throws Throwable {
859 super(containerView, contentViewClient, true);
861 mTempDir = getInstrumentation().getTargetContext().getCacheDir().getPath();
865 protected Boolean getAlteredValue() {
870 protected Boolean getInitialValue() {
875 protected Boolean getCurrentValue() {
876 return mAwSettings.getAllowContentAccess();
880 protected void setCurrentValue(Boolean value) {
881 mAwSettings.setAllowContentAccess(value);
885 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
886 AwSettingsTest.this.resetResourceRequestCountInContentProvider(TARGET);
887 final String fileName = mTempDir + "/" + TARGET + ".html";
889 TestFileUtil.createNewHtmlFile(fileName,
892 // Adding a query avoids hitting a cached image, and also verifies
893 // that content URL query parameters are ignored when accessing
894 // a content provider.
895 AwSettingsTest.this.createContentUrl(TARGET + "?id=" + mIndex) + "\">");
897 loadUrlSync("file://" + fileName);
898 if (value == ENABLED) {
899 AwSettingsTest.this.ensureResourceRequestCountInContentProvider(TARGET, 1);
901 AwSettingsTest.this.ensureResourceRequestCountInContentProvider(TARGET, 0);
904 TestFileUtil.deleteFile(fileName);
909 private String mTempDir;
912 // This class provides helper methods for testing of settings related to
913 // the text autosizing feature.
914 abstract class AwSettingsTextAutosizingTestHelper<T> extends AwSettingsTestHelper<T> {
915 protected static final float PARAGRAPH_FONT_SIZE = 14.0f;
917 AwSettingsTextAutosizingTestHelper(
918 AwTestContainerView containerView,
919 TestAwContentsClient contentViewClient) throws Throwable {
920 super(containerView, contentViewClient, true);
921 mNeedToWaitForFontSizeChange = false;
922 loadDataSync(getData());
926 protected void setCurrentValue(T value) throws Throwable {
927 mNeedToWaitForFontSizeChange = false;
928 if (value != getCurrentValue()) {
929 mOldFontSize = getActualFontSize();
930 mNeedToWaitForFontSizeChange = true;
934 protected float getActualFontSize() throws Throwable {
935 if (!mNeedToWaitForFontSizeChange) {
936 executeJavaScriptAndWaitForResult("setTitleToActualFontSize()");
938 final float oldFontSize = mOldFontSize;
939 poll(new Callable<Boolean>() {
941 public Boolean call() throws Exception {
942 executeJavaScriptAndWaitForResult("setTitleToActualFontSize()");
943 float newFontSize = Float.parseFloat(getTitleOnUiThread());
944 return newFontSize != oldFontSize;
947 mNeedToWaitForFontSizeChange = false;
949 return Float.parseFloat(getTitleOnUiThread());
952 protected String getData() {
953 DeviceDisplayInfo deviceInfo = DeviceDisplayInfo.create(mContext);
954 int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
955 int layoutWidth = (int) (displayWidth * 2.5f); // Use 2.5 as autosizing layout tests do.
956 StringBuilder sb = new StringBuilder();
959 "<meta name=\"viewport\" content=\"width=" + layoutWidth + "\">" +
961 "body { width: " + layoutWidth + "px; margin: 0; overflow-y: hidden; }" +
964 "function setTitleToActualFontSize() {" +
965 // parseFloat is used to trim out the "px" suffix.
966 " document.title = parseFloat(getComputedStyle(" +
967 " document.getElementById('par')).getPropertyValue('font-size'));" +
968 "}</script></head>" +
970 "<p id=\"par\" style=\"font-size:");
971 sb.append(PARAGRAPH_FONT_SIZE);
973 // Make the paragraph wide enough for being processed by the font autosizer.
974 for (int i = 0; i < 500; i++) {
975 sb.append("Hello, World! ");
977 sb.append("</p></body></html>");
978 return sb.toString();
981 private boolean mNeedToWaitForFontSizeChange;
982 private float mOldFontSize;
985 class AwSettingsLayoutAlgorithmTestHelper extends
986 AwSettingsTextAutosizingTestHelper<LayoutAlgorithm> {
988 AwSettingsLayoutAlgorithmTestHelper(
989 AwTestContainerView containerView,
990 TestAwContentsClient contentViewClient) throws Throwable {
991 super(containerView, contentViewClient);
992 // Font autosizing doesn't step in for narrow layout widths.
993 mAwSettings.setUseWideViewPort(true);
997 protected LayoutAlgorithm getAlteredValue() {
998 return LayoutAlgorithm.TEXT_AUTOSIZING;
1002 protected LayoutAlgorithm getInitialValue() {
1003 return LayoutAlgorithm.NARROW_COLUMNS;
1007 protected LayoutAlgorithm getCurrentValue() {
1008 return mAwSettings.getLayoutAlgorithm();
1012 protected void setCurrentValue(LayoutAlgorithm value) throws Throwable {
1013 super.setCurrentValue(value);
1014 mAwSettings.setLayoutAlgorithm(value);
1018 protected void doEnsureSettingHasValue(LayoutAlgorithm value) throws Throwable {
1019 final float actualFontSize = getActualFontSize();
1020 if (value == LayoutAlgorithm.TEXT_AUTOSIZING) {
1021 assertFalse("Actual font size: " + actualFontSize,
1022 actualFontSize == PARAGRAPH_FONT_SIZE);
1024 assertTrue("Actual font size: " + actualFontSize,
1025 actualFontSize == PARAGRAPH_FONT_SIZE);
1030 class AwSettingsTextZoomTestHelper extends AwSettingsTextAutosizingTestHelper<Integer> {
1031 private static final int INITIAL_TEXT_ZOOM = 100;
1032 private final float mInitialActualFontSize;
1034 AwSettingsTextZoomTestHelper(
1035 AwTestContainerView containerView,
1036 TestAwContentsClient contentViewClient) throws Throwable {
1037 super(containerView, contentViewClient);
1038 mInitialActualFontSize = getActualFontSize();
1042 protected Integer getAlteredValue() {
1043 return INITIAL_TEXT_ZOOM * 2;
1047 protected Integer getInitialValue() {
1048 return INITIAL_TEXT_ZOOM;
1052 protected Integer getCurrentValue() {
1053 return mAwSettings.getTextZoom();
1057 protected void setCurrentValue(Integer value) throws Throwable {
1058 super.setCurrentValue(value);
1059 mAwSettings.setTextZoom(value);
1063 protected void doEnsureSettingHasValue(Integer value) throws Throwable {
1064 final float actualFontSize = getActualFontSize();
1065 // Ensure that actual vs. initial font size ratio is similar to actual vs. initial
1066 // text zoom values ratio.
1067 final float ratiosDelta = Math.abs(
1068 (actualFontSize / mInitialActualFontSize) -
1069 (value / (float) INITIAL_TEXT_ZOOM));
1071 "|(" + actualFontSize + " / " + mInitialActualFontSize + ") - (" +
1072 value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta,
1073 ratiosDelta <= 0.2f);
1077 class AwSettingsTextZoomAutosizingTestHelper
1078 extends AwSettingsTextAutosizingTestHelper<Integer> {
1079 private static final int INITIAL_TEXT_ZOOM = 100;
1080 private final float mInitialActualFontSize;
1082 AwSettingsTextZoomAutosizingTestHelper(
1083 AwTestContainerView containerView,
1084 TestAwContentsClient contentViewClient) throws Throwable {
1085 super(containerView, contentViewClient);
1086 mAwSettings.setLayoutAlgorithm(LayoutAlgorithm.TEXT_AUTOSIZING);
1087 // The initial font size can be adjusted by font autosizer depending on the page's
1089 mInitialActualFontSize = getActualFontSize();
1093 protected Integer getAlteredValue() {
1094 return INITIAL_TEXT_ZOOM * 2;
1098 protected Integer getInitialValue() {
1099 return INITIAL_TEXT_ZOOM;
1103 protected Integer getCurrentValue() {
1104 return mAwSettings.getTextZoom();
1108 protected void setCurrentValue(Integer value) throws Throwable {
1109 super.setCurrentValue(value);
1110 mAwSettings.setTextZoom(value);
1114 protected void doEnsureSettingHasValue(Integer value) throws Throwable {
1115 final float actualFontSize = getActualFontSize();
1116 // Ensure that actual vs. initial font size ratio is similar to actual vs. initial
1117 // text zoom values ratio.
1118 final float ratiosDelta = Math.abs(
1119 (actualFontSize / mInitialActualFontSize) -
1120 (value / (float) INITIAL_TEXT_ZOOM));
1122 "|(" + actualFontSize + " / " + mInitialActualFontSize + ") - (" +
1123 value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta,
1124 ratiosDelta <= 0.2f);
1128 class AwSettingsJavaScriptPopupsTestHelper extends AwSettingsTestHelper<Boolean> {
1129 private static final String POPUP_ENABLED = "Popup enabled";
1130 private static final String POPUP_BLOCKED = "Popup blocked";
1132 AwSettingsJavaScriptPopupsTestHelper(
1133 AwTestContainerView containerView,
1134 TestAwContentsClient contentViewClient) throws Throwable {
1135 super(containerView, contentViewClient, true);
1139 protected Boolean getAlteredValue() {
1144 protected Boolean getInitialValue() {
1149 protected Boolean getCurrentValue() {
1150 return mAwSettings.getJavaScriptCanOpenWindowsAutomatically();
1154 protected void setCurrentValue(Boolean value) {
1155 mAwSettings.setJavaScriptCanOpenWindowsAutomatically(value);
1159 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
1160 loadDataSync(getData());
1161 final boolean expectPopupEnabled = value;
1162 poll(new Callable<Boolean>() {
1164 public Boolean call() throws Exception {
1165 String title = getTitleOnUiThread();
1166 return expectPopupEnabled ? POPUP_ENABLED.equals(title) :
1167 POPUP_BLOCKED.equals(title);
1170 assertEquals(value ? POPUP_ENABLED : POPUP_BLOCKED, getTitleOnUiThread());
1173 private String getData() {
1174 return "<html><head>" +
1176 " function tryOpenWindow() {" +
1177 " var newWindow = window.open(" +
1178 " 'data:text/html;charset=utf-8," +
1179 " <html><head><title>" + POPUP_ENABLED + "</title></head></html>');" +
1180 " if (!newWindow) document.title = '" + POPUP_BLOCKED + "';" +
1182 "</script></head>" +
1183 "<body onload='tryOpenWindow()'></body></html>";
1187 class AwSettingsCacheModeTestHelper extends AwSettingsTestHelper<Integer> {
1189 AwSettingsCacheModeTestHelper(
1190 AwTestContainerView containerView,
1191 TestAwContentsClient contentViewClient,
1193 TestWebServer webServer) throws Throwable {
1194 super(containerView, contentViewClient, true);
1196 mWebServer = webServer;
1200 protected Integer getAlteredValue() {
1201 // We use the value that results in a behaviour completely opposite to default.
1202 return WebSettings.LOAD_CACHE_ONLY;
1206 protected Integer getInitialValue() {
1207 return WebSettings.LOAD_DEFAULT;
1211 protected Integer getCurrentValue() {
1212 return mAwSettings.getCacheMode();
1216 protected void setCurrentValue(Integer value) {
1217 mAwSettings.setCacheMode(value);
1221 protected void doEnsureSettingHasValue(Integer value) throws Throwable {
1222 final String htmlPath = "/cache_mode_" + mIndex + ".html";
1224 final String url = mWebServer.setResponse(htmlPath, "response", null);
1225 assertEquals(0, mWebServer.getRequestCount(htmlPath));
1226 if (value == WebSettings.LOAD_DEFAULT) {
1228 assertEquals(1, mWebServer.getRequestCount(htmlPath));
1230 loadUrlSyncAndExpectError(url);
1231 assertEquals(0, mWebServer.getRequestCount(htmlPath));
1236 private TestWebServer mWebServer;
1239 // To verify whether UseWideViewport works, we check, if the page width specified
1240 // in the "meta viewport" tag is applied. When UseWideViewport is turned off, the
1241 // "viewport" tag is ignored, and the layout width is set to device width in DIP pixels.
1242 // We specify a very high width value to make sure that it doesn't intersect with
1243 // device screen widths (in DIP pixels).
1244 class AwSettingsUseWideViewportTestHelper extends AwSettingsTestHelper<Boolean> {
1245 private static final String VIEWPORT_TAG_LAYOUT_WIDTH = "3000";
1247 AwSettingsUseWideViewportTestHelper(
1248 AwTestContainerView containerView,
1249 TestAwContentsClient contentViewClient) throws Throwable {
1250 super(containerView, contentViewClient, true);
1254 protected Boolean getAlteredValue() {
1259 protected Boolean getInitialValue() {
1264 protected Boolean getCurrentValue() {
1265 return mAwSettings.getUseWideViewPort();
1269 protected void setCurrentValue(Boolean value) {
1270 mAwSettings.setUseWideViewPort(value);
1274 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
1275 loadDataSync(getData());
1276 final String bodyWidth = getTitleOnUiThread();
1278 assertTrue(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth));
1280 assertFalse(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth));
1284 private String getData() {
1285 return "<html><head>" +
1286 "<meta name='viewport' content='width=" + VIEWPORT_TAG_LAYOUT_WIDTH + "' />" +
1288 "<body onload='document.title=document.body.clientWidth'></body></html>";
1292 class AwSettingsLoadWithOverviewModeTestHelper extends AwSettingsTestHelper<Boolean> {
1293 private static final float DEFAULT_PAGE_SCALE = 1.0f;
1295 AwSettingsLoadWithOverviewModeTestHelper(
1296 AwTestContainerView containerView,
1297 TestAwContentsClient contentViewClient,
1298 boolean withViewPortTag) throws Throwable {
1299 super(containerView, contentViewClient, true);
1300 mWithViewPortTag = withViewPortTag;
1301 mAwSettings.setUseWideViewPort(true);
1305 protected Boolean getAlteredValue() {
1310 protected Boolean getInitialValue() {
1315 protected Boolean getCurrentValue() {
1316 return mAwSettings.getLoadWithOverviewMode();
1320 protected void setCurrentValue(Boolean value) {
1321 mExpectScaleChange = mAwSettings.getLoadWithOverviewMode() != value;
1322 if (mExpectScaleChange) {
1323 mOnScaleChangedCallCount =
1324 mContentViewClient.getOnScaleChangedHelper().getCallCount();
1326 mAwSettings.setLoadWithOverviewMode(value);
1330 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
1331 loadDataSync(getData());
1332 if (mExpectScaleChange) {
1333 mContentViewClient.getOnScaleChangedHelper().
1334 waitForCallback(mOnScaleChangedCallCount);
1335 mExpectScaleChange = false;
1337 float currentScale = AwSettingsTest.this.getScaleOnUiThread(mAwContents);
1339 assertTrue("Expected: " + currentScale + " < " + DEFAULT_PAGE_SCALE,
1340 currentScale < DEFAULT_PAGE_SCALE);
1342 assertEquals(DEFAULT_PAGE_SCALE, currentScale);
1346 private String getData() {
1347 return "<html><head>" +
1348 (mWithViewPortTag ? "<meta name='viewport' content='width=3000' />" : "") +
1350 "<body></body></html>";
1353 private final boolean mWithViewPortTag;
1354 private boolean mExpectScaleChange;
1355 private int mOnScaleChangedCallCount;
1358 class AwSettingsForceZeroLayoutHeightTestHelper extends AwSettingsTestHelper<Boolean> {
1360 AwSettingsForceZeroLayoutHeightTestHelper(
1361 AwTestContainerView containerView,
1362 TestAwContentsClient contentViewClient,
1363 boolean withViewPortTag) throws Throwable {
1364 super(containerView, contentViewClient, true);
1365 mWithViewPortTag = withViewPortTag;
1366 mAwSettings.setUseWideViewPort(true);
1370 protected Boolean getAlteredValue() {
1375 protected Boolean getInitialValue() {
1380 protected Boolean getCurrentValue() {
1381 return mAwSettings.getForceZeroLayoutHeight();
1385 protected void setCurrentValue(Boolean value) {
1386 mAwSettings.setForceZeroLayoutHeight(value);
1390 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
1391 loadDataSync(getData());
1392 int height = Integer.parseInt(getTitleOnUiThread());
1394 assertEquals(0, height);
1396 assertTrue("Div should be at least 50px high, was: " + height, height >= 50);
1400 private String getData() {
1401 return "<html><head>" +
1402 (mWithViewPortTag ? "<meta name='viewport' content='height=3000' />" : "") +
1403 " <script type='text/javascript'> " +
1404 " window.addEventListener('load', function(event) { " +
1405 " document.title = document.getElementById('testDiv').clientHeight; " +
1410 " <div style='height:50px;'>test</div> " +
1411 " <div id='testDiv' style='height:100%;'></div> " +
1415 private final boolean mWithViewPortTag;
1418 class AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper extends
1419 AwSettingsTestHelper<Boolean> {
1421 AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper(
1422 AwTestContainerView containerView,
1423 TestAwContentsClient contentViewClient) throws Throwable {
1424 super(containerView, contentViewClient, true);
1425 mAwSettings.setUseWideViewPort(true);
1426 mAwSettings.setForceZeroLayoutHeight(true);
1430 protected Boolean getAlteredValue() {
1435 protected Boolean getInitialValue() {
1440 protected Boolean getCurrentValue() {
1441 return mAwSettings.getZeroLayoutHeightDisablesViewportQuirk();
1445 protected void setCurrentValue(Boolean value) {
1446 mAwSettings.setZeroLayoutHeightDisablesViewportQuirk(value);
1450 protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
1451 DeviceDisplayInfo deviceInfo = DeviceDisplayInfo.create(mContext);
1452 int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
1454 loadDataSync(getData());
1455 int width = Integer.parseInt(getTitleOnUiThread());
1457 assertEquals(displayWidth, width);
1459 assertEquals(3000, width);
1463 private String getData() {
1464 return "<html><head>" +
1465 "<meta name='viewport' content='width=3000' />" +
1466 " <script type='text/javascript'> " +
1467 " window.addEventListener('load', function(event) { " +
1468 " document.title = document.documentElement.clientWidth; " +
1473 " <div style='height:50px;'>test</div> " +
1474 " <div id='testDiv' style='height:100%;'></div> " +
1479 // The test verifies that JavaScript is disabled upon WebView
1480 // creation without accessing AwSettings. If the test passes,
1481 // it means that WebView-specific web preferences configuration
1482 // is applied on WebView creation. JS state is used, because it is
1483 // enabled by default in Chrome, but must be disabled by default
1486 @Feature({"AndroidWebView", "Preferences"})
1487 public void testJavaScriptDisabledByDefault() throws Throwable {
1488 final String JS_ENABLED_STRING = "JS has run";
1489 final String JS_DISABLED_STRING = "JS has not run";
1490 final String TEST_PAGE_HTML =
1491 "<html><head><title>" + JS_DISABLED_STRING + "</title>"
1492 + "</head><body onload=\"document.title='" + JS_ENABLED_STRING
1493 + "';\"></body></html>";
1494 final TestAwContentsClient contentClient = new TestAwContentsClient();
1495 final AwTestContainerView testContainerView =
1496 createAwTestContainerViewOnMainSync(contentClient);
1497 final AwContents awContents = testContainerView.getAwContents();
1500 contentClient.getOnPageFinishedHelper(),
1504 assertEquals(JS_DISABLED_STRING, getTitleOnUiThread(awContents));
1508 @Feature({"AndroidWebView", "Preferences"})
1509 public void testJavaScriptEnabledWithTwoViews() throws Throwable {
1510 ViewPair views = createViews();
1511 runPerViewSettingsTest(
1512 new AwSettingsJavaScriptTestHelper(views.getContainer0(), views.getClient0()),
1513 new AwSettingsJavaScriptTestHelper(views.getContainer1(), views.getClient1()));
1517 @Feature({"AndroidWebView", "Preferences"})
1518 public void testJavaScriptEnabledDynamicWithTwoViews() throws Throwable {
1519 ViewPair views = createViews();
1520 runPerViewSettingsTest(
1521 new AwSettingsJavaScriptDynamicTestHelper(views.getContainer0(), views.getClient0()),
1522 new AwSettingsJavaScriptDynamicTestHelper(views.getContainer1(), views.getClient1()));
1526 @Feature({"AndroidWebView", "Preferences"})
1527 public void testPluginsEnabledWithTwoViews() throws Throwable {
1528 ViewPair views = createViews();
1529 runPerViewSettingsTest(
1530 new AwSettingsPluginsTestHelper(views.getContainer0(), views.getClient0()),
1531 new AwSettingsPluginsTestHelper(views.getContainer1(), views.getClient1()));
1535 @Feature({"AndroidWebView", "Preferences"})
1536 public void testStandardFontFamilyWithTwoViews() throws Throwable {
1537 ViewPair views = createViews();
1538 runPerViewSettingsTest(
1539 new AwSettingsStandardFontFamilyTestHelper(views.getContainer0(), views.getClient0()),
1540 new AwSettingsStandardFontFamilyTestHelper(views.getContainer1(), views.getClient1()));
1544 @Feature({"AndroidWebView", "Preferences"})
1545 public void testDefaultFontSizeWithTwoViews() throws Throwable {
1546 ViewPair views = createViews();
1547 runPerViewSettingsTest(
1548 new AwSettingsDefaultFontSizeTestHelper(views.getContainer0(), views.getClient0()),
1549 new AwSettingsDefaultFontSizeTestHelper(views.getContainer1(), views.getClient1()));
1552 // The test verifies that after changing the LoadsImagesAutomatically
1553 // setting value from false to true previously skipped images are
1554 // automatically loaded.
1556 @Feature({"AndroidWebView", "Preferences"})
1557 public void testLoadsImagesAutomaticallyNoPageReload() throws Throwable {
1558 final TestAwContentsClient contentClient = new TestAwContentsClient();
1559 final AwTestContainerView testContainerView =
1560 createAwTestContainerViewOnMainSync(contentClient);
1561 final AwContents awContents = testContainerView.getAwContents();
1562 AwSettings settings = getAwSettingsOnUiThread(awContents);
1563 settings.setJavaScriptEnabled(true);
1564 ImagePageGenerator generator = new ImagePageGenerator(0, false);
1565 settings.setLoadsImagesAutomatically(false);
1566 loadDataSync(awContents,
1567 contentClient.getOnPageFinishedHelper(),
1568 generator.getPageSource(),
1569 "text/html", false);
1570 assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
1571 getTitleOnUiThread(awContents));
1572 settings.setLoadsImagesAutomatically(true);
1573 poll(new Callable<Boolean>() {
1575 public Boolean call() throws Exception {
1576 return !ImagePageGenerator.IMAGE_NOT_LOADED_STRING.equals(
1577 getTitleOnUiThread(awContents));
1580 assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, getTitleOnUiThread(awContents));
1585 @Feature({"AndroidWebView", "Preferences"})
1586 public void testLoadsImagesAutomaticallyWithTwoViews() throws Throwable {
1587 ViewPair views = createViews();
1588 runPerViewSettingsTest(
1589 new AwSettingsLoadImagesAutomaticallyTestHelper(
1590 views.getContainer0(), views.getClient0(), new ImagePageGenerator(0, true)),
1591 new AwSettingsLoadImagesAutomaticallyTestHelper(
1592 views.getContainer1(), views.getClient1(), new ImagePageGenerator(1, true)));
1596 @Feature({"AndroidWebView", "Preferences"})
1597 public void testDefaultTextEncodingWithTwoViews() throws Throwable {
1598 ViewPair views = createViews();
1599 runPerViewSettingsTest(
1600 new AwSettingsDefaultTextEncodingTestHelper(views.getContainer0(), views.getClient0()),
1601 new AwSettingsDefaultTextEncodingTestHelper(views.getContainer1(), views.getClient1()));
1604 // The test verifies that the default user agent string follows the format
1605 // defined in Android CTS tests:
1607 // Mozilla/5.0 (Linux;[ U;] Android <version>;[ <language>-<country>;]
1608 // [<devicemodel>;] Build/<buildID>) AppleWebKit/<major>.<minor> (KHTML, like Gecko)
1609 // Version/<major>.<minor>[ Mobile] Safari/<major>.<minor>
1611 @Feature({"AndroidWebView", "Preferences"})
1612 public void testUserAgentStringDefault() throws Throwable {
1613 final TestAwContentsClient contentClient = new TestAwContentsClient();
1614 final AwTestContainerView testContainerView =
1615 createAwTestContainerViewOnMainSync(contentClient);
1616 final AwContents awContents = testContainerView.getAwContents();
1617 AwSettings settings = getAwSettingsOnUiThread(awContents);
1618 final String actualUserAgentString = settings.getUserAgentString();
1619 assertEquals(actualUserAgentString, AwSettings.getDefaultUserAgent());
1620 final String patternString =
1621 "Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?" +
1622 "\\s?(.*)\\sBuild/(.+)\\) AppleWebKit/(\\d+)\\.(\\d+) \\(KHTML, like Gecko\\) " +
1623 "Version/\\d+\\.\\d Chrome/\\d+\\.\\d+\\.\\d+\\.\\d+" +
1624 "( Mobile)? Safari/(\\d+)\\.(\\d+)";
1625 final Pattern userAgentExpr = Pattern.compile(patternString);
1626 Matcher patternMatcher = userAgentExpr.matcher(actualUserAgentString);
1627 assertTrue(String.format("User agent string did not match expected pattern. %nExpected " +
1628 "pattern:%n%s%nActual:%n%s", patternString, actualUserAgentString),
1629 patternMatcher.find());
1630 // No country-language code token.
1631 assertEquals(null, patternMatcher.group(3));
1632 if ("REL".equals(Build.VERSION.CODENAME)) {
1633 // Model is only added in release builds
1634 assertEquals(Build.MODEL, patternMatcher.group(6));
1635 // Release version is valid only in release builds
1636 assertEquals(Build.VERSION.RELEASE, patternMatcher.group(2));
1638 assertEquals(Build.ID, patternMatcher.group(7));
1642 @Feature({"AndroidWebView", "Preferences"})
1643 public void testUserAgentStringOverride() throws Throwable {
1644 final TestAwContentsClient contentClient = new TestAwContentsClient();
1645 final AwTestContainerView testContainerView =
1646 createAwTestContainerViewOnMainSync(contentClient);
1647 final AwContents awContents = testContainerView.getAwContents();
1648 AwSettings settings = getAwSettingsOnUiThread(awContents);
1649 final String defaultUserAgentString = settings.getUserAgentString();
1651 // Check that an attempt to reset the default UA string has no effect.
1652 settings.setUserAgentString(null);
1653 assertEquals(defaultUserAgentString, settings.getUserAgentString());
1654 settings.setUserAgentString("");
1655 assertEquals(defaultUserAgentString, settings.getUserAgentString());
1657 // Check that we can also set the default value.
1658 settings.setUserAgentString(defaultUserAgentString);
1659 assertEquals(defaultUserAgentString, settings.getUserAgentString());
1661 // Set a custom UA string, verify that it can be reset back to default.
1662 final String customUserAgentString = "AwSettingsTest";
1663 settings.setUserAgentString(customUserAgentString);
1664 assertEquals(customUserAgentString, settings.getUserAgentString());
1665 settings.setUserAgentString(null);
1666 assertEquals(defaultUserAgentString, settings.getUserAgentString());
1669 // Verify that the current UA override setting has a priority over UA
1670 // overrides in navigation history entries.
1672 @Feature({"AndroidWebView", "Preferences"})
1673 public void testUserAgentStringOverrideForHistory() throws Throwable {
1674 final TestAwContentsClient contentClient = new TestAwContentsClient();
1675 final AwTestContainerView testContainerView =
1676 createAwTestContainerViewOnMainSync(contentClient);
1677 final AwContents awContents = testContainerView.getAwContents();
1678 final ContentViewCore contentView = testContainerView.getContentViewCore();
1679 CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
1680 AwSettings settings = getAwSettingsOnUiThread(awContents);
1681 settings.setJavaScriptEnabled(true);
1682 final String defaultUserAgentString = settings.getUserAgentString();
1683 final String customUserAgentString = "AwSettingsTest";
1684 // We are using different page titles to make sure that we are really
1685 // going back and forward between them.
1686 final String pageTemplate =
1687 "<html><head><title>%s</title></head>" +
1688 "<body onload='document.title+=navigator.userAgent'></body>" +
1690 final String page1Title = "Page1";
1691 final String page2Title = "Page2";
1692 final String page1 = String.format(pageTemplate, page1Title);
1693 final String page2 = String.format(pageTemplate, page2Title);
1694 settings.setUserAgentString(customUserAgentString);
1696 awContents, onPageFinishedHelper, page1, "text/html", false);
1697 assertEquals(page1Title + customUserAgentString, getTitleOnUiThread(awContents));
1699 awContents, onPageFinishedHelper, page2, "text/html", false);
1700 assertEquals(page2Title + customUserAgentString, getTitleOnUiThread(awContents));
1701 settings.setUserAgentString(null);
1702 // Must not cause any changes until the next page loading.
1703 assertEquals(page2Title + customUserAgentString, getTitleOnUiThread(awContents));
1704 HistoryUtils.goBackSync(getInstrumentation(), contentView, onPageFinishedHelper);
1705 assertEquals(page1Title + defaultUserAgentString, getTitleOnUiThread(awContents));
1706 HistoryUtils.goForwardSync(getInstrumentation(), contentView,
1707 onPageFinishedHelper);
1708 assertEquals(page2Title + defaultUserAgentString, getTitleOnUiThread(awContents));
1712 @Feature({"AndroidWebView", "Preferences"})
1713 public void testUserAgentStringWithTwoViews() throws Throwable {
1714 ViewPair views = createViews();
1715 runPerViewSettingsTest(
1716 new AwSettingsUserAgentStringTestHelper(views.getContainer0(), views.getClient0()),
1717 new AwSettingsUserAgentStringTestHelper(views.getContainer1(), views.getClient1()));
1721 @Feature({"AndroidWebView", "Preferences"})
1722 public void testUserAgentWithTestServer() throws Throwable {
1723 final TestAwContentsClient contentClient = new TestAwContentsClient();
1724 final AwTestContainerView testContainerView =
1725 createAwTestContainerViewOnMainSync(contentClient);
1726 AwContents awContents = testContainerView.getAwContents();
1727 AwSettings settings = getAwSettingsOnUiThread(awContents);
1728 final String customUserAgentString =
1729 "testUserAgentWithTestServerUserAgent";
1731 TestWebServer webServer = null;
1732 String fileName = null;
1734 webServer = new TestWebServer(false);
1735 final String httpPath = "/testUserAgentWithTestServer.html";
1736 final String url = webServer.setResponse(httpPath, "foo", null);
1738 settings.setUserAgentString(customUserAgentString);
1739 loadUrlSync(awContents,
1740 contentClient.getOnPageFinishedHelper(),
1743 assertEquals(1, webServer.getRequestCount(httpPath));
1744 HttpRequest request = webServer.getLastRequest(httpPath);
1745 Header[] matchingHeaders = request.getHeaders("User-Agent");
1746 assertEquals(1, matchingHeaders.length);
1748 Header header = matchingHeaders[0];
1749 assertEquals(customUserAgentString, header.getValue());
1751 if (webServer != null) webServer.shutdown();
1756 @Feature({"AndroidWebView", "Preferences"})
1757 public void testDomStorageEnabledWithTwoViews() throws Throwable {
1758 ViewPair views = createViews();
1759 runPerViewSettingsTest(
1760 new AwSettingsDomStorageEnabledTestHelper(views.getContainer0(), views.getClient0()),
1761 new AwSettingsDomStorageEnabledTestHelper(views.getContainer1(), views.getClient1()));
1764 // Ideally, these three tests below should be combined into one, or tested using
1765 // runPerViewSettingsTest. However, it seems the database setting cannot be toggled
1766 // once set. Filed b/8186497.
1768 @Feature({"AndroidWebView", "Preferences"})
1769 public void testDatabaseInitialValue() throws Throwable {
1770 TestAwContentsClient client = new TestAwContentsClient();
1771 final AwTestContainerView testContainerView =
1772 createAwTestContainerViewOnMainSync(client);
1773 AwSettingsDatabaseTestHelper helper =
1774 new AwSettingsDatabaseTestHelper(testContainerView, client);
1775 helper.ensureSettingHasInitialValue();
1779 @Feature({"AndroidWebView", "Preferences"})
1780 public void testDatabaseEnabled() throws Throwable {
1781 TestAwContentsClient client = new TestAwContentsClient();
1782 final AwTestContainerView testContainerView =
1783 createAwTestContainerViewOnMainSync(client);
1784 AwSettingsDatabaseTestHelper helper =
1785 new AwSettingsDatabaseTestHelper(testContainerView, client);
1786 helper.setAlteredSettingValue();
1787 helper.ensureSettingHasAlteredValue();
1791 @Feature({"AndroidWebView", "Preferences"})
1792 public void testDatabaseDisabled() throws Throwable {
1793 TestAwContentsClient client = new TestAwContentsClient();
1794 final AwTestContainerView testContainerView =
1795 createAwTestContainerViewOnMainSync(client);
1796 AwSettingsDatabaseTestHelper helper =
1797 new AwSettingsDatabaseTestHelper(testContainerView, client);
1798 helper.setInitialSettingValue();
1799 helper.ensureSettingHasInitialValue();
1803 @Feature({"AndroidWebView", "Preferences"})
1804 public void testUniversalAccessFromFilesWithTwoViews() throws Throwable {
1805 ViewPair views = createViews();
1806 runPerViewSettingsTest(
1807 new AwSettingsUniversalAccessFromFilesTestHelper(views.getContainer0(),
1808 views.getClient0()),
1809 new AwSettingsUniversalAccessFromFilesTestHelper(views.getContainer1(),
1810 views.getClient1()));
1813 // This test verifies that local image resources can be loaded from file:
1814 // URLs regardless of file access state.
1816 @Feature({"AndroidWebView", "Preferences"})
1817 public void testFileAccessFromFilesImage() throws Throwable {
1818 final String testFile = "webview/image_access.html";
1819 assertFileIsReadable(UrlUtils.getTestFilePath(testFile));
1820 final String imageContainerUrl = UrlUtils.getTestFileUrl(testFile);
1821 final String imageHeight = "16";
1822 final TestAwContentsClient contentClient = new TestAwContentsClient();
1823 final AwTestContainerView testContainerView =
1824 createAwTestContainerViewOnMainSync(contentClient);
1825 final AwContents awContents = testContainerView.getAwContents();
1826 AwSettings settings = getAwSettingsOnUiThread(awContents);
1827 settings.setJavaScriptEnabled(true);
1828 settings.setAllowUniversalAccessFromFileURLs(false);
1829 settings.setAllowFileAccessFromFileURLs(false);
1830 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), imageContainerUrl);
1831 assertEquals(imageHeight, getTitleOnUiThread(awContents));
1835 @Feature({"AndroidWebView", "Preferences"})
1836 public void testFileAccessFromFilesIframeWithTwoViews() throws Throwable {
1837 ViewPair views = createViews();
1838 runPerViewSettingsTest(
1839 new AwSettingsFileAccessFromFilesIframeTestHelper(
1840 views.getContainer0(), views.getClient0()),
1841 new AwSettingsFileAccessFromFilesIframeTestHelper(
1842 views.getContainer1(), views.getClient1()));
1846 @Feature({"AndroidWebView", "Preferences"})
1847 public void testFileAccessFromFilesXhrWithTwoViews() throws Throwable {
1848 ViewPair views = createViews();
1849 runPerViewSettingsTest(
1850 new AwSettingsFileAccessFromFilesXhrTestHelper(views.getContainer0(),
1851 views.getClient0()),
1852 new AwSettingsFileAccessFromFilesXhrTestHelper(views.getContainer1(),
1853 views.getClient1()));
1857 @Feature({"AndroidWebView", "Preferences"})
1858 public void testFileUrlAccessWithTwoViews() throws Throwable {
1859 ViewPair views = createViews();
1860 runPerViewSettingsTest(
1861 new AwSettingsFileUrlAccessTestHelper(views.getContainer0(), views.getClient0(), 0),
1862 new AwSettingsFileUrlAccessTestHelper(views.getContainer1(), views.getClient1(), 1));
1866 @Feature({"AndroidWebView", "Preferences"})
1867 public void testContentUrlAccessWithTwoViews() throws Throwable {
1868 ViewPair views = createViews();
1869 runPerViewSettingsTest(
1870 new AwSettingsContentUrlAccessTestHelper(views.getContainer0(), views.getClient0(), 0),
1871 new AwSettingsContentUrlAccessTestHelper(views.getContainer1(), views.getClient1(), 1));
1875 @Feature({"AndroidWebView", "Preferences", "Navigation"})
1876 public void testBlockingContentUrlsFromDataUrls() throws Throwable {
1877 final TestAwContentsClient contentClient = new TestAwContentsClient();
1878 final AwTestContainerView testContainerView =
1879 createAwTestContainerViewOnMainSync(contentClient);
1880 final AwContents awContents = testContainerView.getAwContents();
1881 final String target = "content_from_data";
1882 final String page = "<html><body>" +
1884 createContentUrl(target) + "\">" +
1886 resetResourceRequestCountInContentProvider(target);
1889 contentClient.getOnPageFinishedHelper(),
1893 ensureResourceRequestCountInContentProvider(target, 0);
1897 @Feature({"AndroidWebView", "Preferences", "Navigation"})
1898 public void testContentUrlFromFileWithTwoViews() throws Throwable {
1899 ViewPair views = createViews();
1900 runPerViewSettingsTest(
1901 new AwSettingsContentUrlAccessFromFileTestHelper(
1902 views.getContainer0(), views.getClient0(), 0),
1903 new AwSettingsContentUrlAccessFromFileTestHelper(
1904 views.getContainer1(), views.getClient1(), 1));
1908 // @Feature({"AndroidWebView", "Preferences"})
1909 // http://crbug.com/387101
1911 public void testBlockNetworkImagesDoesNotBlockDataUrlImage() throws Throwable {
1912 final TestAwContentsClient contentClient = new TestAwContentsClient();
1913 final AwTestContainerView testContainerView =
1914 createAwTestContainerViewOnMainSync(contentClient);
1915 final AwContents awContents = testContainerView.getAwContents();
1916 final AwSettings settings = getAwSettingsOnUiThread(awContents);
1917 ImagePageGenerator generator = new ImagePageGenerator(0, false);
1919 settings.setJavaScriptEnabled(true);
1920 settings.setImagesEnabled(false);
1921 loadDataSync(awContents,
1922 contentClient.getOnPageFinishedHelper(),
1923 generator.getPageSource(),
1926 assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, getTitleOnUiThread(awContents));
1930 @Feature({"AndroidWebView", "Preferences"})
1931 public void testBlockNetworkImagesBlocksNetworkImageAndReloadInPlace() throws Throwable {
1932 final TestAwContentsClient contentClient = new TestAwContentsClient();
1933 final AwTestContainerView testContainerView =
1934 createAwTestContainerViewOnMainSync(contentClient);
1935 final AwContents awContents = testContainerView.getAwContents();
1936 final AwSettings settings = getAwSettingsOnUiThread(awContents);
1937 settings.setJavaScriptEnabled(true);
1938 ImagePageGenerator generator = new ImagePageGenerator(0, false);
1940 TestWebServer webServer = null;
1942 webServer = new TestWebServer(false);
1943 final String httpImageUrl = generator.getPageUrl(webServer);
1945 settings.setImagesEnabled(false);
1946 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), httpImageUrl);
1947 assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
1948 getTitleOnUiThread(awContents));
1950 settings.setImagesEnabled(true);
1951 poll(new Callable<Boolean>() {
1953 public Boolean call() throws Exception {
1954 return ImagePageGenerator.IMAGE_LOADED_STRING.equals(
1955 getTitleOnUiThread(awContents));
1959 if (webServer != null) webServer.shutdown();
1964 @Feature({"AndroidWebView", "Preferences"})
1965 public void testBlockNetworkImagesWithTwoViews() throws Throwable {
1966 ViewPair views = createViews();
1967 TestWebServer webServer = null;
1969 webServer = new TestWebServer(false);
1970 runPerViewSettingsTest(
1971 new AwSettingsImagesEnabledHelper(
1972 views.getContainer0(),
1975 new ImagePageGenerator(0, true)),
1976 new AwSettingsImagesEnabledHelper(
1977 views.getContainer1(),
1980 new ImagePageGenerator(1, true)));
1982 if (webServer != null) webServer.shutdown();
1987 @Feature({"AndroidWebView", "Preferences"})
1988 public void testBlockNetworkLoadsWithHttpResources() throws Throwable {
1989 final TestAwContentsClient contentClient = new TestAwContentsClient();
1990 final AwTestContainerView testContainer =
1991 createAwTestContainerViewOnMainSync(contentClient);
1992 final AwContents awContents = testContainer.getAwContents();
1993 final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
1994 awSettings.setJavaScriptEnabled(true);
1995 ImagePageGenerator generator = new ImagePageGenerator(0, false);
1997 TestWebServer webServer = null;
1998 String fileName = null;
2000 // Set up http image.
2001 webServer = new TestWebServer(false);
2002 final String httpPath = "/image.png";
2003 final String imageUrl = webServer.setResponseBase64(
2004 httpPath, generator.getImageSourceNoAdvance(),
2005 CommonResources.getImagePngHeaders(true));
2007 // Set up file html that loads http iframe.
2008 String pageHtml = "<img src='" + imageUrl + "' " +
2009 "onload=\"document.title='img_onload_fired';\" " +
2010 "onerror=\"document.title='img_onerror_fired';\" />";
2011 Context context = getInstrumentation().getTargetContext();
2012 fileName = context.getCacheDir() + "/block_network_loads_test.html";
2013 TestFileUtil.deleteFile(fileName); // Remove leftover file if any.
2014 TestFileUtil.createNewHtmlFile(fileName, "unset", pageHtml);
2016 // Actual test. Blocking should trigger onerror handler.
2017 awSettings.setBlockNetworkLoads(true);
2020 contentClient.getOnPageFinishedHelper(),
2021 "file:///" + fileName);
2022 assertEquals(0, webServer.getRequestCount(httpPath));
2023 assertEquals("img_onerror_fired", getTitleOnUiThread(awContents));
2025 // Unblock should load normally.
2026 awSettings.setBlockNetworkLoads(false);
2029 contentClient.getOnPageFinishedHelper(),
2030 "file:///" + fileName);
2031 assertEquals(1, webServer.getRequestCount(httpPath));
2032 assertEquals("img_onload_fired", getTitleOnUiThread(awContents));
2034 if (fileName != null) TestFileUtil.deleteFile(fileName);
2035 if (webServer != null) webServer.shutdown();
2039 private static class AudioEvent {
2040 private CallbackHelper mCallback;
2041 public AudioEvent(CallbackHelper callback) {
2042 mCallback = callback;
2045 @JavascriptInterface
2046 public void onCanPlay() {
2047 mCallback.notifyCalled();
2050 @JavascriptInterface
2051 public void onError() {
2052 mCallback.notifyCalled();
2057 @Feature({"AndroidWebView", "Preferences"})
2058 public void testBlockNetworkLoadsWithAudio() throws Throwable {
2059 final TestAwContentsClient contentClient = new TestAwContentsClient();
2060 final AwTestContainerView testContainer =
2061 createAwTestContainerViewOnMainSync(contentClient);
2062 final AwContents awContents = testContainer.getAwContents();
2063 final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
2064 CallbackHelper callback = new CallbackHelper();
2065 awSettings.setJavaScriptEnabled(true);
2067 TestWebServer webServer = null;
2069 webServer = new TestWebServer(false);
2070 final String httpPath = "/audio.mp3";
2071 // Don't care about the response is correct or not, just want
2072 // to know whether Url is accessed.
2073 final String audioUrl = webServer.setResponse(httpPath, "1", null);
2075 String pageHtml = "<html><body><audio controls src='" + audioUrl + "' " +
2076 "oncanplay=\"AudioEvent.onCanPlay();\" " +
2077 "onerror=\"AudioEvent.onError();\" /> </body></html>";
2078 // Actual test. Blocking should trigger onerror handler.
2079 awSettings.setBlockNetworkLoads(true);
2080 awContents.addPossiblyUnsafeJavascriptInterface(
2081 new AudioEvent(callback), "AudioEvent", null);
2082 int count = callback.getCallCount();
2083 loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml,
2084 "text/html", false);
2085 callback.waitForCallback(count, 1);
2086 assertEquals(0, webServer.getRequestCount(httpPath));
2088 // The below test failed in Nexus Galaxy.
2089 // See https://code.google.com/p/chromium/issues/detail?id=313463
2090 // Unblock should load normally.
2092 awSettings.setBlockNetworkLoads(false);
2093 count = callback.getCallCount();
2094 loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml,
2095 "text/html", false);
2096 callback.waitForCallback(count, 1);
2097 assertTrue(0 != webServer.getRequestCount(httpPath));
2100 if (webServer != null) webServer.shutdown();
2104 // Test an assert URL (file:///android_asset/)
2106 @Feature({"AndroidWebView", "Navigation"})
2107 public void testAssetUrl() throws Throwable {
2108 // Note: this text needs to be kept in sync with the contents of the html file referenced
2110 final String expectedTitle = "Asset File";
2111 final TestAwContentsClient contentClient = new TestAwContentsClient();
2112 final AwTestContainerView testContainerView =
2113 createAwTestContainerViewOnMainSync(contentClient);
2114 final AwContents awContents = testContainerView.getAwContents();
2115 loadUrlSync(awContents,
2116 contentClient.getOnPageFinishedHelper(),
2117 "file:///android_asset/asset_file.html");
2118 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
2121 // Test a resource URL (file:///android_res/).
2123 @Feature({"AndroidWebView", "Navigation"})
2124 public void testResourceUrl() throws Throwable {
2125 // Note: this text needs to be kept in sync with the contents of the html file referenced
2127 final String expectedTitle = "Resource File";
2128 final TestAwContentsClient contentClient = new TestAwContentsClient();
2129 final AwTestContainerView testContainerView =
2130 createAwTestContainerViewOnMainSync(contentClient);
2131 final AwContents awContents = testContainerView.getAwContents();
2132 loadUrlSync(awContents,
2133 contentClient.getOnPageFinishedHelper(),
2134 "file:///android_res/raw/resource_file.html");
2135 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
2138 // Test that the file URL access toggle does not affect asset URLs.
2140 @Feature({"AndroidWebView", "Navigation"})
2141 public void testFileUrlAccessToggleDoesNotBlockAssetUrls() throws Throwable {
2142 // Note: this text needs to be kept in sync with the contents of the html file referenced
2144 final String expectedTitle = "Asset File";
2145 final TestAwContentsClient contentClient = new TestAwContentsClient();
2146 final AwTestContainerView testContainerView =
2147 createAwTestContainerViewOnMainSync(contentClient);
2148 final AwContents awContents = testContainerView.getAwContents();
2149 final AwSettings settings = getAwSettingsOnUiThread(awContents);
2150 settings.setAllowFileAccess(false);
2151 loadUrlSync(awContents,
2152 contentClient.getOnPageFinishedHelper(),
2153 "file:///android_asset/asset_file.html");
2154 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
2157 // Test that the file URL access toggle does not affect resource URLs.
2159 @Feature({"AndroidWebView", "Navigation"})
2160 public void testFileUrlAccessToggleDoesNotBlockResourceUrls() throws Throwable {
2161 // Note: this text needs to be kept in sync with the contents of the html file referenced
2163 final String expectedTitle = "Resource File";
2164 final TestAwContentsClient contentClient = new TestAwContentsClient();
2165 final AwTestContainerView testContainerView =
2166 createAwTestContainerViewOnMainSync(contentClient);
2167 final AwContents awContents = testContainerView.getAwContents();
2168 final AwSettings settings = getAwSettingsOnUiThread(awContents);
2169 settings.setAllowFileAccess(false);
2170 loadUrlSync(awContents,
2171 contentClient.getOnPageFinishedHelper(),
2172 "file:///android_res/raw/resource_file.html");
2173 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
2177 @Feature({"AndroidWebView", "Preferences"})
2178 public void testLayoutAlgorithmWithTwoViews() throws Throwable {
2179 ViewPair views = createViews();
2180 runPerViewSettingsTest(
2181 new AwSettingsLayoutAlgorithmTestHelper(views.getContainer0(), views.getClient0()),
2182 new AwSettingsLayoutAlgorithmTestHelper(views.getContainer1(), views.getClient1()));
2186 @Feature({"AndroidWebView", "Preferences"})
2187 public void testTextZoomWithTwoViews() throws Throwable {
2188 ViewPair views = createViews();
2189 runPerViewSettingsTest(
2190 new AwSettingsTextZoomTestHelper(views.getContainer0(), views.getClient0()),
2191 new AwSettingsTextZoomTestHelper(views.getContainer1(), views.getClient1()));
2195 @Feature({"AndroidWebView", "Preferences"})
2196 public void testTextZoomAutosizingWithTwoViews() throws Throwable {
2197 ViewPair views = createViews();
2198 runPerViewSettingsTest(
2199 new AwSettingsTextZoomAutosizingTestHelper(views.getContainer0(), views.getClient0()),
2200 new AwSettingsTextZoomAutosizingTestHelper(views.getContainer1(), views.getClient1()));
2204 @Feature({"AndroidWebView", "Preferences"})
2205 public void testJavaScriptPopupsWithTwoViews() throws Throwable {
2206 ViewPair views = createViews();
2207 runPerViewSettingsTest(
2208 new AwSettingsJavaScriptPopupsTestHelper(views.getContainer0(), views.getClient0()),
2209 new AwSettingsJavaScriptPopupsTestHelper(views.getContainer1(), views.getClient1()));
2213 @Feature({"AndroidWebView", "Preferences"})
2214 public void testCacheMode() throws Throwable {
2215 final TestAwContentsClient contentClient = new TestAwContentsClient();
2216 final AwTestContainerView testContainer =
2217 createAwTestContainerViewOnMainSync(contentClient);
2218 final AwContents awContents = testContainer.getAwContents();
2219 final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents());
2220 clearCacheOnUiThread(awContents, true);
2222 assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode());
2223 TestWebServer webServer = null;
2225 webServer = new TestWebServer(false);
2226 final String htmlPath = "/testCacheMode.html";
2227 final String url = webServer.setResponse(htmlPath, "response", null);
2228 awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
2229 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2230 assertEquals(1, webServer.getRequestCount(htmlPath));
2231 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2232 assertEquals(1, webServer.getRequestCount(htmlPath));
2234 awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
2235 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2236 assertEquals(2, webServer.getRequestCount(htmlPath));
2237 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2238 assertEquals(3, webServer.getRequestCount(htmlPath));
2240 awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
2241 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2242 assertEquals(3, webServer.getRequestCount(htmlPath));
2243 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2244 assertEquals(3, webServer.getRequestCount(htmlPath));
2246 final String htmlNotInCachePath = "/testCacheMode-not-in-cache.html";
2247 final String urlNotInCache = webServer.setResponse(htmlNotInCachePath, "", null);
2248 loadUrlSyncAndExpectError(awContents,
2249 contentClient.getOnPageFinishedHelper(),
2250 contentClient.getOnReceivedErrorHelper(),
2252 assertEquals(0, webServer.getRequestCount(htmlNotInCachePath));
2254 if (webServer != null) webServer.shutdown();
2259 @Feature({"AndroidWebView", "Preferences"})
2260 // As our implementation of network loads blocking uses the same net::URLRequest settings, make
2261 // sure that setting cache mode doesn't accidentally enable network loads. The reference
2262 // behaviour is that when network loads are blocked, setting cache mode has no effect.
2263 public void testCacheModeWithBlockedNetworkLoads() throws Throwable {
2264 final TestAwContentsClient contentClient = new TestAwContentsClient();
2265 final AwTestContainerView testContainer =
2266 createAwTestContainerViewOnMainSync(contentClient);
2267 final AwContents awContents = testContainer.getAwContents();
2268 final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents());
2269 clearCacheOnUiThread(awContents, true);
2271 assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode());
2272 awSettings.setBlockNetworkLoads(true);
2273 TestWebServer webServer = null;
2275 webServer = new TestWebServer(false);
2276 final String htmlPath = "/testCacheModeWithBlockedNetworkLoads.html";
2277 final String url = webServer.setResponse(htmlPath, "response", null);
2278 loadUrlSyncAndExpectError(awContents,
2279 contentClient.getOnPageFinishedHelper(),
2280 contentClient.getOnReceivedErrorHelper(),
2282 assertEquals(0, webServer.getRequestCount(htmlPath));
2284 awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
2285 loadUrlSyncAndExpectError(awContents,
2286 contentClient.getOnPageFinishedHelper(),
2287 contentClient.getOnReceivedErrorHelper(),
2289 assertEquals(0, webServer.getRequestCount(htmlPath));
2291 awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
2292 loadUrlSyncAndExpectError(awContents,
2293 contentClient.getOnPageFinishedHelper(),
2294 contentClient.getOnReceivedErrorHelper(),
2296 assertEquals(0, webServer.getRequestCount(htmlPath));
2298 awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
2299 loadUrlSyncAndExpectError(awContents,
2300 contentClient.getOnPageFinishedHelper(),
2301 contentClient.getOnReceivedErrorHelper(),
2303 assertEquals(0, webServer.getRequestCount(htmlPath));
2305 if (webServer != null) webServer.shutdown();
2310 @Feature({"AndroidWebView", "Preferences"})
2311 public void testCacheModeWithTwoViews() throws Throwable {
2312 ViewPair views = createViews();
2313 TestWebServer webServer = null;
2315 webServer = new TestWebServer(false);
2316 runPerViewSettingsTest(
2317 new AwSettingsCacheModeTestHelper(
2318 views.getContainer0(), views.getClient0(), 0, webServer),
2319 new AwSettingsCacheModeTestHelper(
2320 views.getContainer1(), views.getClient1(), 1, webServer));
2322 if (webServer != null) webServer.shutdown();
2326 static class ManifestTestHelper {
2327 private final TestWebServer mWebServer;
2328 private final String mHtmlPath;
2329 private final String mHtmlUrl;
2330 private final String mManifestPath;
2333 TestWebServer webServer, String htmlPageName, String manifestName) {
2334 mWebServer = webServer;
2335 mHtmlPath = "/" + htmlPageName;
2336 mHtmlUrl = webServer.setResponse(
2337 mHtmlPath, "<html manifest=\"" + manifestName + "\"></html>", null);
2338 mManifestPath = "/" + manifestName;
2339 webServer.setResponse(
2342 CommonResources.getContentTypeAndCacheHeaders("text/cache-manifest", false));
2345 String getHtmlPath() {
2349 String getHtmlUrl() {
2353 String getManifestPath() {
2354 return mManifestPath;
2357 int waitUntilHtmlIsRequested(final int initialRequestCount) throws Exception {
2358 return waitUntilResourceIsRequested(mHtmlPath, initialRequestCount);
2361 int waitUntilManifestIsRequested(final int initialRequestCount) throws Exception {
2362 return waitUntilResourceIsRequested(mManifestPath, initialRequestCount);
2365 private int waitUntilResourceIsRequested(
2366 final String path, final int initialRequestCount) throws Exception {
2367 poll(new Callable<Boolean>() {
2369 public Boolean call() throws Exception {
2370 return mWebServer.getRequestCount(path) > initialRequestCount;
2373 return mWebServer.getRequestCount(path);
2378 @Feature({"AndroidWebView", "Preferences", "AppCache"})
2379 public void testAppCache() throws Throwable {
2380 final TestAwContentsClient contentClient = new TestAwContentsClient();
2381 final AwTestContainerView testContainer =
2382 createAwTestContainerViewOnMainSync(contentClient);
2383 final AwContents awContents = testContainer.getAwContents();
2384 final AwSettings settings = getAwSettingsOnUiThread(awContents);
2385 settings.setJavaScriptEnabled(true);
2386 // Note that the cache isn't actually enabled until the call to setAppCachePath.
2387 settings.setAppCacheEnabled(true);
2389 TestWebServer webServer = null;
2391 webServer = new TestWebServer(false);
2392 ManifestTestHelper helper = new ManifestTestHelper(
2393 webServer, "testAppCache.html", "appcache.manifest");
2396 contentClient.getOnPageFinishedHelper(),
2397 helper.getHtmlUrl());
2398 helper.waitUntilHtmlIsRequested(0);
2399 // Unfortunately, there is no other good way of verifying that AppCache is
2400 // disabled, other than checking that it didn't try to fetch the manifest.
2402 assertEquals(0, webServer.getRequestCount(helper.getManifestPath()));
2403 settings.setAppCachePath("whatever"); // Enables AppCache.
2406 contentClient.getOnPageFinishedHelper(),
2407 helper.getHtmlUrl());
2408 helper.waitUntilManifestIsRequested(0);
2410 if (webServer != null) webServer.shutdown();
2415 @Feature({"AndroidWebView", "Preferences", "AppCache"})
2416 public void testAppCacheWithTwoViews() throws Throwable {
2417 // We don't use the test helper here, because making sure that AppCache
2418 // is disabled takes a lot of time, so running through the usual drill
2419 // will take about 20 seconds.
2420 ViewPair views = createViews();
2422 AwSettings settings0 = getAwSettingsOnUiThread(views.getContents0());
2423 settings0.setJavaScriptEnabled(true);
2424 settings0.setAppCachePath("whatever");
2425 settings0.setAppCacheEnabled(true);
2426 AwSettings settings1 = getAwSettingsOnUiThread(views.getContents1());
2427 settings1.setJavaScriptEnabled(true);
2428 // AppCachePath setting is global, no need to set it for the second view.
2429 settings1.setAppCacheEnabled(true);
2431 TestWebServer webServer = null;
2433 webServer = new TestWebServer(false);
2434 ManifestTestHelper helper0 = new ManifestTestHelper(
2435 webServer, "testAppCache_0.html", "appcache.manifest_0");
2437 views.getContents0(),
2438 views.getClient0().getOnPageFinishedHelper(),
2439 helper0.getHtmlUrl());
2440 int manifestRequests0 = helper0.waitUntilManifestIsRequested(0);
2441 ManifestTestHelper helper1 = new ManifestTestHelper(
2442 webServer, "testAppCache_1.html", "appcache.manifest_1");
2444 views.getContents1(),
2445 views.getClient1().getOnPageFinishedHelper(),
2446 helper1.getHtmlUrl());
2447 helper1.waitUntilManifestIsRequested(0);
2448 settings1.setAppCacheEnabled(false);
2450 views.getContents0(),
2451 views.getClient0().getOnPageFinishedHelper(),
2452 helper0.getHtmlUrl());
2453 helper0.waitUntilManifestIsRequested(manifestRequests0);
2454 final int prevManifestRequestCount =
2455 webServer.getRequestCount(helper1.getManifestPath());
2456 int htmlRequests1 = webServer.getRequestCount(helper1.getHtmlPath());
2458 views.getContents1(),
2459 views.getClient1().getOnPageFinishedHelper(),
2460 helper1.getHtmlUrl());
2461 helper1.waitUntilHtmlIsRequested(htmlRequests1);
2462 // Unfortunately, there is no other good way of verifying that AppCache is
2463 // disabled, other than checking that it didn't try to fetch the manifest.
2466 prevManifestRequestCount, webServer.getRequestCount(helper1.getManifestPath()));
2468 if (webServer != null) webServer.shutdown();
2473 @Feature({"AndroidWebView", "Preferences"})
2474 public void testUseWideViewportWithTwoViews() throws Throwable {
2475 ViewPair views = createViews(true);
2476 runPerViewSettingsTest(
2477 new AwSettingsUseWideViewportTestHelper(views.getContainer0(), views.getClient0()),
2478 new AwSettingsUseWideViewportTestHelper(views.getContainer1(), views.getClient1()));
2482 @Feature({"AndroidWebView", "Preferences"})
2483 public void testUseWideViewportWithTwoViewsNoQuirks() throws Throwable {
2484 ViewPair views = createViews();
2485 runPerViewSettingsTest(
2486 new AwSettingsUseWideViewportTestHelper(views.getContainer0(), views.getClient0()),
2487 new AwSettingsUseWideViewportTestHelper(views.getContainer1(), views.getClient1()));
2490 private void useWideViewportLayoutWidthTest(
2491 AwTestContainerView testContainer, CallbackHelper onPageFinishedHelper)
2493 final AwContents awContents = testContainer.getAwContents();
2494 AwSettings settings = getAwSettingsOnUiThread(awContents);
2496 final String pageTemplate = "<html><head>%s</head>" +
2497 "<body onload='document.title=document.body.clientWidth'></body></html>";
2498 final String pageNoViewport = String.format(pageTemplate, "");
2499 final String pageViewportDeviceWidth = String.format(
2501 "<meta name='viewport' content='width=device-width' />");
2502 final String viewportTagSpecifiedWidth = "3000";
2503 final String pageViewportSpecifiedWidth = String.format(
2505 "<meta name='viewport' content='width=" + viewportTagSpecifiedWidth + "' />");
2507 DeviceDisplayInfo deviceInfo = DeviceDisplayInfo.create(testContainer.getContext());
2508 int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
2510 settings.setJavaScriptEnabled(true);
2511 assertFalse(settings.getUseWideViewPort());
2512 // When UseWideViewPort is off, "width" setting of "meta viewport"
2513 // tags is ignored, and the layout width is set to device width in CSS pixels.
2514 // Thus, all 3 pages will have the same body width.
2515 loadDataSync(awContents, onPageFinishedHelper, pageNoViewport, "text/html", false);
2516 int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2517 // Avoid rounding errors.
2518 assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
2519 Math.abs(displayWidth - actualWidth) <= 1);
2520 loadDataSync(awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false);
2521 actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2522 assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
2523 Math.abs(displayWidth - actualWidth) <= 1);
2525 awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false);
2526 actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2527 assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
2528 Math.abs(displayWidth - actualWidth) <= 1);
2530 settings.setUseWideViewPort(true);
2531 // When UseWideViewPort is on, "meta viewport" tag is used.
2532 // If there is no viewport tag, or width isn't specified,
2533 // then layout width is set to max(980, <device-width-in-DIP-pixels>)
2534 loadDataSync(awContents, onPageFinishedHelper, pageNoViewport, "text/html", false);
2535 actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2536 assertTrue("Expected: >= 980 , Actual: " + actualWidth, actualWidth >= 980);
2537 loadDataSync(awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false);
2538 actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2539 assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
2540 Math.abs(displayWidth - actualWidth) <= 1);
2542 awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false);
2543 assertEquals(viewportTagSpecifiedWidth, getTitleOnUiThread(awContents));
2547 @Feature({"AndroidWebView", "Preferences"})
2548 public void testUseWideViewportLayoutWidth() throws Throwable {
2549 TestAwContentsClient contentClient = new TestAwContentsClient();
2550 AwTestContainerView testContainerView =
2551 createAwTestContainerViewOnMainSync(contentClient);
2552 useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper());
2556 @Feature({"AndroidWebView", "Preferences"})
2557 public void testUseWideViewportLayoutWidthNoQuirks() throws Throwable {
2558 TestAwContentsClient contentClient = new TestAwContentsClient();
2559 AwTestContainerView testContainerView =
2560 createAwTestContainerViewOnMainSync(contentClient, false);
2561 useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper());
2565 @Feature({"AndroidWebView", "Preferences"})
2566 public void testUseWideViewportControlsDoubleTabToZoom() throws Throwable {
2567 final TestAwContentsClient contentClient = new TestAwContentsClient();
2568 final AwTestContainerView testContainerView =
2569 createAwTestContainerViewOnMainSync(contentClient);
2570 final AwContents awContents = testContainerView.getAwContents();
2571 CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
2572 AwSettings settings = getAwSettingsOnUiThread(awContents);
2573 settings.setBuiltInZoomControls(true);
2575 DeviceDisplayInfo deviceInfo =
2576 DeviceDisplayInfo.create(testContainerView.getContext());
2577 int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
2578 int layoutWidth = displayWidth * 2;
2579 final String page = "<html>" +
2580 "<head><meta name='viewport' content='width=" + layoutWidth + "'>" +
2581 "<style> body { width: " + layoutWidth + "px; }</style></head>" +
2582 "<body>Page Text</body></html>";
2584 assertFalse(settings.getUseWideViewPort());
2585 // Without wide viewport the <meta viewport> tag will be ignored by WebView,
2586 // but it doesn't really matter as we don't expect double tap to change the scale.
2587 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2588 final float initialScale = getScaleOnUiThread(awContents);
2589 simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView);
2591 assertEquals(initialScale, getScaleOnUiThread(awContents));
2593 settings.setUseWideViewPort(true);
2594 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2595 int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
2596 simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView);
2597 contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
2598 final float zoomedOutScale = getScaleOnUiThread(awContents);
2599 assertTrue("zoomedOut: " + zoomedOutScale + ", initial: " + initialScale,
2600 zoomedOutScale < initialScale);
2604 @Feature({"AndroidWebView", "Preferences"})
2605 public void testForceZeroLayoutHeightWithTwoViews() throws Throwable {
2606 ViewPair views = createViews();
2607 runPerViewSettingsTest(
2608 new AwSettingsForceZeroLayoutHeightTestHelper(
2609 views.getContainer0(), views.getClient0(), false),
2610 new AwSettingsForceZeroLayoutHeightTestHelper(
2611 views.getContainer1(), views.getClient1(), false));
2615 @Feature({"AndroidWebView", "Preferences"})
2616 public void testForceZeroLayoutHeightViewportTagWithTwoViews() throws Throwable {
2617 ViewPair views = createViews();
2618 runPerViewSettingsTest(
2619 new AwSettingsForceZeroLayoutHeightTestHelper(
2620 views.getContainer0(), views.getClient0(), true),
2621 new AwSettingsForceZeroLayoutHeightTestHelper(
2622 views.getContainer1(), views.getClient1(), true));
2626 @Feature({"AndroidWebView", "Preferences"})
2627 public void testZeroLayoutHeightDisablesViewportQuirkWithTwoViews() throws Throwable {
2628 ViewPair views = createViews();
2629 runPerViewSettingsTest(
2630 new AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper(
2631 views.getContainer0(), views.getClient0()),
2632 new AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper(
2633 views.getContainer1(), views.getClient1()));
2637 @Feature({"AndroidWebView", "Preferences"})
2638 public void testLoadWithOverviewModeWithTwoViews() throws Throwable {
2639 ViewPair views = createViews();
2640 runPerViewSettingsTest(
2641 new AwSettingsLoadWithOverviewModeTestHelper(
2642 views.getContainer0(), views.getClient0(), false),
2643 new AwSettingsLoadWithOverviewModeTestHelper(
2644 views.getContainer1(), views.getClient1(), false));
2648 @Feature({"AndroidWebView", "Preferences"})
2649 public void testLoadWithOverviewModeViewportTagWithTwoViews() throws Throwable {
2650 ViewPair views = createViews();
2651 runPerViewSettingsTest(
2652 new AwSettingsLoadWithOverviewModeTestHelper(
2653 views.getContainer0(), views.getClient0(), true),
2654 new AwSettingsLoadWithOverviewModeTestHelper(
2655 views.getContainer1(), views.getClient1(), true));
2659 @Feature({"AndroidWebView", "Preferences"})
2660 public void testSetInitialScale() throws Throwable {
2661 final TestAwContentsClient contentClient = new TestAwContentsClient();
2662 final AwTestContainerView testContainerView =
2663 createAwTestContainerViewOnMainSync(contentClient);
2664 final AwContents awContents = testContainerView.getAwContents();
2665 final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
2666 CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
2668 WindowManager wm = (WindowManager) getInstrumentation().getTargetContext()
2669 .getSystemService(Context.WINDOW_SERVICE);
2670 Point screenSize = new Point();
2671 wm.getDefaultDisplay().getSize(screenSize);
2672 // Make sure after 50% scale, page width still larger than screen.
2673 int height = screenSize.y * 2 + 1;
2674 int width = screenSize.x * 2 + 1;
2675 final String page = "<html><body>" +
2676 "<p style='height:" + height + "px;width:" + width + "px'>" +
2677 "testSetInitialScale</p></body></html>";
2678 final float defaultScale =
2679 getInstrumentation().getTargetContext().getResources().getDisplayMetrics().density;
2681 assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
2682 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2683 assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
2685 int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
2686 awSettings.setInitialPageScale(50);
2687 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2688 contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
2689 assertEquals(0.5f, getPixelScaleOnUiThread(awContents), .01f);
2691 onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
2692 awSettings.setInitialPageScale(500);
2693 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2694 contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
2695 assertEquals(5.0f, getPixelScaleOnUiThread(awContents), .01f);
2697 onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
2698 awSettings.setInitialPageScale(0);
2699 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2700 contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
2701 assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
2706 @Feature({"AndroidWebView", "Preferences"})
2707 http://crbug.com/304549
2710 public void testMediaPlaybackWithoutUserGesture() throws Throwable {
2711 assertTrue(VideoTestUtil.runVideoTest(this, false, WAIT_TIMEOUT_MS));
2715 @Feature({"AndroidWebView", "Preferences"})
2716 public void testMediaPlaybackWithUserGesture() throws Throwable {
2717 // Wait for 5 second to see if video played.
2718 assertFalse(VideoTestUtil.runVideoTest(this, true, scaleTimeout(5000)));
2722 @Feature({"AndroidWebView", "Preferences"})
2723 public void testDefaultVideoPosterURL() throws Throwable {
2724 final CallbackHelper videoPosterAccessedCallbackHelper = new CallbackHelper();
2725 final String DEFAULT_VIDEO_POSTER_URL = "http://default_video_poster/";
2726 TestAwContentsClient client = new TestAwContentsClient() {
2728 public AwWebResourceResponse shouldInterceptRequest(
2729 ShouldInterceptRequestParams params) {
2730 if (params.url.equals(DEFAULT_VIDEO_POSTER_URL)) {
2731 videoPosterAccessedCallbackHelper.notifyCalled();
2736 final AwContents awContents = createAwTestContainerViewOnMainSync(client).getAwContents();
2737 getInstrumentation().runOnMainSync(new Runnable() {
2740 AwSettings awSettings = awContents.getSettings();
2741 awSettings.setDefaultVideoPosterURL(DEFAULT_VIDEO_POSTER_URL);
2744 VideoTestWebServer webServer = new VideoTestWebServer(
2745 getInstrumentation().getTargetContext());
2747 String data = "<html><head><body>" +
2748 "<video id='video' control src='" +
2749 webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
2750 loadDataAsync(awContents, data, "text/html", false);
2751 videoPosterAccessedCallbackHelper.waitForCallback(0, 1, 20, TimeUnit.SECONDS);
2753 if (webServer.getTestWebServer() != null)
2754 webServer.getTestWebServer().shutdown();
2759 @Feature({"AndroidWebView", "Preferences"})
2760 public void testAllowMixedMode() throws Throwable {
2761 final TestAwContentsClient contentClient = new TestAwContentsClient() {
2763 public void onReceivedSslError(ValueCallback<Boolean> callback, SslError error) {
2764 callback.onReceiveValue(true);
2767 final AwTestContainerView testContainerView =
2768 createAwTestContainerViewOnMainSync(contentClient);
2769 final AwContents awContents = testContainerView.getAwContents();
2770 final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
2772 awSettings.setJavaScriptEnabled(true);
2774 TestWebServer httpsServer = new TestWebServer(true);
2775 TestWebServer httpServer = new TestWebServer(false);
2777 final String JS_URL = "/insecure.js";
2778 final String IMG_URL = "/insecure.png";
2779 final String SECURE_URL = "/secure.html";
2780 httpServer.setResponse(JS_URL, "window.loaded_js = 42;", null);
2781 httpServer.setResponseBase64(IMG_URL, CommonResources.FAVICON_DATA_BASE64, null);
2783 final String JS_HTML = "<script src=\"" + httpServer.getResponseUrl(JS_URL) +
2785 final String IMG_HTML = "<img src=\"" + httpServer.getResponseUrl(IMG_URL) + "\" />";
2786 final String SECURE_HTML = "<body>" + IMG_HTML + " " + JS_HTML + "</body>";
2788 String secureUrl = httpsServer.setResponse(SECURE_URL, SECURE_HTML, null);
2790 awSettings.setMixedContentMode(AwSettings.MIXED_CONTENT_NEVER_ALLOW);
2791 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), secureUrl);
2792 assertEquals(1, httpsServer.getRequestCount(SECURE_URL));
2793 assertEquals(0, httpServer.getRequestCount(JS_URL));
2794 assertEquals(0, httpServer.getRequestCount(IMG_URL));
2796 awSettings.setMixedContentMode(AwSettings.MIXED_CONTENT_ALWAYS_ALLOW);
2797 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), secureUrl);
2798 assertEquals(2, httpsServer.getRequestCount(SECURE_URL));
2799 assertEquals(1, httpServer.getRequestCount(JS_URL));
2800 assertEquals(1, httpServer.getRequestCount(IMG_URL));
2802 awSettings.setMixedContentMode(AwSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
2803 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), secureUrl);
2804 assertEquals(3, httpsServer.getRequestCount(SECURE_URL));
2805 assertEquals(1, httpServer.getRequestCount(JS_URL));
2806 assertEquals(2, httpServer.getRequestCount(IMG_URL));
2808 httpServer.shutdown();
2809 httpsServer.shutdown();
2813 static class ViewPair {
2814 private final AwTestContainerView mContainer0;
2815 private final TestAwContentsClient mClient0;
2816 private final AwTestContainerView mContainer1;
2817 private final TestAwContentsClient mClient1;
2819 ViewPair(AwTestContainerView container0, TestAwContentsClient client0,
2820 AwTestContainerView container1, TestAwContentsClient client1) {
2821 this.mContainer0 = container0;
2822 this.mClient0 = client0;
2823 this.mContainer1 = container1;
2824 this.mClient1 = client1;
2827 AwTestContainerView getContainer0() {
2831 AwContents getContents0() {
2832 return mContainer0.getAwContents();
2835 TestAwContentsClient getClient0() {
2839 AwTestContainerView getContainer1() {
2843 AwContents getContents1() {
2844 return mContainer1.getAwContents();
2847 TestAwContentsClient getClient1() {
2853 * Verifies the following statements about a setting:
2854 * - initially, the setting has a default value;
2855 * - the setting can be switched to an alternate value and back;
2856 * - switching a setting in the first WebView doesn't affect the setting
2857 * state in the second WebView and vice versa.
2859 * @param helper0 Test helper for the first ContentView
2860 * @param helper1 Test helper for the second ContentView
2863 private void runPerViewSettingsTest(AwSettingsTestHelper helper0,
2864 AwSettingsTestHelper helper1) throws Throwable {
2865 helper0.ensureSettingHasInitialValue();
2866 helper1.ensureSettingHasInitialValue();
2868 helper1.setAlteredSettingValue();
2869 helper0.ensureSettingHasInitialValue();
2870 helper1.ensureSettingHasAlteredValue();
2872 helper1.setInitialSettingValue();
2873 helper0.ensureSettingHasInitialValue();
2874 helper1.ensureSettingHasInitialValue();
2876 helper0.setAlteredSettingValue();
2877 helper0.ensureSettingHasAlteredValue();
2878 helper1.ensureSettingHasInitialValue();
2880 helper0.setInitialSettingValue();
2881 helper0.ensureSettingHasInitialValue();
2882 helper1.ensureSettingHasInitialValue();
2884 helper0.setAlteredSettingValue();
2885 helper0.ensureSettingHasAlteredValue();
2886 helper1.ensureSettingHasInitialValue();
2888 helper1.setAlteredSettingValue();
2889 helper0.ensureSettingHasAlteredValue();
2890 helper1.ensureSettingHasAlteredValue();
2892 helper0.setInitialSettingValue();
2893 helper0.ensureSettingHasInitialValue();
2894 helper1.ensureSettingHasAlteredValue();
2896 helper1.setInitialSettingValue();
2897 helper0.ensureSettingHasInitialValue();
2898 helper1.ensureSettingHasInitialValue();
2901 private ViewPair createViews() throws Throwable {
2902 return createViews(false);
2905 private ViewPair createViews(boolean supportsLegacyQuirks) throws Throwable {
2906 TestAwContentsClient client0 = new TestAwContentsClient();
2907 TestAwContentsClient client1 = new TestAwContentsClient();
2908 return new ViewPair(
2909 createAwTestContainerViewOnMainSync(client0, supportsLegacyQuirks),
2911 createAwTestContainerViewOnMainSync(client1, supportsLegacyQuirks),
2915 static void assertFileIsReadable(String filePath) {
2916 File file = new File(filePath);
2918 assertTrue("Test file \"" + filePath + "\" is not readable." +
2919 "Please make sure that files from android_webview/test/data/device_files/ " +
2920 "has been pushed to the device before testing",
2922 } catch (SecurityException e) {
2923 fail("Got a SecurityException for \"" + filePath + "\": " + e.toString());
2928 * Verifies the number of resource requests made to the content provider.
2929 * @param resource Resource name
2930 * @param expectedCount Expected resource requests count
2932 private void ensureResourceRequestCountInContentProvider(String resource, int expectedCount) {
2933 Context context = getInstrumentation().getTargetContext();
2934 int actualCount = TestContentProvider.getResourceRequestCount(context, resource);
2935 assertEquals(expectedCount, actualCount);
2938 private void resetResourceRequestCountInContentProvider(String resource) {
2939 Context context = getInstrumentation().getTargetContext();
2940 TestContentProvider.resetResourceRequestCount(context, resource);
2943 private String createContentUrl(final String target) {
2944 return TestContentProvider.createContentUrl(target);
2947 private void simulateDoubleTapCenterOfWebViewOnUiThread(final AwTestContainerView webView)
2949 final int x = (webView.getRight() - webView.getLeft()) / 2;
2950 final int y = (webView.getBottom() - webView.getTop()) / 2;
2951 final AwContents awContents = webView.getAwContents();
2952 runTestOnUiThread(new Runnable() {
2955 awContents.getContentViewCore().sendDoubleTapForTest(
2956 SystemClock.uptimeMillis(), x, y);