// 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.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>";
        }
    }

    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
    @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', '%23AABBCCDD');"
                + "};"
                + "</script>";
        mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "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));
    }
}
