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.test.util.CallbackHelper;
37 import org.chromium.content.browser.test.util.HistoryUtils;
38 import org.chromium.content_public.browser.WebContents;
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 jsEnabledString = "JS has run";
1489 final String jsDisabledString = "JS has not run";
1490 final String testPageHtml =
1491 "<html><head><title>" + jsDisabledString + "</title>"
1492 + "</head><body onload=\"document.title='" + jsEnabledString
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(jsDisabledString, 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 WebContents webContents = awContents.getWebContents();
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(), webContents, onPageFinishedHelper);
1705 assertEquals(page1Title + defaultUserAgentString, getTitleOnUiThread(awContents));
1706 HistoryUtils.goForwardSync(getInstrumentation(), webContents,
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 public void testBlockNetworkImagesDoesNotBlockDataUrlImage() throws Throwable {
1910 final TestAwContentsClient contentClient = new TestAwContentsClient();
1911 final AwTestContainerView testContainerView =
1912 createAwTestContainerViewOnMainSync(contentClient);
1913 final AwContents awContents = testContainerView.getAwContents();
1914 final AwSettings settings = getAwSettingsOnUiThread(awContents);
1915 ImagePageGenerator generator = new ImagePageGenerator(0, false);
1917 settings.setJavaScriptEnabled(true);
1918 settings.setImagesEnabled(false);
1919 loadDataSync(awContents,
1920 contentClient.getOnPageFinishedHelper(),
1921 generator.getPageSource(),
1924 assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, getTitleOnUiThread(awContents));
1928 @Feature({"AndroidWebView", "Preferences"})
1929 public void testBlockNetworkImagesBlocksNetworkImageAndReloadInPlace() throws Throwable {
1930 final TestAwContentsClient contentClient = new TestAwContentsClient();
1931 final AwTestContainerView testContainerView =
1932 createAwTestContainerViewOnMainSync(contentClient);
1933 final AwContents awContents = testContainerView.getAwContents();
1934 final AwSettings settings = getAwSettingsOnUiThread(awContents);
1935 settings.setJavaScriptEnabled(true);
1936 ImagePageGenerator generator = new ImagePageGenerator(0, false);
1938 TestWebServer webServer = null;
1940 webServer = new TestWebServer(false);
1941 final String httpImageUrl = generator.getPageUrl(webServer);
1943 settings.setImagesEnabled(false);
1944 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), httpImageUrl);
1945 assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
1946 getTitleOnUiThread(awContents));
1948 settings.setImagesEnabled(true);
1949 poll(new Callable<Boolean>() {
1951 public Boolean call() throws Exception {
1952 return ImagePageGenerator.IMAGE_LOADED_STRING.equals(
1953 getTitleOnUiThread(awContents));
1957 if (webServer != null) webServer.shutdown();
1962 @Feature({"AndroidWebView", "Preferences"})
1963 public void testBlockNetworkImagesWithTwoViews() throws Throwable {
1964 ViewPair views = createViews();
1965 TestWebServer webServer = null;
1967 webServer = new TestWebServer(false);
1968 runPerViewSettingsTest(
1969 new AwSettingsImagesEnabledHelper(
1970 views.getContainer0(),
1973 new ImagePageGenerator(0, true)),
1974 new AwSettingsImagesEnabledHelper(
1975 views.getContainer1(),
1978 new ImagePageGenerator(1, true)));
1980 if (webServer != null) webServer.shutdown();
1985 @Feature({"AndroidWebView", "Preferences"})
1986 public void testBlockNetworkLoadsWithHttpResources() throws Throwable {
1987 final TestAwContentsClient contentClient = new TestAwContentsClient();
1988 final AwTestContainerView testContainer =
1989 createAwTestContainerViewOnMainSync(contentClient);
1990 final AwContents awContents = testContainer.getAwContents();
1991 final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
1992 awSettings.setJavaScriptEnabled(true);
1993 ImagePageGenerator generator = new ImagePageGenerator(0, false);
1995 TestWebServer webServer = null;
1996 String fileName = null;
1998 // Set up http image.
1999 webServer = new TestWebServer(false);
2000 final String httpPath = "/image.png";
2001 final String imageUrl = webServer.setResponseBase64(
2002 httpPath, generator.getImageSourceNoAdvance(),
2003 CommonResources.getImagePngHeaders(true));
2005 // Set up file html that loads http iframe.
2006 String pageHtml = "<img src='" + imageUrl + "' " +
2007 "onload=\"document.title='img_onload_fired';\" " +
2008 "onerror=\"document.title='img_onerror_fired';\" />";
2009 Context context = getInstrumentation().getTargetContext();
2010 fileName = context.getCacheDir() + "/block_network_loads_test.html";
2011 TestFileUtil.deleteFile(fileName); // Remove leftover file if any.
2012 TestFileUtil.createNewHtmlFile(fileName, "unset", pageHtml);
2014 // Actual test. Blocking should trigger onerror handler.
2015 awSettings.setBlockNetworkLoads(true);
2018 contentClient.getOnPageFinishedHelper(),
2019 "file:///" + fileName);
2020 assertEquals(0, webServer.getRequestCount(httpPath));
2021 assertEquals("img_onerror_fired", getTitleOnUiThread(awContents));
2023 // Unblock should load normally.
2024 awSettings.setBlockNetworkLoads(false);
2027 contentClient.getOnPageFinishedHelper(),
2028 "file:///" + fileName);
2029 assertEquals(1, webServer.getRequestCount(httpPath));
2030 assertEquals("img_onload_fired", getTitleOnUiThread(awContents));
2032 if (fileName != null) TestFileUtil.deleteFile(fileName);
2033 if (webServer != null) webServer.shutdown();
2037 private static class AudioEvent {
2038 private CallbackHelper mCallback;
2039 public AudioEvent(CallbackHelper callback) {
2040 mCallback = callback;
2043 @JavascriptInterface
2044 public void onCanPlay() {
2045 mCallback.notifyCalled();
2048 @JavascriptInterface
2049 public void onError() {
2050 mCallback.notifyCalled();
2055 @Feature({"AndroidWebView", "Preferences"})
2056 public void testBlockNetworkLoadsWithAudio() throws Throwable {
2057 final TestAwContentsClient contentClient = new TestAwContentsClient();
2058 final AwTestContainerView testContainer =
2059 createAwTestContainerViewOnMainSync(contentClient);
2060 final AwContents awContents = testContainer.getAwContents();
2061 final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
2062 final CallbackHelper callback = new CallbackHelper();
2063 awSettings.setJavaScriptEnabled(true);
2065 TestWebServer webServer = null;
2067 webServer = new TestWebServer(false);
2068 final String httpPath = "/audio.mp3";
2069 // Don't care about the response is correct or not, just want
2070 // to know whether Url is accessed.
2071 final String audioUrl = webServer.setResponse(httpPath, "1", null);
2073 String pageHtml = "<html><body><audio controls src='" + audioUrl + "' " +
2074 "oncanplay=\"AudioEvent.onCanPlay();\" " +
2075 "onerror=\"AudioEvent.onError();\" /> </body></html>";
2076 // Actual test. Blocking should trigger onerror handler.
2077 awSettings.setBlockNetworkLoads(true);
2078 runTestOnUiThread(new Runnable() {
2081 awContents.addPossiblyUnsafeJavascriptInterface(
2082 new AudioEvent(callback), "AudioEvent", null);
2085 int count = callback.getCallCount();
2086 loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml,
2087 "text/html", false);
2088 callback.waitForCallback(count, 1);
2089 assertEquals(0, webServer.getRequestCount(httpPath));
2091 // The below test failed in Nexus Galaxy.
2092 // See https://code.google.com/p/chromium/issues/detail?id=313463
2093 // Unblock should load normally.
2095 awSettings.setBlockNetworkLoads(false);
2096 count = callback.getCallCount();
2097 loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml,
2098 "text/html", false);
2099 callback.waitForCallback(count, 1);
2100 assertTrue(0 != webServer.getRequestCount(httpPath));
2103 if (webServer != null) webServer.shutdown();
2107 // Test an assert URL (file:///android_asset/)
2109 @Feature({"AndroidWebView", "Navigation"})
2110 public void testAssetUrl() throws Throwable {
2111 // Note: this text needs to be kept in sync with the contents of the html file referenced
2113 final String expectedTitle = "Asset File";
2114 final TestAwContentsClient contentClient = new TestAwContentsClient();
2115 final AwTestContainerView testContainerView =
2116 createAwTestContainerViewOnMainSync(contentClient);
2117 final AwContents awContents = testContainerView.getAwContents();
2118 loadUrlSync(awContents,
2119 contentClient.getOnPageFinishedHelper(),
2120 "file:///android_asset/asset_file.html");
2121 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
2124 // Test a resource URL (file:///android_res/).
2126 @Feature({"AndroidWebView", "Navigation"})
2127 public void testResourceUrl() throws Throwable {
2128 // Note: this text needs to be kept in sync with the contents of the html file referenced
2130 final String expectedTitle = "Resource File";
2131 final TestAwContentsClient contentClient = new TestAwContentsClient();
2132 final AwTestContainerView testContainerView =
2133 createAwTestContainerViewOnMainSync(contentClient);
2134 final AwContents awContents = testContainerView.getAwContents();
2135 loadUrlSync(awContents,
2136 contentClient.getOnPageFinishedHelper(),
2137 "file:///android_res/raw/resource_file.html");
2138 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
2141 // Test that the file URL access toggle does not affect asset URLs.
2143 @Feature({"AndroidWebView", "Navigation"})
2144 public void testFileUrlAccessToggleDoesNotBlockAssetUrls() throws Throwable {
2145 // Note: this text needs to be kept in sync with the contents of the html file referenced
2147 final String expectedTitle = "Asset File";
2148 final TestAwContentsClient contentClient = new TestAwContentsClient();
2149 final AwTestContainerView testContainerView =
2150 createAwTestContainerViewOnMainSync(contentClient);
2151 final AwContents awContents = testContainerView.getAwContents();
2152 final AwSettings settings = getAwSettingsOnUiThread(awContents);
2153 settings.setAllowFileAccess(false);
2154 loadUrlSync(awContents,
2155 contentClient.getOnPageFinishedHelper(),
2156 "file:///android_asset/asset_file.html");
2157 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
2160 // Test that the file URL access toggle does not affect resource URLs.
2162 @Feature({"AndroidWebView", "Navigation"})
2163 public void testFileUrlAccessToggleDoesNotBlockResourceUrls() throws Throwable {
2164 // Note: this text needs to be kept in sync with the contents of the html file referenced
2166 final String expectedTitle = "Resource File";
2167 final TestAwContentsClient contentClient = new TestAwContentsClient();
2168 final AwTestContainerView testContainerView =
2169 createAwTestContainerViewOnMainSync(contentClient);
2170 final AwContents awContents = testContainerView.getAwContents();
2171 final AwSettings settings = getAwSettingsOnUiThread(awContents);
2172 settings.setAllowFileAccess(false);
2173 loadUrlSync(awContents,
2174 contentClient.getOnPageFinishedHelper(),
2175 "file:///android_res/raw/resource_file.html");
2176 assertEquals(expectedTitle, getTitleOnUiThread(awContents));
2180 @Feature({"AndroidWebView", "Preferences"})
2181 public void testLayoutAlgorithmWithTwoViews() throws Throwable {
2182 ViewPair views = createViews();
2183 runPerViewSettingsTest(
2184 new AwSettingsLayoutAlgorithmTestHelper(views.getContainer0(), views.getClient0()),
2185 new AwSettingsLayoutAlgorithmTestHelper(views.getContainer1(), views.getClient1()));
2189 @Feature({"AndroidWebView", "Preferences"})
2190 public void testTextZoomWithTwoViews() throws Throwable {
2191 ViewPair views = createViews();
2192 runPerViewSettingsTest(
2193 new AwSettingsTextZoomTestHelper(views.getContainer0(), views.getClient0()),
2194 new AwSettingsTextZoomTestHelper(views.getContainer1(), views.getClient1()));
2198 @Feature({"AndroidWebView", "Preferences"})
2199 public void testTextZoomAutosizingWithTwoViews() throws Throwable {
2200 ViewPair views = createViews();
2201 runPerViewSettingsTest(
2202 new AwSettingsTextZoomAutosizingTestHelper(views.getContainer0(), views.getClient0()),
2203 new AwSettingsTextZoomAutosizingTestHelper(views.getContainer1(), views.getClient1()));
2207 @Feature({"AndroidWebView", "Preferences"})
2208 public void testJavaScriptPopupsWithTwoViews() throws Throwable {
2209 ViewPair views = createViews();
2210 runPerViewSettingsTest(
2211 new AwSettingsJavaScriptPopupsTestHelper(views.getContainer0(), views.getClient0()),
2212 new AwSettingsJavaScriptPopupsTestHelper(views.getContainer1(), views.getClient1()));
2216 @Feature({"AndroidWebView", "Preferences"})
2217 public void testCacheMode() throws Throwable {
2218 final TestAwContentsClient contentClient = new TestAwContentsClient();
2219 final AwTestContainerView testContainer =
2220 createAwTestContainerViewOnMainSync(contentClient);
2221 final AwContents awContents = testContainer.getAwContents();
2222 final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents());
2223 clearCacheOnUiThread(awContents, true);
2225 assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode());
2226 TestWebServer webServer = null;
2228 webServer = new TestWebServer(false);
2229 final String htmlPath = "/testCacheMode.html";
2230 final String url = webServer.setResponse(htmlPath, "response", null);
2231 awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
2232 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2233 assertEquals(1, webServer.getRequestCount(htmlPath));
2234 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2235 assertEquals(1, webServer.getRequestCount(htmlPath));
2237 awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
2238 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2239 assertEquals(2, webServer.getRequestCount(htmlPath));
2240 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2241 assertEquals(3, webServer.getRequestCount(htmlPath));
2243 awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
2244 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2245 assertEquals(3, webServer.getRequestCount(htmlPath));
2246 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
2247 assertEquals(3, webServer.getRequestCount(htmlPath));
2249 final String htmlNotInCachePath = "/testCacheMode-not-in-cache.html";
2250 final String urlNotInCache = webServer.setResponse(htmlNotInCachePath, "", null);
2251 loadUrlSyncAndExpectError(awContents,
2252 contentClient.getOnPageFinishedHelper(),
2253 contentClient.getOnReceivedErrorHelper(),
2255 assertEquals(0, webServer.getRequestCount(htmlNotInCachePath));
2257 if (webServer != null) webServer.shutdown();
2262 @Feature({"AndroidWebView", "Preferences"})
2263 // As our implementation of network loads blocking uses the same net::URLRequest settings, make
2264 // sure that setting cache mode doesn't accidentally enable network loads. The reference
2265 // behaviour is that when network loads are blocked, setting cache mode has no effect.
2266 public void testCacheModeWithBlockedNetworkLoads() throws Throwable {
2267 final TestAwContentsClient contentClient = new TestAwContentsClient();
2268 final AwTestContainerView testContainer =
2269 createAwTestContainerViewOnMainSync(contentClient);
2270 final AwContents awContents = testContainer.getAwContents();
2271 final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents());
2272 clearCacheOnUiThread(awContents, true);
2274 assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode());
2275 awSettings.setBlockNetworkLoads(true);
2276 TestWebServer webServer = null;
2278 webServer = new TestWebServer(false);
2279 final String htmlPath = "/testCacheModeWithBlockedNetworkLoads.html";
2280 final String url = webServer.setResponse(htmlPath, "response", null);
2281 loadUrlSyncAndExpectError(awContents,
2282 contentClient.getOnPageFinishedHelper(),
2283 contentClient.getOnReceivedErrorHelper(),
2285 assertEquals(0, webServer.getRequestCount(htmlPath));
2287 awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
2288 loadUrlSyncAndExpectError(awContents,
2289 contentClient.getOnPageFinishedHelper(),
2290 contentClient.getOnReceivedErrorHelper(),
2292 assertEquals(0, webServer.getRequestCount(htmlPath));
2294 awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
2295 loadUrlSyncAndExpectError(awContents,
2296 contentClient.getOnPageFinishedHelper(),
2297 contentClient.getOnReceivedErrorHelper(),
2299 assertEquals(0, webServer.getRequestCount(htmlPath));
2301 awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
2302 loadUrlSyncAndExpectError(awContents,
2303 contentClient.getOnPageFinishedHelper(),
2304 contentClient.getOnReceivedErrorHelper(),
2306 assertEquals(0, webServer.getRequestCount(htmlPath));
2308 if (webServer != null) webServer.shutdown();
2313 @Feature({"AndroidWebView", "Preferences"})
2314 public void testCacheModeWithTwoViews() throws Throwable {
2315 ViewPair views = createViews();
2316 TestWebServer webServer = null;
2318 webServer = new TestWebServer(false);
2319 runPerViewSettingsTest(
2320 new AwSettingsCacheModeTestHelper(
2321 views.getContainer0(), views.getClient0(), 0, webServer),
2322 new AwSettingsCacheModeTestHelper(
2323 views.getContainer1(), views.getClient1(), 1, webServer));
2325 if (webServer != null) webServer.shutdown();
2329 static class ManifestTestHelper {
2330 private final TestWebServer mWebServer;
2331 private final String mHtmlPath;
2332 private final String mHtmlUrl;
2333 private final String mManifestPath;
2336 TestWebServer webServer, String htmlPageName, String manifestName) {
2337 mWebServer = webServer;
2338 mHtmlPath = "/" + htmlPageName;
2339 mHtmlUrl = webServer.setResponse(
2340 mHtmlPath, "<html manifest=\"" + manifestName + "\"></html>", null);
2341 mManifestPath = "/" + manifestName;
2342 webServer.setResponse(
2345 CommonResources.getContentTypeAndCacheHeaders("text/cache-manifest", false));
2348 String getHtmlPath() {
2352 String getHtmlUrl() {
2356 String getManifestPath() {
2357 return mManifestPath;
2360 int waitUntilHtmlIsRequested(final int initialRequestCount) throws Exception {
2361 return waitUntilResourceIsRequested(mHtmlPath, initialRequestCount);
2364 int waitUntilManifestIsRequested(final int initialRequestCount) throws Exception {
2365 return waitUntilResourceIsRequested(mManifestPath, initialRequestCount);
2368 private int waitUntilResourceIsRequested(
2369 final String path, final int initialRequestCount) throws Exception {
2370 poll(new Callable<Boolean>() {
2372 public Boolean call() throws Exception {
2373 return mWebServer.getRequestCount(path) > initialRequestCount;
2376 return mWebServer.getRequestCount(path);
2381 @Feature({"AndroidWebView", "Preferences", "AppCache"})
2382 public void testAppCache() throws Throwable {
2383 final TestAwContentsClient contentClient = new TestAwContentsClient();
2384 final AwTestContainerView testContainer =
2385 createAwTestContainerViewOnMainSync(contentClient);
2386 final AwContents awContents = testContainer.getAwContents();
2387 final AwSettings settings = getAwSettingsOnUiThread(awContents);
2388 settings.setJavaScriptEnabled(true);
2389 // Note that the cache isn't actually enabled until the call to setAppCachePath.
2390 settings.setAppCacheEnabled(true);
2392 TestWebServer webServer = null;
2394 webServer = new TestWebServer(false);
2395 ManifestTestHelper helper = new ManifestTestHelper(
2396 webServer, "testAppCache.html", "appcache.manifest");
2399 contentClient.getOnPageFinishedHelper(),
2400 helper.getHtmlUrl());
2401 helper.waitUntilHtmlIsRequested(0);
2402 // Unfortunately, there is no other good way of verifying that AppCache is
2403 // disabled, other than checking that it didn't try to fetch the manifest.
2405 assertEquals(0, webServer.getRequestCount(helper.getManifestPath()));
2406 settings.setAppCachePath("whatever"); // Enables AppCache.
2409 contentClient.getOnPageFinishedHelper(),
2410 helper.getHtmlUrl());
2411 helper.waitUntilManifestIsRequested(0);
2413 if (webServer != null) webServer.shutdown();
2418 @Feature({"AndroidWebView", "Preferences", "AppCache"})
2419 public void testAppCacheWithTwoViews() throws Throwable {
2420 // We don't use the test helper here, because making sure that AppCache
2421 // is disabled takes a lot of time, so running through the usual drill
2422 // will take about 20 seconds.
2423 ViewPair views = createViews();
2425 AwSettings settings0 = getAwSettingsOnUiThread(views.getContents0());
2426 settings0.setJavaScriptEnabled(true);
2427 settings0.setAppCachePath("whatever");
2428 settings0.setAppCacheEnabled(true);
2429 AwSettings settings1 = getAwSettingsOnUiThread(views.getContents1());
2430 settings1.setJavaScriptEnabled(true);
2431 // AppCachePath setting is global, no need to set it for the second view.
2432 settings1.setAppCacheEnabled(true);
2434 TestWebServer webServer = null;
2436 webServer = new TestWebServer(false);
2437 ManifestTestHelper helper0 = new ManifestTestHelper(
2438 webServer, "testAppCache_0.html", "appcache.manifest_0");
2440 views.getContents0(),
2441 views.getClient0().getOnPageFinishedHelper(),
2442 helper0.getHtmlUrl());
2443 int manifestRequests0 = helper0.waitUntilManifestIsRequested(0);
2444 ManifestTestHelper helper1 = new ManifestTestHelper(
2445 webServer, "testAppCache_1.html", "appcache.manifest_1");
2447 views.getContents1(),
2448 views.getClient1().getOnPageFinishedHelper(),
2449 helper1.getHtmlUrl());
2450 helper1.waitUntilManifestIsRequested(0);
2451 settings1.setAppCacheEnabled(false);
2453 views.getContents0(),
2454 views.getClient0().getOnPageFinishedHelper(),
2455 helper0.getHtmlUrl());
2456 helper0.waitUntilManifestIsRequested(manifestRequests0);
2457 final int prevManifestRequestCount =
2458 webServer.getRequestCount(helper1.getManifestPath());
2459 int htmlRequests1 = webServer.getRequestCount(helper1.getHtmlPath());
2461 views.getContents1(),
2462 views.getClient1().getOnPageFinishedHelper(),
2463 helper1.getHtmlUrl());
2464 helper1.waitUntilHtmlIsRequested(htmlRequests1);
2465 // Unfortunately, there is no other good way of verifying that AppCache is
2466 // disabled, other than checking that it didn't try to fetch the manifest.
2469 prevManifestRequestCount, webServer.getRequestCount(helper1.getManifestPath()));
2471 if (webServer != null) webServer.shutdown();
2476 @Feature({"AndroidWebView", "Preferences"})
2477 public void testUseWideViewportWithTwoViews() throws Throwable {
2478 ViewPair views = createViews(true);
2479 runPerViewSettingsTest(
2480 new AwSettingsUseWideViewportTestHelper(views.getContainer0(), views.getClient0()),
2481 new AwSettingsUseWideViewportTestHelper(views.getContainer1(), views.getClient1()));
2485 @Feature({"AndroidWebView", "Preferences"})
2486 public void testUseWideViewportWithTwoViewsNoQuirks() throws Throwable {
2487 ViewPair views = createViews();
2488 runPerViewSettingsTest(
2489 new AwSettingsUseWideViewportTestHelper(views.getContainer0(), views.getClient0()),
2490 new AwSettingsUseWideViewportTestHelper(views.getContainer1(), views.getClient1()));
2493 private void useWideViewportLayoutWidthTest(
2494 AwTestContainerView testContainer, CallbackHelper onPageFinishedHelper)
2496 final AwContents awContents = testContainer.getAwContents();
2497 AwSettings settings = getAwSettingsOnUiThread(awContents);
2499 final String pageTemplate = "<html><head>%s</head>" +
2500 "<body onload='document.title=document.body.clientWidth'></body></html>";
2501 final String pageNoViewport = String.format(pageTemplate, "");
2502 final String pageViewportDeviceWidth = String.format(
2504 "<meta name='viewport' content='width=device-width' />");
2505 final String viewportTagSpecifiedWidth = "3000";
2506 final String pageViewportSpecifiedWidth = String.format(
2508 "<meta name='viewport' content='width=" + viewportTagSpecifiedWidth + "' />");
2510 DeviceDisplayInfo deviceInfo = DeviceDisplayInfo.create(testContainer.getContext());
2511 int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
2513 settings.setJavaScriptEnabled(true);
2514 assertFalse(settings.getUseWideViewPort());
2515 // When UseWideViewPort is off, "width" setting of "meta viewport"
2516 // tags is ignored, and the layout width is set to device width in CSS pixels.
2517 // Thus, all 3 pages will have the same body width.
2518 loadDataSync(awContents, onPageFinishedHelper, pageNoViewport, "text/html", false);
2519 int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2520 // Avoid rounding errors.
2521 assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
2522 Math.abs(displayWidth - actualWidth) <= 1);
2523 loadDataSync(awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false);
2524 actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2525 assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
2526 Math.abs(displayWidth - actualWidth) <= 1);
2528 awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false);
2529 actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2530 assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
2531 Math.abs(displayWidth - actualWidth) <= 1);
2533 settings.setUseWideViewPort(true);
2534 // When UseWideViewPort is on, "meta viewport" tag is used.
2535 // If there is no viewport tag, or width isn't specified,
2536 // then layout width is set to max(980, <device-width-in-DIP-pixels>)
2537 loadDataSync(awContents, onPageFinishedHelper, pageNoViewport, "text/html", false);
2538 actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2539 assertTrue("Expected: >= 980 , Actual: " + actualWidth, actualWidth >= 980);
2540 loadDataSync(awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false);
2541 actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
2542 assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
2543 Math.abs(displayWidth - actualWidth) <= 1);
2545 awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false);
2546 assertEquals(viewportTagSpecifiedWidth, getTitleOnUiThread(awContents));
2550 @Feature({"AndroidWebView", "Preferences"})
2551 public void testUseWideViewportLayoutWidth() throws Throwable {
2552 TestAwContentsClient contentClient = new TestAwContentsClient();
2553 AwTestContainerView testContainerView =
2554 createAwTestContainerViewOnMainSync(contentClient);
2555 useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper());
2559 @Feature({"AndroidWebView", "Preferences"})
2560 public void testUseWideViewportLayoutWidthNoQuirks() throws Throwable {
2561 TestAwContentsClient contentClient = new TestAwContentsClient();
2562 AwTestContainerView testContainerView =
2563 createAwTestContainerViewOnMainSync(contentClient, false);
2564 useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper());
2568 @Feature({"AndroidWebView", "Preferences"})
2569 public void testUseWideViewportControlsDoubleTabToZoom() throws Throwable {
2570 final TestAwContentsClient contentClient = new TestAwContentsClient();
2571 final AwTestContainerView testContainerView =
2572 createAwTestContainerViewOnMainSync(contentClient);
2573 final AwContents awContents = testContainerView.getAwContents();
2574 CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
2575 AwSettings settings = getAwSettingsOnUiThread(awContents);
2576 settings.setBuiltInZoomControls(true);
2578 DeviceDisplayInfo deviceInfo =
2579 DeviceDisplayInfo.create(testContainerView.getContext());
2580 int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
2581 int layoutWidth = displayWidth * 2;
2582 final String page = "<html>" +
2583 "<head><meta name='viewport' content='width=" + layoutWidth + "'>" +
2584 "<style> body { width: " + layoutWidth + "px; }</style></head>" +
2585 "<body>Page Text</body></html>";
2587 assertFalse(settings.getUseWideViewPort());
2588 // Without wide viewport the <meta viewport> tag will be ignored by WebView,
2589 // but it doesn't really matter as we don't expect double tap to change the scale.
2590 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2591 final float initialScale = getScaleOnUiThread(awContents);
2592 simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView);
2594 assertEquals(initialScale, getScaleOnUiThread(awContents));
2596 settings.setUseWideViewPort(true);
2597 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2598 int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
2599 simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView);
2600 contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
2601 final float zoomedOutScale = getScaleOnUiThread(awContents);
2602 assertTrue("zoomedOut: " + zoomedOutScale + ", initial: " + initialScale,
2603 zoomedOutScale < initialScale);
2607 @Feature({"AndroidWebView", "Preferences"})
2608 public void testForceZeroLayoutHeightWithTwoViews() throws Throwable {
2609 ViewPair views = createViews();
2610 runPerViewSettingsTest(
2611 new AwSettingsForceZeroLayoutHeightTestHelper(
2612 views.getContainer0(), views.getClient0(), false),
2613 new AwSettingsForceZeroLayoutHeightTestHelper(
2614 views.getContainer1(), views.getClient1(), false));
2618 @Feature({"AndroidWebView", "Preferences"})
2619 public void testForceZeroLayoutHeightViewportTagWithTwoViews() throws Throwable {
2620 ViewPair views = createViews();
2621 runPerViewSettingsTest(
2622 new AwSettingsForceZeroLayoutHeightTestHelper(
2623 views.getContainer0(), views.getClient0(), true),
2624 new AwSettingsForceZeroLayoutHeightTestHelper(
2625 views.getContainer1(), views.getClient1(), true));
2629 @Feature({"AndroidWebView", "Preferences"})
2630 public void testZeroLayoutHeightDisablesViewportQuirkWithTwoViews() throws Throwable {
2631 ViewPair views = createViews();
2632 runPerViewSettingsTest(
2633 new AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper(
2634 views.getContainer0(), views.getClient0()),
2635 new AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper(
2636 views.getContainer1(), views.getClient1()));
2640 @Feature({"AndroidWebView", "Preferences"})
2641 public void testLoadWithOverviewModeWithTwoViews() throws Throwable {
2642 ViewPair views = createViews();
2643 runPerViewSettingsTest(
2644 new AwSettingsLoadWithOverviewModeTestHelper(
2645 views.getContainer0(), views.getClient0(), false),
2646 new AwSettingsLoadWithOverviewModeTestHelper(
2647 views.getContainer1(), views.getClient1(), false));
2651 @Feature({"AndroidWebView", "Preferences"})
2652 public void testLoadWithOverviewModeViewportTagWithTwoViews() throws Throwable {
2653 ViewPair views = createViews();
2654 runPerViewSettingsTest(
2655 new AwSettingsLoadWithOverviewModeTestHelper(
2656 views.getContainer0(), views.getClient0(), true),
2657 new AwSettingsLoadWithOverviewModeTestHelper(
2658 views.getContainer1(), views.getClient1(), true));
2662 @Feature({"AndroidWebView", "Preferences"})
2663 public void testSetInitialScale() throws Throwable {
2664 final TestAwContentsClient contentClient = new TestAwContentsClient();
2665 final AwTestContainerView testContainerView =
2666 createAwTestContainerViewOnMainSync(contentClient);
2667 final AwContents awContents = testContainerView.getAwContents();
2668 final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
2669 CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
2671 WindowManager wm = (WindowManager) getInstrumentation().getTargetContext()
2672 .getSystemService(Context.WINDOW_SERVICE);
2673 Point screenSize = new Point();
2674 wm.getDefaultDisplay().getSize(screenSize);
2675 // Make sure after 50% scale, page width still larger than screen.
2676 int height = screenSize.y * 2 + 1;
2677 int width = screenSize.x * 2 + 1;
2678 final String page = "<html><body>" +
2679 "<p style='height:" + height + "px;width:" + width + "px'>" +
2680 "testSetInitialScale</p></body></html>";
2681 final float defaultScale =
2682 getInstrumentation().getTargetContext().getResources().getDisplayMetrics().density;
2684 assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
2685 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2686 assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
2688 int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
2689 awSettings.setInitialPageScale(50);
2690 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2691 contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
2692 assertEquals(0.5f, getPixelScaleOnUiThread(awContents), .01f);
2694 onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
2695 awSettings.setInitialPageScale(500);
2696 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2697 contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
2698 assertEquals(5.0f, getPixelScaleOnUiThread(awContents), .01f);
2700 onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
2701 awSettings.setInitialPageScale(0);
2702 loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
2703 contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
2704 assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
2709 @Feature({"AndroidWebView", "Preferences"})
2710 http://crbug.com/304549
2713 public void testMediaPlaybackWithoutUserGesture() throws Throwable {
2714 assertTrue(VideoTestUtil.runVideoTest(this, false, WAIT_TIMEOUT_MS));
2718 @Feature({"AndroidWebView", "Preferences"})
2719 public void testMediaPlaybackWithUserGesture() throws Throwable {
2720 // Wait for 5 second to see if video played.
2721 assertFalse(VideoTestUtil.runVideoTest(this, true, scaleTimeout(5000)));
2725 @Feature({"AndroidWebView", "Preferences"})
2726 public void testDefaultVideoPosterURL() throws Throwable {
2727 final CallbackHelper videoPosterAccessedCallbackHelper = new CallbackHelper();
2728 final String defaultVideoPosterUrl = "http://default_video_poster/";
2729 TestAwContentsClient client = new TestAwContentsClient() {
2731 public AwWebResourceResponse shouldInterceptRequest(
2732 ShouldInterceptRequestParams params) {
2733 if (params.url.equals(defaultVideoPosterUrl)) {
2734 videoPosterAccessedCallbackHelper.notifyCalled();
2739 final AwContents awContents = createAwTestContainerViewOnMainSync(client).getAwContents();
2740 getInstrumentation().runOnMainSync(new Runnable() {
2743 AwSettings awSettings = awContents.getSettings();
2744 awSettings.setDefaultVideoPosterURL(defaultVideoPosterUrl);
2747 VideoTestWebServer webServer = new VideoTestWebServer(
2748 getInstrumentation().getTargetContext());
2750 String data = "<html><head><body>" +
2751 "<video id='video' control src='" +
2752 webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
2753 loadDataAsync(awContents, data, "text/html", false);
2754 videoPosterAccessedCallbackHelper.waitForCallback(0, 1, 20, TimeUnit.SECONDS);
2756 if (webServer.getTestWebServer() != null)
2757 webServer.getTestWebServer().shutdown();
2762 @Feature({"AndroidWebView", "Preferences"})
2763 public void testAllowMixedMode() throws Throwable {
2764 final TestAwContentsClient contentClient = new TestAwContentsClient() {
2766 public void onReceivedSslError(ValueCallback<Boolean> callback, SslError error) {
2767 callback.onReceiveValue(true);
2770 final AwTestContainerView testContainerView =
2771 createAwTestContainerViewOnMainSync(contentClient);
2772 final AwContents awContents = testContainerView.getAwContents();
2773 final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
2775 awSettings.setJavaScriptEnabled(true);
2777 TestWebServer httpsServer = null;
2778 TestWebServer httpServer = null;
2780 httpsServer = new TestWebServer(true);
2781 httpServer = new TestWebServer(false);
2783 final String jsUrl = "/insecure.js";
2784 final String imageUrl = "/insecure.png";
2785 final String secureUrl = "/secure.html";
2786 httpServer.setResponse(jsUrl, "window.loaded_js = 42;", null);
2787 httpServer.setResponseBase64(imageUrl, CommonResources.FAVICON_DATA_BASE64, null);
2789 final String jsHtml = "<script src=\"" + httpServer.getResponseUrl(jsUrl) +
2791 final String imageHtml = "<img src=\"" + httpServer.getResponseUrl(imageUrl) + "\" />";
2792 final String secureHtml = "<body>" + imageHtml + " " + jsHtml + "</body>";
2794 String fullSecureUrl = httpsServer.setResponse(secureUrl, secureHtml, null);
2796 awSettings.setMixedContentMode(AwSettings.MIXED_CONTENT_NEVER_ALLOW);
2797 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl);
2798 assertEquals(1, httpsServer.getRequestCount(secureUrl));
2799 assertEquals(0, httpServer.getRequestCount(jsUrl));
2800 assertEquals(0, httpServer.getRequestCount(imageUrl));
2802 awSettings.setMixedContentMode(AwSettings.MIXED_CONTENT_ALWAYS_ALLOW);
2803 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl);
2804 assertEquals(2, httpsServer.getRequestCount(secureUrl));
2805 assertEquals(1, httpServer.getRequestCount(jsUrl));
2806 assertEquals(1, httpServer.getRequestCount(imageUrl));
2808 awSettings.setMixedContentMode(AwSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
2809 loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl);
2810 assertEquals(3, httpsServer.getRequestCount(secureUrl));
2811 assertEquals(1, httpServer.getRequestCount(jsUrl));
2812 assertEquals(2, httpServer.getRequestCount(imageUrl));
2814 if (httpServer != null) {
2815 httpServer.shutdown();
2817 if (httpsServer != null) {
2818 httpsServer.shutdown();
2824 static class ViewPair {
2825 private final AwTestContainerView mContainer0;
2826 private final TestAwContentsClient mClient0;
2827 private final AwTestContainerView mContainer1;
2828 private final TestAwContentsClient mClient1;
2830 ViewPair(AwTestContainerView container0, TestAwContentsClient client0,
2831 AwTestContainerView container1, TestAwContentsClient client1) {
2832 this.mContainer0 = container0;
2833 this.mClient0 = client0;
2834 this.mContainer1 = container1;
2835 this.mClient1 = client1;
2838 AwTestContainerView getContainer0() {
2842 AwContents getContents0() {
2843 return mContainer0.getAwContents();
2846 TestAwContentsClient getClient0() {
2850 AwTestContainerView getContainer1() {
2854 AwContents getContents1() {
2855 return mContainer1.getAwContents();
2858 TestAwContentsClient getClient1() {
2864 * Verifies the following statements about a setting:
2865 * - initially, the setting has a default value;
2866 * - the setting can be switched to an alternate value and back;
2867 * - switching a setting in the first WebView doesn't affect the setting
2868 * state in the second WebView and vice versa.
2870 * @param helper0 Test helper for the first ContentView
2871 * @param helper1 Test helper for the second ContentView
2874 private void runPerViewSettingsTest(AwSettingsTestHelper helper0,
2875 AwSettingsTestHelper helper1) throws Throwable {
2876 helper0.ensureSettingHasInitialValue();
2877 helper1.ensureSettingHasInitialValue();
2879 helper1.setAlteredSettingValue();
2880 helper0.ensureSettingHasInitialValue();
2881 helper1.ensureSettingHasAlteredValue();
2883 helper1.setInitialSettingValue();
2884 helper0.ensureSettingHasInitialValue();
2885 helper1.ensureSettingHasInitialValue();
2887 helper0.setAlteredSettingValue();
2888 helper0.ensureSettingHasAlteredValue();
2889 helper1.ensureSettingHasInitialValue();
2891 helper0.setInitialSettingValue();
2892 helper0.ensureSettingHasInitialValue();
2893 helper1.ensureSettingHasInitialValue();
2895 helper0.setAlteredSettingValue();
2896 helper0.ensureSettingHasAlteredValue();
2897 helper1.ensureSettingHasInitialValue();
2899 helper1.setAlteredSettingValue();
2900 helper0.ensureSettingHasAlteredValue();
2901 helper1.ensureSettingHasAlteredValue();
2903 helper0.setInitialSettingValue();
2904 helper0.ensureSettingHasInitialValue();
2905 helper1.ensureSettingHasAlteredValue();
2907 helper1.setInitialSettingValue();
2908 helper0.ensureSettingHasInitialValue();
2909 helper1.ensureSettingHasInitialValue();
2912 private ViewPair createViews() throws Throwable {
2913 return createViews(false);
2916 private ViewPair createViews(boolean supportsLegacyQuirks) throws Throwable {
2917 TestAwContentsClient client0 = new TestAwContentsClient();
2918 TestAwContentsClient client1 = new TestAwContentsClient();
2919 return new ViewPair(
2920 createAwTestContainerViewOnMainSync(client0, supportsLegacyQuirks),
2922 createAwTestContainerViewOnMainSync(client1, supportsLegacyQuirks),
2926 static void assertFileIsReadable(String filePath) {
2927 File file = new File(filePath);
2929 assertTrue("Test file \"" + filePath + "\" is not readable." +
2930 "Please make sure that files from android_webview/test/data/device_files/ " +
2931 "has been pushed to the device before testing",
2933 } catch (SecurityException e) {
2934 fail("Got a SecurityException for \"" + filePath + "\": " + e.toString());
2939 * Verifies the number of resource requests made to the content provider.
2940 * @param resource Resource name
2941 * @param expectedCount Expected resource requests count
2943 private void ensureResourceRequestCountInContentProvider(String resource, int expectedCount) {
2944 Context context = getInstrumentation().getTargetContext();
2945 int actualCount = TestContentProvider.getResourceRequestCount(context, resource);
2946 assertEquals(expectedCount, actualCount);
2949 private void resetResourceRequestCountInContentProvider(String resource) {
2950 Context context = getInstrumentation().getTargetContext();
2951 TestContentProvider.resetResourceRequestCount(context, resource);
2954 private String createContentUrl(final String target) {
2955 return TestContentProvider.createContentUrl(target);
2958 private void simulateDoubleTapCenterOfWebViewOnUiThread(final AwTestContainerView webView)
2960 final int x = (webView.getRight() - webView.getLeft()) / 2;
2961 final int y = (webView.getBottom() - webView.getTop()) / 2;
2962 final AwContents awContents = webView.getAwContents();
2963 runTestOnUiThread(new Runnable() {
2966 awContents.getContentViewCore().sendDoubleTapForTest(
2967 SystemClock.uptimeMillis(), x, y);