// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.android_webview.test;

import static org.chromium.android_webview.test.AwActivityTestRule.WAIT_TIMEOUT_MS;
import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;

import android.content.Context;
import android.graphics.Point;
import android.net.http.SslError;
import android.os.Build;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;

import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwSettings;
import org.chromium.android_webview.AwSettings.LayoutAlgorithm;
import org.chromium.android_webview.AwWebResourceResponse;
import org.chromium.android_webview.test.AwActivityTestRule.TestDependencyFactory;
import org.chromium.android_webview.test.TestAwContentsClient.DoUpdateVisitedHistoryHelper;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.ImagePageGenerator;
import org.chromium.android_webview.test.util.JSUtils;
import org.chromium.android_webview.test.util.VideoTestUtil;
import org.chromium.android_webview.test.util.VideoTestWebServer;
import org.chromium.base.Callback;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.RetryOnFailure;
import org.chromium.base.test.util.TestFileUtil;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.content_public.browser.test.util.DOMUtils;
import org.chromium.content_public.browser.test.util.HistoryUtils;
import org.chromium.content_public.common.ContentSwitches;
import org.chromium.content_public.common.ContentUrlConstants;
import org.chromium.net.test.EmbeddedTestServer;
import org.chromium.net.test.util.TestWebServer;
import org.chromium.ui.display.DisplayAndroid;
import org.chromium.ui.display.DisplayUtil;

import java.io.File;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A test suite for AwSettings class. The key objective is to verify that each
 * settings applies either to each individual view or to all views of the
 * application
 */
@RunWith(AwJUnit4ClassRunner.class)
@CommandLineFlags.Add(ContentSwitches.HOST_RESOLVER_RULES + "=MAP * 127.0.0.1")
public class AwSettingsTest {
    @Rule
    public AwActivityTestRule mActivityTestRule =
            new AwActivityTestRule() {
                @Override
                public TestDependencyFactory createTestDependencyFactory() {
                    if (mOverridenFactory == null) {
                        return new TestDependencyFactory();
                    } else {
                        return mOverridenFactory;
                    }
                }
            };

    private static final boolean ENABLED = true;
    private static final boolean DISABLED = false;

    private int mTitleIdx;

    /**
     * A helper class for testing a particular preference from AwSettings.
     * The generic type T is the type of the setting. Usually, to test an
     * effect of the preference, JS code is executed that sets document's title.
     * In this case, requiresJsEnabled constructor argument must be set to true.
     */
    abstract class AwSettingsTestHelper<T> {
        protected final AwContents mAwContents;
        protected final Context mContext;
        protected final TestAwContentsClient mContentViewClient;
        protected final AwSettings mAwSettings;

        AwSettingsTestHelper(AwTestContainerView containerView,
                             TestAwContentsClient contentViewClient,
                             boolean requiresJsEnabled) throws Throwable {
            mAwContents = containerView.getAwContents();
            mContext = containerView.getContext();
            mContentViewClient = contentViewClient;
            mAwSettings = mActivityTestRule.getAwSettingsOnUiThread(mAwContents);
            if (requiresJsEnabled) {
                mAwSettings.setJavaScriptEnabled(true);
            }
        }

        void ensureSettingHasAlteredValue() throws Throwable {
            ensureSettingHasValue(getAlteredValue());
        }

        void ensureSettingHasInitialValue() throws Throwable {
            ensureSettingHasValue(getInitialValue());
        }

        void setAlteredSettingValue() throws Throwable {
            setCurrentValue(getAlteredValue());
        }

        void setInitialSettingValue() throws Throwable {
            setCurrentValue(getInitialValue());
        }

        protected abstract T getAlteredValue();

        protected abstract T getInitialValue();

        protected abstract T getCurrentValue();

        protected abstract void setCurrentValue(T value) throws Throwable;

        protected abstract void doEnsureSettingHasValue(T value) throws Throwable;

        protected String getTitleOnUiThread() throws Exception {
            return mActivityTestRule.getTitleOnUiThread(mAwContents);
        }

        protected void loadDataSync(String data) throws Throwable {
            mActivityTestRule.loadDataSync(mAwContents,
                    mContentViewClient.getOnPageFinishedHelper(), data, "text/html", false);
        }

        protected void loadUrlSync(String url) throws Throwable {
            mActivityTestRule.loadUrlSync(
                    mAwContents, mContentViewClient.getOnPageFinishedHelper(), url);
        }

        protected void loadUrlSyncAndExpectError(String url) throws Throwable {
            mActivityTestRule.loadUrlSyncAndExpectError(mAwContents,
                    mContentViewClient.getOnPageFinishedHelper(),
                    mContentViewClient.getOnReceivedErrorHelper(), url);
        }

        protected String executeJavaScriptAndWaitForResult(String script) throws Exception {
            return mActivityTestRule.executeJavaScriptAndWaitForResult(
                    mAwContents, mContentViewClient, script);
        }

        private void ensureSettingHasValue(T value) throws Throwable {
            Assert.assertEquals(value, getCurrentValue());
            doEnsureSettingHasValue(value);
        }
    }

    class AwSettingsJavaScriptTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String JS_ENABLED_STRING = "JS Enabled";
        private static final String JS_DISABLED_STRING = "JS Disabled";

        AwSettingsJavaScriptTestHelper(AwTestContainerView containerView,
                                       TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, false);
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getJavaScriptEnabled();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setJavaScriptEnabled(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadDataSync(getData());
            Assert.assertEquals(value == ENABLED ? JS_ENABLED_STRING : JS_DISABLED_STRING,
                    getTitleOnUiThread());
        }

        private String getData() {
            return "<html><head><title>" + JS_DISABLED_STRING + "</title>"
                    + "</head><body onload=\"document.title='" + JS_ENABLED_STRING
                    + "';\"></body></html>";
        }
    }

    // In contrast to AwSettingsJavaScriptTestHelper, doesn't reload the page when testing
    // JavaScript state.
    class AwSettingsJavaScriptDynamicTestHelper extends AwSettingsJavaScriptTestHelper {
        AwSettingsJavaScriptDynamicTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient);
            // Load the page.
            super.doEnsureSettingHasValue(getInitialValue());
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            String oldTitle = getTitleOnUiThread();
            String newTitle = oldTitle + "_modified";
            executeJavaScriptAndWaitForResult(getScript(newTitle));
            Assert.assertEquals(value == ENABLED ? newTitle : oldTitle, getTitleOnUiThread());
        }

        private String getScript(String title) {
            return "document.title='" + title + "';";
        }
    }

    class AwSettingsStandardFontFamilyTestHelper extends AwSettingsTestHelper<String> {
        AwSettingsStandardFontFamilyTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
        }

        @Override
        protected String getAlteredValue() {
            return "cursive";
        }

        @Override
        protected String getInitialValue() {
            return "sans-serif";
        }

        @Override
        protected String getCurrentValue() {
            return mAwSettings.getStandardFontFamily();
        }

        @Override
        protected void setCurrentValue(String value) {
            mAwSettings.setStandardFontFamily(value);
        }

        @Override
        protected void doEnsureSettingHasValue(String value) throws Throwable {
            loadDataSync(getData());
            Assert.assertEquals(value, getTitleOnUiThread());
        }

        private String getData() {
            return "<html><body onload=\"document.title = "
                    + "getComputedStyle(document.body).getPropertyValue('font-family');\">"
                    + "</body></html>";
        }
    }

    class AwSettingsDefaultFontSizeTestHelper extends AwSettingsTestHelper<Integer> {
        AwSettingsDefaultFontSizeTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
        }

        @Override
        protected Integer getAlteredValue() {
            return 42;
        }

        @Override
        protected Integer getInitialValue() {
            return 16;
        }

        @Override
        protected Integer getCurrentValue() {
            return mAwSettings.getDefaultFontSize();
        }

        @Override
        protected void setCurrentValue(Integer value) {
            mAwSettings.setDefaultFontSize(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Integer value) throws Throwable {
            loadDataSync(getData());
            Assert.assertEquals(value.toString() + "px", getTitleOnUiThread());
        }

        private String getData() {
            return "<html><body onload=\"document.title = "
                    + "getComputedStyle(document.body).getPropertyValue('font-size');\">"
                    + "</body></html>";
        }
    }

    class AwSettingsLoadImagesAutomaticallyTestHelper extends AwSettingsTestHelper<Boolean> {
        private ImagePageGenerator mGenerator;

        AwSettingsLoadImagesAutomaticallyTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient,
                ImagePageGenerator generator) throws Throwable {
            super(containerView, contentViewClient, true);
            mGenerator = generator;
        }

        @Override
        protected Boolean getAlteredValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getLoadsImagesAutomatically();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setLoadsImagesAutomatically(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadDataSync(mGenerator.getPageSource());
            Assert.assertEquals(value == ENABLED ? ImagePageGenerator.IMAGE_LOADED_STRING
                                                 : ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
                    getTitleOnUiThread());
        }
    }


    class AwSettingsImagesEnabledHelper extends AwSettingsTestHelper<Boolean> {

        AwSettingsImagesEnabledHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient,
                TestWebServer webServer,
                ImagePageGenerator generator) throws Throwable {
            super(containerView, contentViewClient, true);
            mWebServer = webServer;
            mGenerator = generator;
        }

        @Override
        protected Boolean getAlteredValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getImagesEnabled();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setImagesEnabled(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            final String httpImageUrl = mGenerator.getPageUrl(mWebServer);
            mActivityTestRule.loadUrlSync(
                    mAwContents, mContentViewClient.getOnPageFinishedHelper(), httpImageUrl);
            Assert.assertEquals(value == ENABLED ? ImagePageGenerator.IMAGE_LOADED_STRING
                                                 : ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
                    getTitleOnUiThread());
        }

        private TestWebServer mWebServer;
        private ImagePageGenerator mGenerator;
    }

    class AwSettingsDefaultTextEncodingTestHelper extends AwSettingsTestHelper<String> {
        AwSettingsDefaultTextEncodingTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
        }

        @Override
        protected String getAlteredValue() {
            return "Latin-1";
        }

        @Override
        protected String getInitialValue() {
            return "UTF-8";
        }

        @Override
        protected String getCurrentValue() {
            return mAwSettings.getDefaultTextEncodingName();
        }

        @Override
        protected void setCurrentValue(String value) {
            mAwSettings.setDefaultTextEncodingName(value);
        }

        @Override
        protected void doEnsureSettingHasValue(String value) throws Throwable {
            loadDataSync(getData());
            Assert.assertEquals(value, getTitleOnUiThread());
        }

        private String getData() {
            return "<html><body onload='document.title=document.defaultCharset'></body></html>";
        }
    }

    class AwSettingsUserAgentStringTestHelper extends AwSettingsTestHelper<String> {
        private final String mDefaultUa;
        private static final String DEFAULT_UA = "";
        private static final String CUSTOM_UA = "ChromeViewTest";

        AwSettingsUserAgentStringTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            mDefaultUa = mAwSettings.getUserAgentString();
        }

        @Override
        protected String getAlteredValue() {
            return CUSTOM_UA;
        }

        @Override
        protected String getInitialValue() {
            return DEFAULT_UA;
        }

        @Override
        protected String getCurrentValue() {
            // The test framework expects that getXXX() == Z after setXXX(Z).
            // But setUserAgentString("" / null) resets the UA string to default,
            // and getUserAgentString returns the default UA string afterwards.
            // To align with the framework, we return an empty string instead of
            // the default UA.
            String currentUa = mAwSettings.getUserAgentString();
            return mDefaultUa.equals(currentUa) ? DEFAULT_UA : currentUa;
        }

        @Override
        protected void setCurrentValue(String value) {
            mAwSettings.setUserAgentString(value);
        }

        @Override
        protected void doEnsureSettingHasValue(String value) throws Throwable {
            loadDataSync(getData());
            Assert.assertEquals(
                    DEFAULT_UA.equals(value) ? mDefaultUa : value, getTitleOnUiThread());
        }

        private String getData() {
            return "<html><body onload='document.title=navigator.userAgent'></body></html>";
        }
    }

    class AwSettingsDomStorageEnabledTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String TEST_FILE = "android_webview/test/data/localStorage.html";
        private static final String NO_LOCAL_STORAGE = "No localStorage";
        private static final String HAS_LOCAL_STORAGE = "Has localStorage";

        AwSettingsDomStorageEnabledTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            AwSettingsTest.assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(TEST_FILE));
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getDomStorageEnabled();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setDomStorageEnabled(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            // It is not permitted to access localStorage from data URLs in WebKit,
            // that is why a standalone page must be used.
            loadUrlSync(UrlUtils.getIsolatedTestFileUrl(TEST_FILE));
            Assert.assertEquals(
                    value == ENABLED ? HAS_LOCAL_STORAGE : NO_LOCAL_STORAGE, getTitleOnUiThread());
        }
    }

    class AwSettingsDatabaseTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String TEST_FILE = "android_webview/test/data/database_access.html";
        private static final String NO_DATABASE = "No database";
        private static final String HAS_DATABASE = "Has database";

        AwSettingsDatabaseTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            AwSettingsTest.assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(TEST_FILE));
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getDatabaseEnabled();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setDatabaseEnabled(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            // It seems accessing the database through a data scheme is not
            // supported, and fails with a DOM exception (likely a cross-domain
            // violation).
            loadUrlSync(UrlUtils.getIsolatedTestFileUrl(TEST_FILE));
            Assert.assertEquals(
                    value == ENABLED ? HAS_DATABASE : NO_DATABASE, getTitleOnUiThread());
        }
    }

    class AwSettingsUniversalAccessFromFilesTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String TEST_CONTAINER_FILE =
                "android_webview/test/data/iframe_access.html";
        private static final String TEST_FILE = "android_webview/test/data/hello_world.html";
        private static final String ACCESS_DENIED_TITLE = "Exception";

        AwSettingsUniversalAccessFromFilesTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            AwSettingsTest.assertFileIsReadable(
                    UrlUtils.getIsolatedTestFilePath(TEST_CONTAINER_FILE));
            AwSettingsTest.assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(TEST_FILE));
            mIframeContainerUrl = UrlUtils.getIsolatedTestFileUrl(TEST_CONTAINER_FILE);
            mIframeUrl = UrlUtils.getIsolatedTestFileUrl(TEST_FILE);
            // The value of the setting depends on the SDK version.
            mAwSettings.setAllowUniversalAccessFromFileURLs(false);
            // If universal access is true, the value of file access doesn't
            // matter. While if universal access is false, having file access
            // enabled will allow file loading.
            mAwSettings.setAllowFileAccessFromFileURLs(false);
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getAllowUniversalAccessFromFileURLs();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setAllowUniversalAccessFromFileURLs(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadUrlSync(mIframeContainerUrl);
            Assert.assertEquals(
                    value == ENABLED ? mIframeUrl : ACCESS_DENIED_TITLE, getTitleOnUiThread());
        }

        private final String mIframeContainerUrl;
        private final String mIframeUrl;
    }

    class AwSettingsFileAccessFromFilesIframeTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String TEST_CONTAINER_FILE =
                "android_webview/test/data/iframe_access.html";
        private static final String TEST_FILE = "android_webview/test/data/hello_world.html";
        private static final String ACCESS_DENIED_TITLE = "Exception";

        AwSettingsFileAccessFromFilesIframeTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            AwSettingsTest.assertFileIsReadable(
                    UrlUtils.getIsolatedTestFilePath(TEST_CONTAINER_FILE));
            AwSettingsTest.assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(TEST_FILE));
            mIframeContainerUrl = UrlUtils.getIsolatedTestFileUrl(TEST_CONTAINER_FILE);
            mIframeUrl = UrlUtils.getIsolatedTestFileUrl(TEST_FILE);
            mAwSettings.setAllowUniversalAccessFromFileURLs(false);
            // The value of the setting depends on the SDK version.
            mAwSettings.setAllowFileAccessFromFileURLs(false);
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getAllowFileAccessFromFileURLs();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setAllowFileAccessFromFileURLs(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadUrlSync(mIframeContainerUrl);
            Assert.assertEquals(
                    value == ENABLED ? mIframeUrl : ACCESS_DENIED_TITLE, getTitleOnUiThread());
        }

        private final String mIframeContainerUrl;
        private final String mIframeUrl;
    }

    class AwSettingsFileAccessFromFilesXhrTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String TEST_FILE = "android_webview/test/data/xhr_access.html";
        private static final String ACCESS_GRANTED_TITLE = "Hello, World!";
        private static final String ACCESS_DENIED_TITLE = "Exception";

        AwSettingsFileAccessFromFilesXhrTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(TEST_FILE));
            mXhrContainerUrl = UrlUtils.getIsolatedTestFileUrl(TEST_FILE);
            mAwSettings.setAllowUniversalAccessFromFileURLs(false);
            // The value of the setting depends on the SDK version.
            mAwSettings.setAllowFileAccessFromFileURLs(false);
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getAllowFileAccessFromFileURLs();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setAllowFileAccessFromFileURLs(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadUrlSync(mXhrContainerUrl);
            Assert.assertEquals(value == ENABLED ? ACCESS_GRANTED_TITLE : ACCESS_DENIED_TITLE,
                    getTitleOnUiThread());
        }

        private final String mXhrContainerUrl;
    }

    class AwSettingsFileUrlAccessTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String TEST_FILE = "android_webview/test/data/hello_world.html";
        private static final String ACCESS_GRANTED_TITLE = "Hello, World!";

        AwSettingsFileUrlAccessTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient,
                int startIndex) throws Throwable {
            super(containerView, contentViewClient, true);
            mIndex = startIndex;
            AwSettingsTest.assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(TEST_FILE));
        }

        @Override
        protected Boolean getAlteredValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getAllowFileAccess();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setAllowFileAccess(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            // Use query parameters to avoid hitting a cached page.
            String fileUrl = UrlUtils.getIsolatedTestFileUrl(TEST_FILE + "?id=" + mIndex);
            mIndex += 2;
            if (value == ENABLED) {
                loadUrlSync(fileUrl);
                Assert.assertEquals(ACCESS_GRANTED_TITLE, getTitleOnUiThread());
            } else {
                loadUrlSyncAndExpectError(fileUrl);
            }
        }

        private int mIndex;
    }

    class AwSettingsContentUrlAccessTestHelper extends AwSettingsTestHelper<Boolean> {

        AwSettingsContentUrlAccessTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient,
                int index) throws Throwable {
            super(containerView, contentViewClient, true);
            mTarget = "content_access_" + index;
        }

        @Override
        protected Boolean getAlteredValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getAllowContentAccess();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setAllowContentAccess(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            resetResourceRequestCountInContentProvider(mTarget);
            if (value == ENABLED) {
                loadUrlSync(createContentUrl(mTarget));
                String title = getTitleOnUiThread();
                Assert.assertNotNull(title);
                Assert.assertTrue("[" + mTarget + "] Actual title: \"" + title + "\"",
                        title.contains(mTarget));
                ensureResourceRequestCountInContentProvider(mTarget, 1);
            } else {
                loadUrlSyncAndExpectError(createContentUrl(mTarget));
                ensureResourceRequestCountInContentProvider(mTarget, 0);
            }
        }

        private final String mTarget;
    }

    class AwSettingsContentUrlAccessFromFileTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String TARGET = "content_from_file";

        AwSettingsContentUrlAccessFromFileTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient,
                int index) throws Throwable {
            super(containerView, contentViewClient, true);
            mIndex = index;
            mTempDir = InstrumentationRegistry.getInstrumentation()
                               .getTargetContext()
                               .getCacheDir()
                               .getPath();
        }

        @Override
        protected Boolean getAlteredValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getAllowContentAccess();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setAllowContentAccess(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            resetResourceRequestCountInContentProvider(TARGET);
            final String fileName = mTempDir + "/" + TARGET + ".html";
            try {
                TestFileUtil.createNewHtmlFile(fileName, TARGET,
                        "<img src=\""
                                // Adding a query avoids hitting a cached image, and also verifies
                                // that content URL query parameters are ignored when accessing
                                // a content provider.
                                + createContentUrl(TARGET + "?id=" + mIndex) + "\">");
                mIndex += 2;
                loadUrlSync("file://" + fileName);
                if (value == ENABLED) {
                    ensureResourceRequestCountInContentProvider(TARGET, 1);
                } else {
                    ensureResourceRequestCountInContentProvider(TARGET, 0);
                }
            } finally {
                TestFileUtil.deleteFile(fileName);
            }
        }

        private int mIndex;
        private String mTempDir;
    }

    // This class provides helper methods for testing of settings related to
    // the text autosizing feature.
    abstract class AwSettingsTextAutosizingTestHelper<T> extends AwSettingsTestHelper<T> {
        protected static final float PARAGRAPH_FONT_SIZE = 14.0f;

        AwSettingsTextAutosizingTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            mNeedToWaitForFontSizeChange = false;
            loadDataSync(getData());
        }

        @Override
        protected void setCurrentValue(T value) throws Throwable {
            mNeedToWaitForFontSizeChange = false;
            if (value != getCurrentValue()) {
                mOldFontSize = getActualFontSize();
                mNeedToWaitForFontSizeChange = true;
            }
        }

        protected float getActualFontSize() throws Throwable {
            if (!mNeedToWaitForFontSizeChange) {
                executeJavaScriptAndWaitForResult("setTitleToActualFontSize()");
            } else {
                final float oldFontSize = mOldFontSize;
                AwActivityTestRule.pollInstrumentationThread(() -> {
                    executeJavaScriptAndWaitForResult("setTitleToActualFontSize()");
                    float newFontSize = Float.parseFloat(getTitleOnUiThread());
                    return newFontSize != oldFontSize;
                });
                mNeedToWaitForFontSizeChange = false;
            }
            return Float.parseFloat(getTitleOnUiThread());
        }

        protected String getData() {
            int displayWidth = calcDisplayWidthDp(mContext);
            int layoutWidth = (int) (displayWidth * 2.5f); // Use 2.5 as autosizing layout tests do.
            StringBuilder sb = new StringBuilder();
            sb.append("<html>"
                    + "<head>"
                    + "<meta name=\"viewport\" content=\"width=" + layoutWidth + "\">"
                    + "<style>"
                    + "body { width: " + layoutWidth + "px; margin: 0; overflow-y: hidden; }"
                    + "</style>"
                    + "<script>"
                    + "function setTitleToActualFontSize() {"
                    // parseFloat is used to trim out the "px" suffix.
                    + "  document.title = parseFloat(getComputedStyle("
                    + "    document.getElementById('par')).getPropertyValue('font-size'));"
                    + "}</script></head>"
                    + "<body>"
                    + "<p id=\"par\" style=\"font-size:");
            sb.append(PARAGRAPH_FONT_SIZE);
            sb.append("px;\">");
            // Make the paragraph wide enough for being processed by the font autosizer.
            for (int i = 0; i < 500; i++) {
                sb.append("Hello, World! ");
            }
            sb.append("</p></body></html>");
            return sb.toString();
        }

        private boolean mNeedToWaitForFontSizeChange;
        private float mOldFontSize;
    }

    class AwSettingsLayoutAlgorithmTestHelper extends AwSettingsTextAutosizingTestHelper<Integer> {
        AwSettingsLayoutAlgorithmTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient);
            // Font autosizing doesn't step in for narrow layout widths.
            mAwSettings.setUseWideViewPort(true);
        }

        @LayoutAlgorithm
        @Override
        protected Integer getAlteredValue() {
            return AwSettings.LAYOUT_ALGORITHM_TEXT_AUTOSIZING;
        }

        @LayoutAlgorithm
        @Override
        protected Integer getInitialValue() {
            return AwSettings.LAYOUT_ALGORITHM_NARROW_COLUMNS;
        }

        @LayoutAlgorithm
        @Override
        protected Integer getCurrentValue() {
            return mAwSettings.getLayoutAlgorithm();
        }

        @Override
        protected void setCurrentValue(@LayoutAlgorithm Integer value) throws Throwable {
            super.setCurrentValue(value);
            mAwSettings.setLayoutAlgorithm(value);
        }

        @Override
        protected void doEnsureSettingHasValue(@LayoutAlgorithm Integer value) throws Throwable {
            final float actualFontSize = getActualFontSize();
            if (value == AwSettings.LAYOUT_ALGORITHM_TEXT_AUTOSIZING) {
                Assert.assertFalse("Actual font size: " + actualFontSize,
                        actualFontSize == PARAGRAPH_FONT_SIZE);
            } else {
                Assert.assertTrue("Actual font size: " + actualFontSize,
                        actualFontSize == PARAGRAPH_FONT_SIZE);
            }
        }
    }

    class AwSettingsTextZoomTestHelper extends AwSettingsTextAutosizingTestHelper<Integer> {
        private static final int INITIAL_TEXT_ZOOM = 100;
        private final float mInitialActualFontSize;

        AwSettingsTextZoomTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient);
            mInitialActualFontSize = getActualFontSize();
        }

        @Override
        protected Integer getAlteredValue() {
            return INITIAL_TEXT_ZOOM * 2;
        }

        @Override
        protected Integer getInitialValue() {
            return INITIAL_TEXT_ZOOM;
        }

        @Override
        protected Integer getCurrentValue() {
            return mAwSettings.getTextZoom();
        }

        @Override
        protected void setCurrentValue(Integer value) throws Throwable {
            super.setCurrentValue(value);
            mAwSettings.setTextZoom(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Integer value) throws Throwable {
            final float actualFontSize = getActualFontSize();
            // Ensure that actual vs. initial font size ratio is similar to actual vs. initial
            // text zoom values ratio.
            final float ratiosDelta = Math.abs(
                    (actualFontSize / mInitialActualFontSize)
                    - (value / (float) INITIAL_TEXT_ZOOM));
            Assert.assertTrue("|(" + actualFontSize + " / " + mInitialActualFontSize + ") - ("
                            + value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta,
                    ratiosDelta <= 0.2f);
        }
    }

    class AwSettingsTextZoomAutosizingTestHelper
            extends AwSettingsTextAutosizingTestHelper<Integer> {
        private static final int INITIAL_TEXT_ZOOM = 100;
        private final float mInitialActualFontSize;

        AwSettingsTextZoomAutosizingTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient);
            mAwSettings.setLayoutAlgorithm(AwSettings.LAYOUT_ALGORITHM_TEXT_AUTOSIZING);
            // The initial font size can be adjusted by font autosizer depending on the page's
            // viewport width.
            mInitialActualFontSize = getActualFontSize();
        }

        @Override
        protected Integer getAlteredValue() {
            return INITIAL_TEXT_ZOOM * 2;
        }

        @Override
        protected Integer getInitialValue() {
            return INITIAL_TEXT_ZOOM;
        }

        @Override
        protected Integer getCurrentValue() {
            return mAwSettings.getTextZoom();
        }

        @Override
        protected void setCurrentValue(Integer value) throws Throwable {
            super.setCurrentValue(value);
            mAwSettings.setTextZoom(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Integer value) throws Throwable {
            final float actualFontSize = getActualFontSize();
            // Ensure that actual vs. initial font size ratio is similar to actual vs. initial
            // text zoom values ratio.
            final float ratiosDelta = Math.abs(
                    (actualFontSize / mInitialActualFontSize)
                    - (value / (float) INITIAL_TEXT_ZOOM));
            Assert.assertTrue("|(" + actualFontSize + " / " + mInitialActualFontSize + ") - ("
                            + value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta,
                    ratiosDelta <= 0.2f);
        }
    }

    class AwSettingsJavaScriptPopupsTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String POPUP_ENABLED = "Popup enabled";
        private static final String POPUP_BLOCKED = "Popup blocked";

        AwSettingsJavaScriptPopupsTestHelper(AwTestContainerView containerView,
                TestAwContentsClient contentViewClient, boolean openTwice) throws Throwable {
            super(containerView, contentViewClient, true);
            mOpenTwice = openTwice;
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getJavaScriptCanOpenWindowsAutomatically();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setJavaScriptCanOpenWindowsAutomatically(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadDataSync(getData());
            final boolean expectPopupEnabled = value;
            AwActivityTestRule.pollInstrumentationThread(() -> {
                String title = getTitleOnUiThread();
                return expectPopupEnabled ? POPUP_ENABLED.equals(title) :
                        POPUP_BLOCKED.equals(title);
            });
            Assert.assertEquals(value ? POPUP_ENABLED : POPUP_BLOCKED, getTitleOnUiThread());
        }

        private String getData() {
            return "<html><head>"
                    + "<script>"
                    + "    function tryOpenWindow() {"
                    + "        var newWindow = window.open('about:blank');"
                    + (mOpenTwice ? "newWindow = window.open('about:blank');" : "")
                    + "        if (newWindow) {"
                    + "            if (newWindow === window) {"
                    + "                if (newWindow.opener != null) {"
                    + "                    newWindow.document.write("
                    + "                        '<html><head><title>" + POPUP_ENABLED
                    + "</title></head></html>');"
                    + "                } else {"
                    + "                    newWindow.document.write('failed to set opener');"
                    + "                }"
                    + "            } else {"
                    + "                document.title = '" + POPUP_ENABLED + "';"
                    + "            }"
                    + "        } else {"
                    + "          document.title = '" + POPUP_BLOCKED + "';"
                    + "        }"
                    + "    }"
                    + "</script></head>"
                    + "<body onload='tryOpenWindow()'></body></html>";
        }

        private boolean mOpenTwice;
    }

    class AwSettingsCacheModeTestHelper extends AwSettingsTestHelper<Integer> {

        AwSettingsCacheModeTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient,
                int index,
                TestWebServer webServer) throws Throwable {
            super(containerView, contentViewClient, true);
            mIndex = index;
            mWebServer = webServer;
        }

        @Override
        protected Integer getAlteredValue() {
            // We use the value that results in a behaviour completely opposite to default.
            return WebSettings.LOAD_CACHE_ONLY;
        }

        @Override
        protected Integer getInitialValue() {
            return WebSettings.LOAD_DEFAULT;
        }

        @Override
        protected Integer getCurrentValue() {
            return mAwSettings.getCacheMode();
        }

        @Override
        protected void setCurrentValue(Integer value) {
            mAwSettings.setCacheMode(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Integer value) throws Throwable {
            final String htmlPath = "/cache_mode_" + mIndex + ".html";
            mIndex += 2;
            final String url = mWebServer.setResponse(htmlPath, "response", null);
            Assert.assertEquals(0, mWebServer.getRequestCount(htmlPath));
            if (value == WebSettings.LOAD_DEFAULT) {
                loadUrlSync(url);
                Assert.assertEquals(1, mWebServer.getRequestCount(htmlPath));
            } else {
                loadUrlSyncAndExpectError(url);
                Assert.assertEquals(0, mWebServer.getRequestCount(htmlPath));
            }
        }

        private int mIndex;
        private TestWebServer mWebServer;
    }

    // To verify whether UseWideViewport works, we check, if the page width specified
    // in the "meta viewport" tag is applied. When UseWideViewport is turned off, the
    // "viewport" tag is ignored, and the layout width is set to device width in DIP pixels.
    // We specify a very high width value to make sure that it doesn't intersect with
    // device screen widths (in DIP pixels).
    class AwSettingsUseWideViewportTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String VIEWPORT_TAG_LAYOUT_WIDTH = "3000";

        AwSettingsUseWideViewportTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getUseWideViewPort();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setUseWideViewPort(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadDataSync(getData());
            final String bodyWidth = getTitleOnUiThread();
            if (value) {
                Assert.assertTrue(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth));
            } else {
                Assert.assertFalse(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth));
            }
        }

        private String getData() {
            return "<html><head>"
                    + "<meta name='viewport' content='width=" + VIEWPORT_TAG_LAYOUT_WIDTH + "' />"
                    + "</head>"
                    + "<body onload='document.title=document.body.clientWidth'></body></html>";
        }
    }

    class AwSettingsLoadWithOverviewModeTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final float DEFAULT_PAGE_SCALE = 1.0f;

        AwSettingsLoadWithOverviewModeTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient,
                boolean withViewPortTag) throws Throwable {
            super(containerView, contentViewClient, true);
            mWithViewPortTag = withViewPortTag;
            mAwSettings.setUseWideViewPort(true);
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getLoadWithOverviewMode();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mExpectScaleChange = mAwSettings.getLoadWithOverviewMode() != value;
            if (mExpectScaleChange) {
                mOnScaleChangedCallCount =
                        mContentViewClient.getOnScaleChangedHelper().getCallCount();
            }
            mAwSettings.setLoadWithOverviewMode(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadDataSync(getData());
            if (mExpectScaleChange) {
                mContentViewClient.getOnScaleChangedHelper()
                        .waitForCallback(mOnScaleChangedCallCount);
                mExpectScaleChange = false;
            }
            float currentScale = mActivityTestRule.getScaleOnUiThread(mAwContents);
            if (value) {
                Assert.assertTrue("Expected: " + currentScale + " < " + DEFAULT_PAGE_SCALE,
                        currentScale < DEFAULT_PAGE_SCALE);
            } else {
                Assert.assertEquals(DEFAULT_PAGE_SCALE, currentScale, 0);
            }
        }

        private String getData() {
            // Add a sequence number as a comment to ensure WebView does not do
            // something special for the same page load, for instance, restoring
            // user state like a scroll position.
            return "<html><head>"
                    + (mWithViewPortTag ? "<meta name='viewport' content='width=3000' />" : "")
                    + "</head><body><!-- "
                    + mDataSequence++
                    + " --></body></html>";
        }

        private final boolean mWithViewPortTag;
        private boolean mExpectScaleChange;
        private int mOnScaleChangedCallCount;
        private int mDataSequence;
    }

    class AwSettingsForceZeroLayoutHeightTestHelper extends AwSettingsTestHelper<Boolean> {

        AwSettingsForceZeroLayoutHeightTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient,
                boolean withViewPortTag) throws Throwable {
            super(containerView, contentViewClient, true);
            mWithViewPortTag = withViewPortTag;
            mAwSettings.setUseWideViewPort(true);
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getForceZeroLayoutHeight();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setForceZeroLayoutHeight(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadDataSync(getData());
            int height = Integer.parseInt(getTitleOnUiThread());
            if (value) {
                Assert.assertEquals(0, height);
            } else {
                Assert.assertTrue("Div should be at least 50px high, was: " + height, height >= 50);
            }
        }

        private String getData() {
            return "<html><head>"
                    + (mWithViewPortTag ? "<meta name='viewport' content='height=3000' />" : "")
                    + "  <script type='text/javascript'> "
                    + "    window.addEventListener('load', function(event) { "
                    + "       document.title = document.getElementById('testDiv').clientHeight; "
                    + "    }); "
                    + "  </script> "
                    + "</head>"
                    + "<body> "
                    + "  <div style='height:50px;'>test</div> "
                    + "  <div id='testDiv' style='height:100%;'></div> "
                    + "</body></html>";
        }

        private final boolean mWithViewPortTag;
    }

    class AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper extends
            AwSettingsTestHelper<Boolean> {

        AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper(
                AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            mAwSettings.setUseWideViewPort(true);
            mAwSettings.setForceZeroLayoutHeight(true);
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getZeroLayoutHeightDisablesViewportQuirk();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setZeroLayoutHeightDisablesViewportQuirk(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            loadDataSync(getData());
            final int reportedClientWidth = Integer.parseInt(getTitleOnUiThread());
            if (value) {
                int displayWidth = calcDisplayWidthDp(mContext);
                Assert.assertEquals(displayWidth, reportedClientWidth);
            } else {
                Assert.assertEquals(3000, reportedClientWidth);
            }
        }

        private String getData() {
            return "<html><head>"
                    + "<meta name='viewport' content='width=3000, minimum-scale=1' />"
                    + "  <script type='text/javascript'> "
                    + "    window.addEventListener('load', function(event) { "
                    + "       document.title = document.documentElement.clientWidth; "
                    + "    }); "
                    + "  </script> "
                    + "</head>"
                    + "<body> "
                    + "  <div style='height:50px;'>test</div> "
                    + "  <div id='testDiv' style='height:100%;'></div> "
                    + "</body></html>";
        }
    }

    class AwSettingsWillSuppressErrorPageTestHelper extends AwSettingsTestHelper<Boolean> {
        private static final String BAD_SCHEME_URL = "htt://nonsense";
        private static final String PREV_TITLE = "cuencpobgjhfdmdovhmfdkjf";
        private static final int MAX_TIME_LOADING_ERROR_PAGE = 1000;
        private final AwContents mAwContents;

        AwSettingsWillSuppressErrorPageTestHelper(AwTestContainerView containerView,
                TestAwContentsClient contentViewClient) throws Throwable {
            super(containerView, contentViewClient, true);
            mAwContents = containerView.getAwContents();
        }

        @Override
        protected Boolean getAlteredValue() {
            return ENABLED;
        }

        @Override
        protected Boolean getInitialValue() {
            return DISABLED;
        }

        @Override
        protected Boolean getCurrentValue() {
            return mAwSettings.getWillSuppressErrorPage();
        }

        @Override
        protected void setCurrentValue(Boolean value) {
            mAwSettings.setWillSuppressErrorPage(value);
        }

        @Override
        protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
            // Load a known state
            loadDataSync(getData());

            final WebContents webContents = mAwContents.getWebContents();
            final CallbackHelper onTitleUpdatedHelper = new CallbackHelper();
            final WebContentsObserver observer =
                    ThreadUtils.runOnUiThreadBlocking(() -> new WebContentsObserver(webContents) {
                        @Override
                        public void titleWasSet(String title) {
                            onTitleUpdatedHelper.notifyCalled();
                        }
                    });
            int callCount = onTitleUpdatedHelper.getCallCount();

            loadUrlSync(BAD_SCHEME_URL);

            // Verify the state in settings reflect what we expect
            AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(mAwContents);
            Assert.assertEquals(value, settings.getWillSuppressErrorPage());

            // Verify the error page is shown / suppressed
            if (value == DISABLED) {
                // Showing an error page should change the page title.
                onTitleUpdatedHelper.waitForCallback(
                        "Showing an error page should change the page title, "
                                + "but no change happened",
                        callCount);
                Assert.assertNotEquals("Showing an error page should change the page title, "
                                + "but no change happened",
                        PREV_TITLE, getTitleOnUiThread());
            } else {
                // Suppressing the error page should mean nothing changes (no callbacks). However,
                // verifying that the error page actually never loads isn't straight-forward,
                // as it happens asynchronously.
                // In fact, there doesn't seem to be any direct, non-flaky way of detecting this.
                Thread.sleep(MAX_TIME_LOADING_ERROR_PAGE);
                Assert.assertEquals(
                        "Suppressing an error page should leave the page title unchanged, "
                                + "but a change still happened",
                        PREV_TITLE, getTitleOnUiThread());
            }

            ThreadUtils.runOnUiThreadBlocking(() -> webContents.removeObserver(observer));
        }

        private String getData() {
            return "<html><head><title>" + PREV_TITLE
                    + "</title></head><body>Page Text</body></html>";
        }
    }

    public static int calcDisplayWidthDp(Context context) {
        return ThreadUtils.runOnUiThreadBlockingNoException(() -> {
            DisplayAndroid displayAndroid = DisplayAndroid.getNonMultiDisplay(context);
            return DisplayUtil.pxToDp(displayAndroid, displayAndroid.getDisplayWidth());
        });
    }

    // The test verifies that JavaScript is disabled upon WebView
    // creation without accessing AwSettings. If the test passes,
    // it means that WebView-specific web preferences configuration
    // is applied on WebView creation. JS state is used, because it is
    // enabled by default in Chrome, but must be disabled by default
    // in WebView.
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testJavaScriptDisabledByDefault() throws Throwable {
        final String jsEnabledString = "JS has run";
        final String jsDisabledString = "JS has not run";
        final String testPageHtml =
                "<html><head><title>" + jsDisabledString + "</title>"
                + "</head><body onload=\"document.title='" + jsEnabledString
                + "';\"></body></html>";
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(),
                testPageHtml, "text/html", false);
        Assert.assertEquals(jsDisabledString, mActivityTestRule.getTitleOnUiThread(awContents));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testJavaScriptEnabledWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsJavaScriptTestHelper(views.getContainer0(), views.getClient0()),
                new AwSettingsJavaScriptTestHelper(views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testJavaScriptEnabledDynamicWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsJavaScriptDynamicTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsJavaScriptDynamicTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testStandardFontFamilyWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsStandardFontFamilyTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsStandardFontFamilyTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testDefaultFontSizeWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsDefaultFontSizeTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsDefaultFontSizeTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    // The test verifies that after changing the LoadsImagesAutomatically
    // setting value from false to true previously skipped images are
    // automatically loaded.
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testLoadsImagesAutomaticallyNoPageReload() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        settings.setJavaScriptEnabled(true);
        ImagePageGenerator generator = new ImagePageGenerator(0, false);
        settings.setLoadsImagesAutomatically(false);
        mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(),
                generator.getPageSource(), "text/html", false);
        Assert.assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
                mActivityTestRule.getTitleOnUiThread(awContents));
        settings.setLoadsImagesAutomatically(true);
        AwActivityTestRule.pollInstrumentationThread(
                () -> !ImagePageGenerator.IMAGE_NOT_LOADED_STRING.equals(
                        mActivityTestRule.getTitleOnUiThread(awContents)));
        Assert.assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING,
                mActivityTestRule.getTitleOnUiThread(awContents));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testLoadsImagesAutomaticallyWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsLoadImagesAutomaticallyTestHelper(
                    views.getContainer0(), views.getClient0(), new ImagePageGenerator(0, true)),
                new AwSettingsLoadImagesAutomaticallyTestHelper(
                    views.getContainer1(), views.getClient1(), new ImagePageGenerator(1, true)));
    }

    /*
     * @SmallTest
     * @Feature({"AndroidWebView", "Preferences"})
     */
    @Test
    @DisabledTest(message = "Disabled due to document.defaultCharset removal. crbug.com/587484")
    public void testDefaultTextEncodingWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsDefaultTextEncodingTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsDefaultTextEncodingTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    // The test verifies that the default user agent string follows the format
    // defined in Android CTS tests:
    //
    // Mozilla/5.0 (Linux;[ U;] Android <version>;[ <language>-<country>;]
    // [<devicemodel>;] Build/<buildID>; wv) AppleWebKit/<major>.<minor> (KHTML, like Gecko)
    // Version/<major>.<minor>[ Mobile] Safari/<major>.<minor>
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUserAgentStringDefault() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        final String actualUserAgentString = settings.getUserAgentString();
        Assert.assertEquals(actualUserAgentString, AwSettings.getDefaultUserAgent());
        final String patternString =
                "Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?"
                + "\\s?(.*)\\sBuild/(.+); wv\\) "
                + "AppleWebKit/(\\d+)\\.(\\d+) \\(KHTML, like Gecko\\) "
                + "Version/\\d+\\.\\d Chrome/\\d+\\.\\d+\\.\\d+\\.\\d+"
                + "( Mobile)? Safari/(\\d+)\\.(\\d+)";
        final Pattern userAgentExpr = Pattern.compile(patternString);
        Matcher patternMatcher = userAgentExpr.matcher(actualUserAgentString);
        Assert.assertTrue(
                String.format("User agent string did not match expected pattern. %nExpected "
                                + "pattern:%n%s%nActual:%n%s",
                        patternString, actualUserAgentString),
                patternMatcher.find());
        // No country-language code token.
        Assert.assertEquals(null, patternMatcher.group(3));
        if ("REL".equals(Build.VERSION.CODENAME)) {
            // Model is only added in release builds
            Assert.assertEquals(Build.MODEL, patternMatcher.group(6));
            // Release version is valid only in release builds
            Assert.assertEquals(Build.VERSION.RELEASE, patternMatcher.group(2));
        }
        Assert.assertEquals(Build.ID, patternMatcher.group(7));
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testWillSuppressErrorPage() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(new AwSettingsWillSuppressErrorPageTestHelper(
                                       views.getContainer0(), views.getClient0()),
                new AwSettingsWillSuppressErrorPageTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUserAgentStringOverride() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        final String defaultUserAgentString = settings.getUserAgentString();

        // Check that an attempt to reset the default UA string has no effect.
        settings.setUserAgentString(null);
        Assert.assertEquals(defaultUserAgentString, settings.getUserAgentString());
        settings.setUserAgentString("");
        Assert.assertEquals(defaultUserAgentString, settings.getUserAgentString());

        // Check that we can also set the default value.
        settings.setUserAgentString(defaultUserAgentString);
        Assert.assertEquals(defaultUserAgentString, settings.getUserAgentString());

        // Set a custom UA string, verify that it can be reset back to default.
        final String customUserAgentString = "AwSettingsTest";
        settings.setUserAgentString(customUserAgentString);
        Assert.assertEquals(customUserAgentString, settings.getUserAgentString());
        settings.setUserAgentString(null);
        Assert.assertEquals(defaultUserAgentString, settings.getUserAgentString());
    }

    // Verify that the current UA override setting has a priority over UA
    // overrides in navigation history entries.
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUserAgentStringOverrideForHistory() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final WebContents webContents = awContents.getWebContents();
        CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
        AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        settings.setJavaScriptEnabled(true);
        final String defaultUserAgentString = settings.getUserAgentString();
        final String customUserAgentString = "AwSettingsTest";
        // We are using different page titles to make sure that we are really
        // going back and forward between them.
        final String pageTemplate =
                "<html><head><title>%s</title></head>"
                + "<body onload='document.title+=navigator.userAgent'></body>"
                + "</html>";
        final String page1Title = "Page1";
        final String page2Title = "Page2";
        final String page1 = String.format(pageTemplate, page1Title);
        final String page2 = String.format(pageTemplate, page2Title);
        settings.setUserAgentString(customUserAgentString);
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page1, "text/html", false);
        Assert.assertEquals(page1Title + customUserAgentString,
                mActivityTestRule.getTitleOnUiThread(awContents));
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page2, "text/html", false);
        Assert.assertEquals(page2Title + customUserAgentString,
                mActivityTestRule.getTitleOnUiThread(awContents));
        settings.setUserAgentString(null);
        // Must not cause any changes until the next page loading.
        Assert.assertEquals(page2Title + customUserAgentString,
                mActivityTestRule.getTitleOnUiThread(awContents));
        HistoryUtils.goBackSync(
                InstrumentationRegistry.getInstrumentation(), webContents, onPageFinishedHelper);
        Assert.assertEquals(page1Title + defaultUserAgentString,
                mActivityTestRule.getTitleOnUiThread(awContents));
        HistoryUtils.goForwardSync(
                InstrumentationRegistry.getInstrumentation(), webContents, onPageFinishedHelper);
        Assert.assertEquals(page2Title + defaultUserAgentString,
                mActivityTestRule.getTitleOnUiThread(awContents));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUserAgentStringWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsUserAgentStringTestHelper(views.getContainer0(), views.getClient0()),
                new AwSettingsUserAgentStringTestHelper(views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUserAgentWithTestServer() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final String customUserAgentString =
                "testUserAgentWithTestServerUserAgent";
        AwContents awContents = testContainerView.getAwContents();
        AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(
                InstrumentationRegistry.getInstrumentation().getContext());

        AwActivityTestRule.enableJavaScriptOnUiThread(awContents);

        try {
            // Create url with echoheader echoing the User-Agent header in the the html body.
            String url = testServer.getURL("/echoheader?User-Agent");
            settings.setUserAgentString(customUserAgentString);
            mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
            String userAgent =
                    mActivityTestRule.getJavaScriptResultBodyTextContent(awContents, contentClient);
            Assert.assertEquals(customUserAgentString, userAgent);
        } finally {
            testServer.stopAndDestroyServer();
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testDomStorageEnabledWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsDomStorageEnabledTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsDomStorageEnabledTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    // Ideally, these three tests below should be combined into one, or tested using
    // runPerViewSettingsTest. However, it seems the database setting cannot be toggled
    // once set. Filed b/8186497.
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testDatabaseInitialValue() throws Throwable {
        TestAwContentsClient client = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(client);
        AwSettingsDatabaseTestHelper helper =
                new AwSettingsDatabaseTestHelper(testContainerView, client);
        helper.ensureSettingHasInitialValue();
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testDatabaseEnabled() throws Throwable {
        TestAwContentsClient client = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(client);
        AwSettingsDatabaseTestHelper helper =
                new AwSettingsDatabaseTestHelper(testContainerView, client);
        helper.setAlteredSettingValue();
        helper.ensureSettingHasAlteredValue();
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testDatabaseDisabled() throws Throwable {
        TestAwContentsClient client = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(client);
        AwSettingsDatabaseTestHelper helper =
                new AwSettingsDatabaseTestHelper(testContainerView, client);
        helper.setInitialSettingValue();
        helper.ensureSettingHasInitialValue();
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUniversalAccessFromFilesWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsUniversalAccessFromFilesTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsUniversalAccessFromFilesTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    // This test verifies that local image resources can be loaded from file:
    // URLs regardless of file access state.
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testFileAccessFromFilesImage() throws Throwable {
        final String testFile = "android_webview/test/data/image_access.html";
        assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(testFile));
        final String imageContainerUrl = UrlUtils.getIsolatedTestFileUrl(testFile);
        final String imageHeight = "16";
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        settings.setJavaScriptEnabled(true);
        settings.setAllowUniversalAccessFromFileURLs(false);
        settings.setAllowFileAccessFromFileURLs(false);
        mActivityTestRule.loadUrlSync(
                awContents, contentClient.getOnPageFinishedHelper(), imageContainerUrl);
        Assert.assertEquals(imageHeight, mActivityTestRule.getTitleOnUiThread(awContents));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testFileAccessFromFilesIframeWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsFileAccessFromFilesIframeTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsFileAccessFromFilesIframeTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testFileAccessFromFilesXhrWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsFileAccessFromFilesXhrTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsFileAccessFromFilesXhrTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    @RetryOnFailure
    public void testFileUrlAccessWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsFileUrlAccessTestHelper(
                        views.getContainer0(), views.getClient0(), 0),
                new AwSettingsFileUrlAccessTestHelper(
                        views.getContainer1(), views.getClient1(), 1));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testContentUrlAccessWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsContentUrlAccessTestHelper(
                        views.getContainer0(), views.getClient0(), 0),
                new AwSettingsContentUrlAccessTestHelper(
                        views.getContainer1(), views.getClient1(), 1));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences", "Navigation"})
    public void testBlockingContentUrlsFromDataUrls() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final String target = "content_from_data";
        final String page = "<html><body>"
                + "<img src=\""
                + createContentUrl(target) + "\">"
                + "</body></html>";
        resetResourceRequestCountInContentProvider(target);
        mActivityTestRule.loadDataSync(
                awContents, contentClient.getOnPageFinishedHelper(), page, "text/html", false);
        ensureResourceRequestCountInContentProvider(target, 0);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences", "Navigation"})
    public void testContentUrlFromFileWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsContentUrlAccessFromFileTestHelper(
                        views.getContainer0(), views.getClient0(), 0),
                new AwSettingsContentUrlAccessFromFileTestHelper(
                        views.getContainer1(), views.getClient1(), 1));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testBlockNetworkImagesDoesNotBlockDataUrlImage() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        ImagePageGenerator generator = new ImagePageGenerator(0, false);

        settings.setJavaScriptEnabled(true);
        settings.setImagesEnabled(false);
        mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(),
                generator.getPageSource(), "text/html", false);
        Assert.assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING,
                mActivityTestRule.getTitleOnUiThread(awContents));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testBlockNetworkImagesBlocksNetworkImageAndReloadInPlace() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        settings.setJavaScriptEnabled(true);
        ImagePageGenerator generator = new ImagePageGenerator(0, false);

        TestWebServer webServer = TestWebServer.start();
        try {
            final String httpImageUrl = generator.getPageUrl(webServer);

            settings.setImagesEnabled(false);
            mActivityTestRule.loadUrlSync(
                    awContents, contentClient.getOnPageFinishedHelper(), httpImageUrl);
            Assert.assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
                    mActivityTestRule.getTitleOnUiThread(awContents));

            settings.setImagesEnabled(true);
            AwActivityTestRule.pollInstrumentationThread(
                    () -> ImagePageGenerator.IMAGE_LOADED_STRING.equals(
                            mActivityTestRule.getTitleOnUiThread(awContents)));
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testBlockNetworkImagesWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        TestWebServer webServer = TestWebServer.start();
        try {
            runPerViewSettingsTest(
                    new AwSettingsImagesEnabledHelper(
                            views.getContainer0(),
                            views.getClient0(),
                            webServer,
                            new ImagePageGenerator(0, true)),
                    new AwSettingsImagesEnabledHelper(
                            views.getContainer1(),
                            views.getClient1(),
                            webServer,
                            new ImagePageGenerator(1, true)));
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testBlockNetworkLoadsWithHttpResources() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainer =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainer.getAwContents();
        final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        awSettings.setJavaScriptEnabled(true);
        ImagePageGenerator generator = new ImagePageGenerator(0, false);

        String fileName = null;
        TestWebServer webServer = TestWebServer.start();
        try {
            // Set up http image.
            final String httpPath = "/image.png";
            final String imageUrl = webServer.setResponseBase64(
                    httpPath, generator.getImageSourceNoAdvance(),
                    CommonResources.getImagePngHeaders(true));

            // Set up file html that loads http iframe.
            String pageHtml = "<img src='" + imageUrl + "' "
                      + "onload=\"document.title='img_onload_fired';\" "
                      + "onerror=\"document.title='img_onerror_fired';\" />";
            Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
            fileName = context.getCacheDir() + "/block_network_loads_test.html";
            TestFileUtil.deleteFile(fileName);  // Remove leftover file if any.
            TestFileUtil.createNewHtmlFile(fileName, "unset", pageHtml);

            // Actual test. Blocking should trigger onerror handler.
            awSettings.setBlockNetworkLoads(true);
            mActivityTestRule.loadUrlSync(
                    awContents, contentClient.getOnPageFinishedHelper(), "file:///" + fileName);
            Assert.assertEquals(0, webServer.getRequestCount(httpPath));
            Assert.assertEquals(
                    "img_onerror_fired", mActivityTestRule.getTitleOnUiThread(awContents));

            // Unblock should load normally.
            awSettings.setBlockNetworkLoads(false);
            mActivityTestRule.loadUrlSync(
                    awContents, contentClient.getOnPageFinishedHelper(), "file:///" + fileName);
            Assert.assertEquals(1, webServer.getRequestCount(httpPath));
            Assert.assertEquals(
                    "img_onload_fired", mActivityTestRule.getTitleOnUiThread(awContents));
        } finally {
            webServer.shutdown();
            if (fileName != null) TestFileUtil.deleteFile(fileName);
        }
    }

    private static class AudioEvent {
        private CallbackHelper mCallback;
        public AudioEvent(CallbackHelper callback) {
            mCallback = callback;
        }

        @JavascriptInterface
        public void onCanPlay() {
            mCallback.notifyCalled();
        }

        @JavascriptInterface
        public void onError() {
            mCallback.notifyCalled();
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testBlockNetworkLoadsWithAudio() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainer =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainer.getAwContents();
        final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        final CallbackHelper callback = new CallbackHelper();
        awSettings.setJavaScriptEnabled(true);

        TestWebServer webServer = TestWebServer.start();
        try {
            final String httpPath = "/audio.mp3";
            // Don't care about the response is correct or not, just want
            // to know whether Url is accessed.
            final String audioUrl = webServer.setResponse(httpPath, "1", null);

            String pageHtml = "<html><body><audio id=\"audio\" controls src='" + audioUrl + "' "
                    + "oncanplay=\"AudioEvent.onCanPlay();\" "
                    + "onerror=\"AudioEvent.onError();\"></audio>"
                    + "<button id=\"play\""
                    + "onclick=\"document.getElementById('audio').play();\"></button>"
                    + "</body></html>";
            // Actual test. Blocking should trigger onerror handler.
            awSettings.setBlockNetworkLoads(true);
            InstrumentationRegistry.getInstrumentation().runOnMainSync(
                    () -> awContents.addJavascriptInterface(new AudioEvent(callback),
                            "AudioEvent"));
            int count = callback.getCallCount();
            mActivityTestRule.loadDataSync(awContents, contentClient.getOnPageFinishedHelper(),
                    pageHtml, "text/html", false);
            DOMUtils.clickNode(testContainer.getWebContents(), "play");
            callback.waitForCallback(count, 1);
            Assert.assertEquals(0, webServer.getRequestCount(httpPath));

            // The below test failed in Nexus Galaxy.
            // See https://code.google.com/p/chromium/issues/detail?id=313463
            // Unblock should load normally.
            /*
            awSettings.setBlockNetworkLoads(false);
            count = callback.getCallCount();
            loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml,
                    "text/html", false);
            callback.waitForCallback(count, 1);
            assertTrue(0 != webServer.getRequestCount(httpPath));
            */
        } finally {
            webServer.shutdown();
        }
    }

    // Test an assert URL (file:///android_asset/)
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Navigation"})
    public void testAssetUrl() throws Throwable {
        // Note: this text needs to be kept in sync with the contents of the html file referenced
        // below.
        final String expectedTitle = "Asset File";
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(),
                "file:///android_asset/asset_file.html");
        Assert.assertEquals(expectedTitle, mActivityTestRule.getTitleOnUiThread(awContents));
    }

    // Test a resource URL (file:///android_res/).
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Navigation"})
    public void testResourceUrl() throws Throwable {
        // Note: this text needs to be kept in sync with the contents of the html file referenced
        // below.
        final String expectedTitle = "Resource File";
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(),
                "file:///android_res/raw/resource_file.html");
        Assert.assertEquals(expectedTitle, mActivityTestRule.getTitleOnUiThread(awContents));
    }

    // Test that the file URL access toggle does not affect asset URLs.
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Navigation"})
    public void testFileUrlAccessToggleDoesNotBlockAssetUrls() throws Throwable {
        // Note: this text needs to be kept in sync with the contents of the html file referenced
        // below.
        final String expectedTitle = "Asset File";
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        settings.setAllowFileAccess(false);
        mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(),
                "file:///android_asset/asset_file.html");
        Assert.assertEquals(expectedTitle, mActivityTestRule.getTitleOnUiThread(awContents));
    }

    // Test that the file URL access toggle does not affect resource URLs.
    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Navigation"})
    public void testFileUrlAccessToggleDoesNotBlockResourceUrls() throws Throwable {
        // Note: this text needs to be kept in sync with the contents of the html file referenced
        // below.
        final String expectedTitle = "Resource File";
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        settings.setAllowFileAccess(false);
        mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(),
                "file:///android_res/raw/resource_file.html");
        Assert.assertEquals(expectedTitle, mActivityTestRule.getTitleOnUiThread(awContents));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testLayoutAlgorithmWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsLayoutAlgorithmTestHelper(views.getContainer0(), views.getClient0()),
                new AwSettingsLayoutAlgorithmTestHelper(views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testTextZoomWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsTextZoomTestHelper(views.getContainer0(), views.getClient0()),
                new AwSettingsTextZoomTestHelper(views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testTextZoomAutosizingWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsTextZoomAutosizingTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsTextZoomAutosizingTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testJavaScriptPopupsWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(new AwSettingsJavaScriptPopupsTestHelper(
                                       views.getContainer0(), views.getClient0(), false),
                new AwSettingsJavaScriptPopupsTestHelper(
                        views.getContainer1(), views.getClient1(), false));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testJavaScriptPopupsAndMultiWindowsWithTwoViews() throws Throwable {
        final ViewPair views = createViews();
        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
            AwSettings awSettings = views.getContents0().getSettings();
            awSettings.setSupportMultipleWindows(true);
            awSettings = views.getContents1().getSettings();
            awSettings.setSupportMultipleWindows(true);
        });
        views.getClient0().getOnCreateWindowHelper().setReturnValue(true);
        views.getClient1().getOnCreateWindowHelper().setReturnValue(true);
        runPerViewSettingsTest(new AwSettingsJavaScriptPopupsTestHelper(
                                       views.getContainer0(), views.getClient0(), false),
                new AwSettingsJavaScriptPopupsTestHelper(
                        views.getContainer1(), views.getClient1(), false));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testJavaScriptPopupsOpenTwice() throws Throwable {
        final ViewPair views = createViews();
        runPerViewSettingsTest(new AwSettingsJavaScriptPopupsTestHelper(
                                       views.getContainer0(), views.getClient0(), true),
                new AwSettingsJavaScriptPopupsTestHelper(
                        views.getContainer1(), views.getClient1(), true));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testCacheMode() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainer =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainer.getAwContents();
        final AwSettings awSettings =
                mActivityTestRule.getAwSettingsOnUiThread(testContainer.getAwContents());
        mActivityTestRule.clearCacheOnUiThread(awContents, true);

        Assert.assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode());
        TestWebServer webServer = TestWebServer.start();
        try {
            final String htmlPath = "/testCacheMode.html";
            final String url = webServer.setResponse(htmlPath, "response", null);
            awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
            mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
            Assert.assertEquals(1, webServer.getRequestCount(htmlPath));
            mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
            Assert.assertEquals(1, webServer.getRequestCount(htmlPath));

            awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
            mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
            Assert.assertEquals(2, webServer.getRequestCount(htmlPath));
            mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
            Assert.assertEquals(3, webServer.getRequestCount(htmlPath));

            awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
            mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
            Assert.assertEquals(3, webServer.getRequestCount(htmlPath));
            mActivityTestRule.loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
            Assert.assertEquals(3, webServer.getRequestCount(htmlPath));

            final String htmlNotInCachePath = "/testCacheMode-not-in-cache.html";
            final String urlNotInCache = webServer.setResponse(htmlNotInCachePath, "", null);
            mActivityTestRule.loadUrlSyncAndExpectError(awContents,
                    contentClient.getOnPageFinishedHelper(),
                    contentClient.getOnReceivedErrorHelper(), urlNotInCache);
            Assert.assertEquals(0, webServer.getRequestCount(htmlNotInCachePath));
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    // As our implementation of network loads blocking uses the same net::URLRequest settings, make
    // sure that setting cache mode doesn't accidentally enable network loads.  The reference
    // behaviour is that when network loads are blocked, setting cache mode has no effect.
    public void testCacheModeWithBlockedNetworkLoads() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainer =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainer.getAwContents();
        final AwSettings awSettings =
                mActivityTestRule.getAwSettingsOnUiThread(testContainer.getAwContents());
        mActivityTestRule.clearCacheOnUiThread(awContents, true);

        Assert.assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode());
        awSettings.setBlockNetworkLoads(true);
        TestWebServer webServer = TestWebServer.start();
        try {
            final String htmlPath = "/testCacheModeWithBlockedNetworkLoads.html";
            final String url = webServer.setResponse(htmlPath, "response", null);
            mActivityTestRule.loadUrlSyncAndExpectError(awContents,
                    contentClient.getOnPageFinishedHelper(),
                    contentClient.getOnReceivedErrorHelper(), url);
            Assert.assertEquals(0, webServer.getRequestCount(htmlPath));

            awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
            mActivityTestRule.loadUrlSyncAndExpectError(awContents,
                    contentClient.getOnPageFinishedHelper(),
                    contentClient.getOnReceivedErrorHelper(), url);
            Assert.assertEquals(0, webServer.getRequestCount(htmlPath));

            awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
            mActivityTestRule.loadUrlSyncAndExpectError(awContents,
                    contentClient.getOnPageFinishedHelper(),
                    contentClient.getOnReceivedErrorHelper(), url);
            Assert.assertEquals(0, webServer.getRequestCount(htmlPath));

            awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
            mActivityTestRule.loadUrlSyncAndExpectError(awContents,
                    contentClient.getOnPageFinishedHelper(),
                    contentClient.getOnReceivedErrorHelper(), url);
            Assert.assertEquals(0, webServer.getRequestCount(htmlPath));
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    @DisabledTest(message = "crbug.com/860556")
    public void testCacheModeWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        TestWebServer webServer = TestWebServer.start();
        try {
            runPerViewSettingsTest(
                    new AwSettingsCacheModeTestHelper(
                            views.getContainer0(), views.getClient0(), 0, webServer),
                    new AwSettingsCacheModeTestHelper(
                            views.getContainer1(), views.getClient1(), 1, webServer));
        } finally {
            webServer.shutdown();
        }
    }

    static class ManifestTestHelper {
        private final TestWebServer mWebServer;
        private final String mHtmlPath;
        private final String mHtmlUrl;
        private final String mManifestPath;

        ManifestTestHelper(
                TestWebServer webServer, String htmlPageName, String manifestName) {
            mWebServer = webServer;
            mHtmlPath = "/" + htmlPageName;
            mHtmlUrl = webServer.setResponse(
                    mHtmlPath, "<html manifest=\"" + manifestName + "\"></html>", null);
            mManifestPath = "/" + manifestName;
            webServer.setResponse(
                    mManifestPath,
                    "CACHE MANIFEST",
                    CommonResources.getContentTypeAndCacheHeaders("text/cache-manifest", false));
        }

        String getHtmlPath() {
            return mHtmlPath;
        }

        String getHtmlUrl() {
            return mHtmlUrl;
        }

        String getManifestPath() {
            return mManifestPath;
        }

        int waitUntilHtmlIsRequested(final int initialRequestCount) throws Exception {
            return waitUntilResourceIsRequested(mHtmlPath, initialRequestCount);
        }

        int waitUntilManifestIsRequested(final int initialRequestCount) throws Exception {
            return waitUntilResourceIsRequested(mManifestPath, initialRequestCount);
        }

        private int waitUntilResourceIsRequested(
                final String path, final int initialRequestCount) throws Exception {
            AwActivityTestRule.pollInstrumentationThread(
                    () -> mWebServer.getRequestCount(path) > initialRequestCount);
            return mWebServer.getRequestCount(path);
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences", "AppCache"})
    public void testAppCache() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainer =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainer.getAwContents();
        final AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        settings.setJavaScriptEnabled(true);
        // Note that the cache isn't actually enabled until the call to setAppCachePath.
        settings.setAppCacheEnabled(true);

        TestWebServer webServer = TestWebServer.start();
        try {
            ManifestTestHelper helper = new ManifestTestHelper(
                    webServer, "testAppCache.html", "appcache.manifest");
            mActivityTestRule.loadUrlSync(
                    awContents, contentClient.getOnPageFinishedHelper(), helper.getHtmlUrl());
            helper.waitUntilHtmlIsRequested(0);
            // Unfortunately, there is no other good way of verifying that AppCache is
            // disabled, other than checking that it didn't try to fetch the manifest.
            Thread.sleep(1000);
            Assert.assertEquals(0, webServer.getRequestCount(helper.getManifestPath()));
            settings.setAppCachePath("whatever");  // Enables AppCache.
            mActivityTestRule.loadUrlSync(
                    awContents, contentClient.getOnPageFinishedHelper(), helper.getHtmlUrl());
            helper.waitUntilManifestIsRequested(0);
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences", "AppCache"})
    @RetryOnFailure
    public void testAppCacheWithTwoViews() throws Throwable {
        // We don't use the test helper here, because making sure that AppCache
        // is disabled takes a lot of time, so running through the usual drill
        // will take about 20 seconds.
        ViewPair views = createViews();

        AwSettings settings0 = mActivityTestRule.getAwSettingsOnUiThread(views.getContents0());
        settings0.setJavaScriptEnabled(true);
        settings0.setAppCachePath("whatever");
        settings0.setAppCacheEnabled(true);
        AwSettings settings1 = mActivityTestRule.getAwSettingsOnUiThread(views.getContents1());
        settings1.setJavaScriptEnabled(true);
        // AppCachePath setting is global, no need to set it for the second view.
        settings1.setAppCacheEnabled(true);

        TestWebServer webServer = TestWebServer.start();
        try {
            ManifestTestHelper helper0 = new ManifestTestHelper(
                    webServer, "testAppCache_0.html", "appcache.manifest_0");
            mActivityTestRule.loadUrlSync(views.getContents0(),
                    views.getClient0().getOnPageFinishedHelper(), helper0.getHtmlUrl());
            int manifestRequests0 = helper0.waitUntilManifestIsRequested(0);
            ManifestTestHelper helper1 = new ManifestTestHelper(
                    webServer, "testAppCache_1.html", "appcache.manifest_1");
            mActivityTestRule.loadUrlSync(views.getContents1(),
                    views.getClient1().getOnPageFinishedHelper(), helper1.getHtmlUrl());
            helper1.waitUntilManifestIsRequested(0);
            settings1.setAppCacheEnabled(false);
            mActivityTestRule.loadUrlSync(views.getContents0(),
                    views.getClient0().getOnPageFinishedHelper(), helper0.getHtmlUrl());
            helper0.waitUntilManifestIsRequested(manifestRequests0);
            final int prevManifestRequestCount =
                    webServer.getRequestCount(helper1.getManifestPath());
            int htmlRequests1 = webServer.getRequestCount(helper1.getHtmlPath());
            mActivityTestRule.loadUrlSync(views.getContents1(),
                    views.getClient1().getOnPageFinishedHelper(), helper1.getHtmlUrl());
            helper1.waitUntilHtmlIsRequested(htmlRequests1);
            // Unfortunately, there is no other good way of verifying that AppCache is
            // disabled, other than checking that it didn't try to fetch the manifest.
            Thread.sleep(1000);
            Assert.assertEquals(
                    prevManifestRequestCount, webServer.getRequestCount(helper1.getManifestPath()));
        } finally {
            webServer.shutdown();
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUseWideViewportWithTwoViews() throws Throwable {
        ViewPair views = createViews(true);
        runPerViewSettingsTest(
                new AwSettingsUseWideViewportTestHelper(views.getContainer0(), views.getClient0()),
                new AwSettingsUseWideViewportTestHelper(views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUseWideViewportWithTwoViewsNoQuirks() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsUseWideViewportTestHelper(views.getContainer0(), views.getClient0()),
                new AwSettingsUseWideViewportTestHelper(views.getContainer1(), views.getClient1()));
    }

    private void useWideViewportLayoutWidthTest(
            AwTestContainerView testContainer, CallbackHelper onPageFinishedHelper)
            throws Throwable {
        final AwContents awContents = testContainer.getAwContents();
        AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);

        final String pageTemplate = "<html><head>%s</head>"
                + "<body onload='document.title=document.body.clientWidth'></body></html>";
        final String pageNoViewport = String.format(pageTemplate, "");
        final String pageViewportDeviceWidth = String.format(
                pageTemplate,
                "<meta name='viewport' content='width=device-width' />");
        final String viewportTagSpecifiedWidth = "3000";
        final String pageViewportSpecifiedWidth = String.format(
                pageTemplate,
                "<meta name='viewport' content='width=" + viewportTagSpecifiedWidth + "' />");

        int displayWidth = calcDisplayWidthDp(testContainer.getContext());

        settings.setJavaScriptEnabled(true);
        Assert.assertFalse(settings.getUseWideViewPort());
        // When UseWideViewPort is off, "width" setting of "meta viewport"
        // tags is ignored, and the layout width is set to device width in CSS pixels.
        // Thus, all 3 pages will have the same body width.
        mActivityTestRule.loadDataSync(
                awContents, onPageFinishedHelper, pageNoViewport, "text/html", false);
        int actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents));
        // Avoid rounding errors.
        Assert.assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
                Math.abs(displayWidth - actualWidth) <= 1);
        mActivityTestRule.loadDataSync(
                awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false);
        actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents));
        Assert.assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
                Math.abs(displayWidth - actualWidth) <= 1);
        mActivityTestRule.loadDataSync(
                awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false);
        actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents));
        Assert.assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
                Math.abs(displayWidth - actualWidth) <= 1);

        settings.setUseWideViewPort(true);
        // When UseWideViewPort is on, "meta viewport" tag is used.
        // If there is no viewport tag, or width isn't specified,
        // then layout width is set to max(980, <device-width-in-DIP-pixels>)
        mActivityTestRule.loadDataSync(
                awContents, onPageFinishedHelper, pageNoViewport, "text/html", false);
        actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents));
        Assert.assertTrue("Expected: >= 980 , Actual: " + actualWidth, actualWidth >= 980);
        mActivityTestRule.loadDataSync(
                awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false);
        actualWidth = Integer.parseInt(mActivityTestRule.getTitleOnUiThread(awContents));
        Assert.assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
                Math.abs(displayWidth - actualWidth) <= 1);
        mActivityTestRule.loadDataSync(
                awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false);
        Assert.assertEquals(
                viewportTagSpecifiedWidth, mActivityTestRule.getTitleOnUiThread(awContents));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUseWideViewportLayoutWidth() throws Throwable {
        TestAwContentsClient contentClient = new TestAwContentsClient();
        AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient, true);
        useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper());
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUseWideViewportLayoutWidthNoQuirks() throws Throwable {
        TestAwContentsClient contentClient = new TestAwContentsClient();
        AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper());
    }

    @Test
    @MediumTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUseWideViewportControlsDoubleTabToZoom() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
        AwSettings settings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        settings.setBuiltInZoomControls(true);

        int displayWidth = calcDisplayWidthDp(testContainerView.getContext());
        int layoutWidth = displayWidth * 2;
        final String page = "<html>"
                + "<head><meta name='viewport' content='width=" + layoutWidth + "'>"
                + "<style> body { width: " + layoutWidth + "px; }</style></head>"
                + "<body>Page Text</body></html>";

        Assert.assertFalse(settings.getUseWideViewPort());
        // Without wide viewport the <meta viewport> tag will be ignored by WebView,
        // but it doesn't really matter as we don't expect double tap to change the scale.
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
        final float initialScale = mActivityTestRule.getScaleOnUiThread(awContents);
        simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView);
        Thread.sleep(1000);
        Assert.assertEquals(initialScale, mActivityTestRule.getScaleOnUiThread(awContents), 0);

        settings.setUseWideViewPort(true);
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
        int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
        simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView);
        contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
        final float zoomedOutScale = mActivityTestRule.getScaleOnUiThread(awContents);
        Assert.assertTrue("zoomedOut: " + zoomedOutScale + ", initial: " + initialScale,
                zoomedOutScale < initialScale);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testForceZeroLayoutHeightWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsForceZeroLayoutHeightTestHelper(
                        views.getContainer0(), views.getClient0(), false),
                new AwSettingsForceZeroLayoutHeightTestHelper(
                        views.getContainer1(), views.getClient1(), false));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    @RetryOnFailure
    public void testForceZeroLayoutHeightViewportTagWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsForceZeroLayoutHeightTestHelper(
                        views.getContainer0(), views.getClient0(), true),
                new AwSettingsForceZeroLayoutHeightTestHelper(
                        views.getContainer1(), views.getClient1(), true));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    @DisabledTest(message = "crbug.com/746264")
    public void testZeroLayoutHeightDisablesViewportQuirkWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper(
                        views.getContainer0(), views.getClient0()),
                new AwSettingsZeroLayoutHeightDisablesViewportQuirkTestHelper(
                        views.getContainer1(), views.getClient1()));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testLoadWithOverviewModeWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsLoadWithOverviewModeTestHelper(
                        views.getContainer0(), views.getClient0(), false),
                new AwSettingsLoadWithOverviewModeTestHelper(
                        views.getContainer1(), views.getClient1(), false));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testLoadWithOverviewModeViewportTagWithTwoViews() throws Throwable {
        ViewPair views = createViews();
        runPerViewSettingsTest(
                new AwSettingsLoadWithOverviewModeTestHelper(
                        views.getContainer0(), views.getClient0(), true),
                new AwSettingsLoadWithOverviewModeTestHelper(
                        views.getContainer1(), views.getClient1(), true));
    }

    /*
     * @SmallTest
     * @Feature({"AndroidWebView", "Preferences"})
     */
    @Test
    @DisabledTest(message = "crbug.com/644894")
    public void testSetInitialScale() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents);
        CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();

        WindowManager wm = (WindowManager) InstrumentationRegistry.getInstrumentation()
                                   .getTargetContext()
                                   .getSystemService(Context.WINDOW_SERVICE);
        Point screenSize = new Point();
        wm.getDefaultDisplay().getSize(screenSize);
        // Make sure after 50% scale, page width still larger than screen.
        int height = screenSize.y * 2 + 1;
        int width = screenSize.x * 2 + 1;
        final String page = "<html><body>"
                + "<p style='height:" + height + "px;width:" + width + "px'>"
                + "testSetInitialScale</p></body></html>";
        final float defaultScale = InstrumentationRegistry.getInstrumentation()
                                           .getTargetContext()
                                           .getResources()
                                           .getDisplayMetrics()
                                           .density;

        Assert.assertEquals(
                defaultScale, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f);
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
        Assert.assertEquals(
                defaultScale, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f);

        int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
        awSettings.setInitialPageScale(50);
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
        contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
        Assert.assertEquals(0.5f, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f);

        onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
        awSettings.setInitialPageScale(500);
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
        contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
        Assert.assertEquals(5.0f, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f);

        onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
        awSettings.setInitialPageScale(0);
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
        contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
        Assert.assertEquals(
                defaultScale, mActivityTestRule.getPixelScaleOnUiThread(awContents), .01f);
    }

    @Test
    @DisableHardwareAccelerationForTest
    @LargeTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testMediaPlaybackWithoutUserGesture() throws Throwable {
        Assert.assertTrue(VideoTestUtil.runVideoTest(InstrumentationRegistry.getInstrumentation(),
                mActivityTestRule, false, WAIT_TIMEOUT_MS));
    }

    @Test
    @DisableHardwareAccelerationForTest
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testMediaPlaybackWithUserGesture() throws Throwable {
        // Wait for 5 second to see if video played.
        Assert.assertFalse(VideoTestUtil.runVideoTest(InstrumentationRegistry.getInstrumentation(),
                mActivityTestRule, true, scaleTimeout(5000)));
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testDefaultVideoPosterURL() throws Throwable {
        final CallbackHelper videoPosterAccessedCallbackHelper = new CallbackHelper();
        final String defaultVideoPosterUrl = "http://default_video_poster/";
        TestAwContentsClient client = new TestAwContentsClient() {
            @Override
            public AwWebResourceResponse shouldInterceptRequest(AwWebResourceRequest request) {
                if (request.url.equals(defaultVideoPosterUrl)) {
                    videoPosterAccessedCallbackHelper.notifyCalled();
                }
                return null;
            }
        };
        final AwContents awContents =
                mActivityTestRule.createAwTestContainerViewOnMainSync(client).getAwContents();
        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
            AwSettings awSettings = awContents.getSettings();
            awSettings.setDefaultVideoPosterURL(defaultVideoPosterUrl);
        });
        VideoTestWebServer webServer = new VideoTestWebServer();
        try {
            String data = "<html><head><body>"
                    + "<video id='video' control src='"
                    + webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
            mActivityTestRule.loadDataAsync(awContents, data, "text/html", false);
            videoPosterAccessedCallbackHelper.waitForCallback(0, 1, 20, TimeUnit.SECONDS);
        } finally {
            if (webServer.getTestWebServer() != null) {
                webServer.getTestWebServer().shutdown();
            }
        }
    }

    private void testScrollTopLeftInteropState(boolean state) throws Throwable {
        final TestAwContentsClient client = new TestAwContentsClient();
        final AwTestContainerView view =
                mActivityTestRule.createAwTestContainerViewOnMainSync(client);
        final AwContents awContents = view.getAwContents();
        CallbackHelper onPageFinishedHelper = client.getOnPageFinishedHelper();
        InstrumentationRegistry.getInstrumentation().runOnMainSync(
                () -> awContents.getSettings().setScrollTopLeftInteropEnabled(state));
        AwActivityTestRule.enableJavaScriptOnUiThread(awContents);
        final String page = "<!doctype html>"
                + "<script>"
                + "window.onload = function() {"
                + "  document.title = document.scrollingElement === document.documentElement;"
                + "};"
                + "</script>";
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
        String actualTitle = mActivityTestRule.getTitleOnUiThread(awContents);
        Assert.assertEquals(state ? "true" : "false", actualTitle);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testScrollTopLeftInteropEnabled() throws Throwable {
        testScrollTopLeftInteropState(true);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testScrollTopLeftInteropDisabled() throws Throwable {
        testScrollTopLeftInteropState(false);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testAllowMixedMode() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient() {
            @Override
            public void onReceivedSslError(Callback<Boolean> callback, SslError error) {
                callback.onResult(true);
            }
        };
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents);

        awSettings.setJavaScriptEnabled(true);

        TestWebServer httpsServer = null;
        TestWebServer httpServer = null;
        try {
            httpsServer = TestWebServer.startSsl();
            httpServer = TestWebServer.start();
            httpServer.setServerHost("example.com");

            final String jsUrl = "/insecure.js";
            final String imageUrl = "/insecure.png";
            final String secureUrl = "/secure.html";
            httpServer.setResponse(jsUrl, "window.loaded_js = 42;", null);
            httpServer.setResponseBase64(imageUrl, CommonResources.FAVICON_DATA_BASE64, null);

            final String jsHtml = "<script src=\"" + httpServer.getResponseUrl(jsUrl)
                    + "\"></script>";
            final String imageHtml = "<img src=\"" + httpServer.getResponseUrl(imageUrl) + "\" />";
            final String secureHtml = "<body>" + imageHtml + " " + jsHtml + "</body>";

            String fullSecureUrl = httpsServer.setResponse(secureUrl, secureHtml, null);

            awSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW);
            mActivityTestRule.loadUrlSync(
                    awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl);
            Assert.assertEquals(1, httpsServer.getRequestCount(secureUrl));
            Assert.assertEquals(0, httpServer.getRequestCount(jsUrl));
            Assert.assertEquals(0, httpServer.getRequestCount(imageUrl));

            awSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
            mActivityTestRule.loadUrlSync(
                    awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl);
            Assert.assertEquals(2, httpsServer.getRequestCount(secureUrl));
            Assert.assertEquals(1, httpServer.getRequestCount(jsUrl));
            Assert.assertEquals(1, httpServer.getRequestCount(imageUrl));

            awSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
            mActivityTestRule.loadUrlSync(
                    awContents, contentClient.getOnPageFinishedHelper(), fullSecureUrl);
            Assert.assertEquals(3, httpsServer.getRequestCount(secureUrl));
            Assert.assertEquals(1, httpServer.getRequestCount(jsUrl));
            Assert.assertEquals(2, httpServer.getRequestCount(imageUrl));
        } finally {
            if (httpServer != null) {
                httpServer.shutdown();
            }
            if (httpsServer != null) {
                httpsServer.shutdown();
            }
        }
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testUpdatingUserAgentWhileLoadingCausesReload() throws Throwable {
        final TestAwContentsClient contentClient = new TestAwContentsClient();
        final AwTestContainerView testContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(contentClient);
        final AwContents awContents = testContainerView.getAwContents();
        final AwSettings awSettings = mActivityTestRule.getAwSettingsOnUiThread(awContents);

        TestWebServer httpServer = null;
        try {
            httpServer = TestWebServer.start();

            String url = httpServer.setResponseWithRunnableAction(
                    "/about.html", "Hello, World!", null,
                    () -> {
                        // This will update the UA string on the UI thread synchronously.
                        awSettings.setUserAgentString("UA Override");
                    }
            );

            DoUpdateVisitedHistoryHelper doUpdateVisitedHistoryHelper =
                    contentClient.getDoUpdateVisitedHistoryHelper();
            int callCount = doUpdateVisitedHistoryHelper.getCallCount();
            mActivityTestRule.loadUrlAsync(awContents, url);
            doUpdateVisitedHistoryHelper.waitForCallback(callCount);
            Assert.assertEquals(url, doUpdateVisitedHistoryHelper.getUrl());
            Assert.assertEquals(true, doUpdateVisitedHistoryHelper.getIsReload());
        } finally {
            if (httpServer != null) {
                httpServer.shutdown();
            }
        }
    }

    private TestDependencyFactory mOverridenFactory;

    @After
    public void tearDown() throws Exception {
        mOverridenFactory = null;
    }

    private static class EmptyDocumentPeristenceTestDependencyFactory
            extends TestDependencyFactory {
        private boolean mAllow;
        public EmptyDocumentPeristenceTestDependencyFactory(boolean allow) {
            mAllow = allow;
        }

        @Override
        public AwSettings createAwSettings(Context context, boolean supportsLegacyQuirks) {
            return new AwSettings(context, false /* isAccessFromFileURLsGrantedByDefault */,
                    supportsLegacyQuirks, mAllow, true /* allowGeolocationOnInsecureOrigins */,
                    false /* doNotUpdateSelectionOnMutatingSelectionRange */);
        }
    }

    private void doAllowEmptyDocumentPersistenceTest(boolean allow) throws Throwable {
        mOverridenFactory = new EmptyDocumentPeristenceTestDependencyFactory(allow);

        final TestAwContentsClient client = new TestAwContentsClient();
        final AwTestContainerView mContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(client);
        final AwContents awContents = mContainerView.getAwContents();
        AwActivityTestRule.enableJavaScriptOnUiThread(awContents);
        JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(),
                awContents, client.getOnEvaluateJavaScriptResultHelper(),
                "window.emptyDocumentPersistenceTest = true;");
        mActivityTestRule.loadUrlSync(awContents, client.getOnPageFinishedHelper(),
                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
        String result = JSUtils.executeJavaScriptAndWaitForResult(
                InstrumentationRegistry.getInstrumentation(), awContents,
                client.getOnEvaluateJavaScriptResultHelper(),
                "window.emptyDocumentPersistenceTest ? 'set' : 'not set';");
        Assert.assertEquals(allow ? "\"set\"" : "\"not set\"", result);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testAllowEmptyDocumentPersistence() throws Throwable {
        doAllowEmptyDocumentPersistenceTest(true);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testDisallowEmptyDocumentPersistence() throws Throwable {
        doAllowEmptyDocumentPersistenceTest(false);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Preferences"})
    public void testCSSHexAlphaColorEnabled() throws Throwable {
        final TestAwContentsClient client = new TestAwContentsClient();
        final AwTestContainerView view =
                mActivityTestRule.createAwTestContainerViewOnMainSync(client);
        final AwContents awContents = view.getAwContents();
        CallbackHelper onPageFinishedHelper = client.getOnPageFinishedHelper();
        AwActivityTestRule.enableJavaScriptOnUiThread(awContents);
        final String expectedTitle = "false"; // https://crbug.com/618472
        final String page = "<!doctype html>"
                + "<script>"
                + "window.onload = function() {"
                + "  document.title = CSS.supports('color', '#AABBCCDD');"
                + "};"
                + "</script>";
        // Loading the html via a data URI requires us to encode '#' symbols as '%23'.
        mActivityTestRule.loadDataSync(
                awContents, onPageFinishedHelper, page.replace("#", "%23"), "text/html", false);
        String actualTitle = mActivityTestRule.getTitleOnUiThread(awContents);
        Assert.assertEquals(expectedTitle, actualTitle);
    }

    private static class SelectionRangeTestDependencyFactory extends TestDependencyFactory {
        private boolean mDoNotUpdate;
        public SelectionRangeTestDependencyFactory(boolean doNotUpdate) {
            mDoNotUpdate = doNotUpdate;
        }

        @Override
        public AwSettings createAwSettings(Context context, boolean supportsLegacyQuirks) {
            return new AwSettings(context, false /* isAccessFromFileURLsGrantedByDefault */,
                    supportsLegacyQuirks, false /* allowEmptyDocumentPersistence */,
                    true /* allowGeolocationOnInsecureOrigins */,
                    mDoNotUpdate /* doNotUpdateSelectionOnMutatingSelectionRange */);
        }
    }

    private void selectionUpdateOnMutatingSelectionRangeTest(boolean doNotUpdate) throws Throwable {
        mOverridenFactory = new SelectionRangeTestDependencyFactory(doNotUpdate);

        final TestAwContentsClient client = new TestAwContentsClient();
        final AwTestContainerView mContainerView =
                mActivityTestRule.createAwTestContainerViewOnMainSync(client);
        final AwContents awContents = mContainerView.getAwContents();
        AwActivityTestRule.enableJavaScriptOnUiThread(awContents);
        final String testPageHtml =
                "<html><head></head><body><div id='a' contenteditable></div><script>"
                + "var cnt = 0;"
                + "var a = document.getElementById('a');"
                + "document.addEventListener('selectionchange', onSelectionChange, false);"
                + "function onSelectionChange(event) {"
                + "  cnt++;"
                + "}"
                + "</script></body></html>";
        mActivityTestRule.loadDataSync(
                awContents, client.getOnPageFinishedHelper(), testPageHtml, "text/html", false);

        // Focus on an empty DIV.
        JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(),
                awContents, client.getOnEvaluateJavaScriptResultHelper(), "window.a.focus();");
        Assert.assertEquals(1, getSelectionChangeCountForSelectionUpdateTest(awContents, client));

        // Create and delete a zero-width space. See crbug.com/698752 for details.
        JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(),
                awContents, client.getOnEvaluateJavaScriptResultHelper(),
                "(function() {"
                        + "var sel = window.getSelection();"
                        + "var range = sel.getRangeAt(0);"
                        + "var span = document.createElement('span');"
                        + "var textNodeForZWSP = document.createTextNode('\u200B');"
                        + "span.appendChild(textNodeForZWSP);"
                        + "range.insertNode(span);"
                        + "range.selectNode(span);"
                        + "range.deleteContents();"
                        + "}) ();");
        int expectedResult = doNotUpdate ? 0 : 1;
        Assert.assertEquals(
                expectedResult, getSelectionChangeCountForSelectionUpdateTest(awContents, client));
    }

    private void pollTitleAs(final String title, final AwContents awContents) throws Exception {
        AwActivityTestRule.pollInstrumentationThread(
                () -> title.equals(mActivityTestRule.getTitleOnUiThread(awContents)));
    }

    private int getSelectionChangeCountForSelectionUpdateTest(
            AwContents awContents, TestAwContentsClient client) throws Exception {
        mTitleIdx++;
        String expectedTitle = Integer.toString(mTitleIdx);
        // Since selectionchange event is posted on a message loop, we run another message loop
        // before we get the result. On Chromium both run on the same message loop.
        JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(),
                awContents, client.getOnEvaluateJavaScriptResultHelper(),
                "setTimeout(function() { document.title = '" + expectedTitle + "'; });");
        pollTitleAs(expectedTitle, awContents);

        String result = JSUtils.executeJavaScriptAndWaitForResult(
                InstrumentationRegistry.getInstrumentation(), awContents,
                client.getOnEvaluateJavaScriptResultHelper(), "window.cnt");
        // Clean up
        JSUtils.executeJavaScriptAndWaitForResult(InstrumentationRegistry.getInstrumentation(),
                awContents, client.getOnEvaluateJavaScriptResultHelper(), "window.cnt = 0;");
        return Integer.parseInt(result);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Selection"})
    public void testDoNotUpdateSelectionOnMutatingSelectionRange() throws Throwable {
        selectionUpdateOnMutatingSelectionRangeTest(true);
    }

    @Test
    @SmallTest
    @Feature({"AndroidWebView", "Selection"})
    public void testUpdateSelectionOnMutatingSelectionRange() throws Throwable {
        selectionUpdateOnMutatingSelectionRangeTest(false);
    }

    static class ViewPair {
        private final AwTestContainerView mContainer0;
        private final TestAwContentsClient mClient0;
        private final AwTestContainerView mContainer1;
        private final TestAwContentsClient mClient1;

        ViewPair(AwTestContainerView container0, TestAwContentsClient client0,
                 AwTestContainerView container1, TestAwContentsClient client1) {
            this.mContainer0 = container0;
            this.mClient0 = client0;
            this.mContainer1 = container1;
            this.mClient1 = client1;
        }

        AwTestContainerView getContainer0() {
            return mContainer0;
        }

        AwContents getContents0() {
            return mContainer0.getAwContents();
        }

        TestAwContentsClient getClient0() {
            return mClient0;
        }

        AwTestContainerView getContainer1() {
            return mContainer1;
        }

        AwContents getContents1() {
            return mContainer1.getAwContents();
        }

        TestAwContentsClient getClient1() {
            return mClient1;
        }
    }

    /**
     * Verifies the following statements about a setting:
     *  - initially, the setting has a default value;
     *  - the setting can be switched to an alternate value and back;
     *  - switching a setting in the first WebView doesn't affect the setting
     *    state in the second WebView and vice versa.
     *
     * @param helper0 Test helper for the first ContentView
     * @param helper1 Test helper for the second ContentView
     * @throws Throwable
     */
    private void runPerViewSettingsTest(
            AwSettingsTestHelper<?> helper0, AwSettingsTestHelper<?> helper1) throws Throwable {
        helper0.ensureSettingHasInitialValue();
        helper1.ensureSettingHasInitialValue();

        helper1.setAlteredSettingValue();
        helper0.ensureSettingHasInitialValue();
        helper1.ensureSettingHasAlteredValue();

        helper1.setInitialSettingValue();
        helper0.ensureSettingHasInitialValue();
        helper1.ensureSettingHasInitialValue();

        helper0.setAlteredSettingValue();
        helper0.ensureSettingHasAlteredValue();
        helper1.ensureSettingHasInitialValue();

        helper0.setInitialSettingValue();
        helper0.ensureSettingHasInitialValue();
        helper1.ensureSettingHasInitialValue();

        helper0.setAlteredSettingValue();
        helper0.ensureSettingHasAlteredValue();
        helper1.ensureSettingHasInitialValue();

        helper1.setAlteredSettingValue();
        helper0.ensureSettingHasAlteredValue();
        helper1.ensureSettingHasAlteredValue();

        helper0.setInitialSettingValue();
        helper0.ensureSettingHasInitialValue();
        helper1.ensureSettingHasAlteredValue();

        helper1.setInitialSettingValue();
        helper0.ensureSettingHasInitialValue();
        helper1.ensureSettingHasInitialValue();
    }

    private ViewPair createViews() throws Throwable {
        return createViews(false);
    }

    private ViewPair createViews(boolean supportsLegacyQuirks) throws Throwable {
        TestAwContentsClient client0 = new TestAwContentsClient();
        TestAwContentsClient client1 = new TestAwContentsClient();
        return new ViewPair(mActivityTestRule.createAwTestContainerViewOnMainSync(
                                    client0, supportsLegacyQuirks),
                client0,
                mActivityTestRule.createAwTestContainerViewOnMainSync(
                        client1, supportsLegacyQuirks),
                client1);
    }

    static void assertFileIsReadable(String filePath) {
        File file = new File(filePath);
        try {
            Assert.assertTrue("Test file \"" + filePath + "\" is not readable."
                            + "Please make sure that files from "
                            + "android_webview/test/data/device_files/ has been pushed to the "
                            + "device before testing",
                    file.canRead());
        } catch (SecurityException e) {
            Assert.fail("Got a SecurityException for \"" + filePath + "\": " + e.toString());
        }
    }

    /**
     * Verifies the number of resource requests made to the content provider.
     * @param resource Resource name
     * @param expectedCount Expected resource requests count
     */
    private void ensureResourceRequestCountInContentProvider(String resource, int expectedCount) {
        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
        int actualCount = TestContentProvider.getResourceRequestCount(context, resource);
        Assert.assertEquals(expectedCount, actualCount);
    }

    private void resetResourceRequestCountInContentProvider(String resource) {
        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
        TestContentProvider.resetResourceRequestCount(context, resource);
    }

    private String createContentUrl(final String target) {
        return TestContentProvider.createContentUrl(target);
    }

    private void simulateDoubleTapCenterOfWebViewOnUiThread(final AwTestContainerView webView)
            throws Throwable {
        final int x = (webView.getRight() - webView.getLeft()) / 2;
        final int y = (webView.getBottom() - webView.getTop()) / 2;
        final AwContents awContents = webView.getAwContents();
        InstrumentationRegistry.getInstrumentation().runOnMainSync(
                ()
                        -> awContents.getWebContents().getEventForwarder().doubleTapForTest(
                                SystemClock.uptimeMillis(), x, y));
    }
}
