This source file includes following definitions.
- ensureSettingHasAlteredValue
- ensureSettingHasInitialValue
- setAlteredSettingValue
- setInitialSettingValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getTitleOnUiThread
- loadDataSync
- loadUrlSync
- loadUrlSyncAndExpectError
- executeJavaScriptAndWaitForResult
- ensureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- doEnsureSettingHasValue
- getScript
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- setCurrentValue
- getActualFontSize
- getData
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- getAlteredValue
- getInitialValue
- getCurrentValue
- setCurrentValue
- doEnsureSettingHasValue
- getData
- Feature
- testJavaScriptDisabledByDefault
- Feature
- testJavaScriptEnabledWithTwoViews
- Feature
- testJavaScriptEnabledDynamicWithTwoViews
- Feature
- testPluginsEnabledWithTwoViews
- Feature
- testStandardFontFamilyWithTwoViews
- Feature
- testDefaultFontSizeWithTwoViews
- Feature
- testLoadsImagesAutomaticallyNoPageReload
- Feature
- testLoadsImagesAutomaticallyWithTwoViews
- Feature
- testDefaultTextEncodingWithTwoViews
- Feature
- testUserAgentStringDefault
- Feature
- testUserAgentStringOverride
- Feature
- testUserAgentStringOverrideForHistory
- Feature
- testUserAgentStringWithTwoViews
- Feature
- testUserAgentWithTestServer
- Feature
- testDomStorageEnabledWithTwoViews
- Feature
- testDatabaseInitialValue
- Feature
- testDatabaseEnabled
- Feature
- testDatabaseDisabled
- Feature
- testUniversalAccessFromFilesWithTwoViews
- Feature
- testFileAccessFromFilesImage
- Feature
- testFileAccessFromFilesIframeWithTwoViews
- Feature
- testFileAccessFromFilesXhrWithTwoViews
- Feature
- testFileUrlAccessWithTwoViews
- Feature
- testContentUrlAccessWithTwoViews
- Feature
- testBlockingContentUrlsFromDataUrls
- Feature
- testContentUrlFromFileWithTwoViews
- Feature
- testBlockNetworkImagesDoesNotBlockDataUrlImage
- Feature
- testBlockNetworkImagesBlocksNetworkImageAndReloadInPlace
- Feature
- testBlockNetworkImagesWithTwoViews
- Feature
- testBlockNetworkLoadsWithHttpResources
- onCanPlay
- onError
- Feature
- testBlockNetworkLoadsWithAudio
- Feature
- testAssetUrl
- Feature
- testResourceUrl
- Feature
- testFileUrlAccessToggleDoesNotBlockAssetUrls
- Feature
- testFileUrlAccessToggleDoesNotBlockResourceUrls
- Feature
- testLayoutAlgorithmWithTwoViews
- Feature
- testTextZoomWithTwoViews
- Feature
- testTextZoomAutosizingWithTwoViews
- Feature
- testJavaScriptPopupsWithTwoViews
- Feature
- testCacheMode
- Feature
- testCacheModeWithBlockedNetworkLoads
- Feature
- testCacheModeWithTwoViews
- getHtmlPath
- getHtmlUrl
- getManifestPath
- waitUntilHtmlIsRequested
- waitUntilManifestIsRequested
- waitUntilResourceIsRequested
- Feature
- testAppCache
- Feature
- testAppCacheWithTwoViews
- Feature
- testUseWideViewportWithTwoViews
- Feature
- testUseWideViewportWithTwoViewsNoQuirks
- useWideViewportLayoutWidthTest
- Feature
- testUseWideViewportLayoutWidth
- Feature
- testUseWideViewportLayoutWidthNoQuirks
- Feature
- testUseWideViewportControlsDoubleTabToZoom
- Feature
- testLoadWithOverviewModeWithTwoViews
- Feature
- testLoadWithOverviewModeViewportTagWithTwoViews
- Feature
- testSetInitialScale
- runVideoTest
- testMediaPlaybackWithoutUserGesture
- Feature
- testMediaPlaybackWithUserGesture
- Feature
- testDefaultVideoPosterURL
- getContainer0
- getContents0
- getClient0
- getContainer1
- getContents1
- getClient1
- runPerViewSettingsTest
- createViews
- createViews
- assertFileIsReadable
- ensureResourceRequestCountInContentProvider
- resetResourceRequestCountInContentProvider
- createContentUrl
- simulateDoubleTapCenterOfWebViewOnUiThread
package org.chromium.android_webview.test;
import android.content.Context;
import android.graphics.Point;
import android.os.Build;
import android.os.SystemClock;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwSettings;
import org.chromium.android_webview.AwSettings.LayoutAlgorithm;
import org.chromium.android_webview.InterceptedRequestData;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.ImagePageGenerator;
import org.chromium.android_webview.test.util.JavascriptEventObserver;
import org.chromium.android_webview.test.util.VideoTestWebServer;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.TestFileUtil;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.content.browser.ContentViewCore;
import org.chromium.content.browser.test.util.CallbackHelper;
import org.chromium.content.browser.test.util.HistoryUtils;
import org.chromium.net.test.util.TestWebServer;
import org.chromium.ui.gfx.DeviceDisplayInfo;
import java.io.File;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AwSettingsTest extends AwTestBase {
private static final boolean ENABLED = true;
private static final boolean DISABLED = false;
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 = AwSettingsTest.this.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 AwSettingsTest.this.getTitleOnUiThread(mAwContents);
}
protected void loadDataSync(String data) throws Throwable {
AwSettingsTest.this.loadDataSync(
mAwContents,
mContentViewClient.getOnPageFinishedHelper(),
data,
"text/html",
false);
}
protected void loadUrlSync(String url) throws Throwable {
AwSettingsTest.this.loadUrlSync(
mAwContents,
mContentViewClient.getOnPageFinishedHelper(),
url);
}
protected void loadUrlSyncAndExpectError(String url) throws Throwable {
AwSettingsTest.this.loadUrlSyncAndExpectError(
mAwContents,
mContentViewClient.getOnPageFinishedHelper(),
mContentViewClient.getOnReceivedErrorHelper(),
url);
}
protected String executeJavaScriptAndWaitForResult(String script) throws Exception {
return AwSettingsTest.this.executeJavaScriptAndWaitForResult(
mAwContents, mContentViewClient, script);
}
private void ensureSettingHasValue(T value) throws Throwable {
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());
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>";
}
}
class AwSettingsJavaScriptDynamicTestHelper extends AwSettingsJavaScriptTestHelper {
AwSettingsJavaScriptDynamicTestHelper(
AwTestContainerView containerView,
TestAwContentsClient contentViewClient) throws Throwable {
super(containerView, contentViewClient);
super.doEnsureSettingHasValue(getInitialValue());
}
@Override
protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
String oldTitle = getTitleOnUiThread();
String newTitle = oldTitle + "_modified";
executeJavaScriptAndWaitForResult(getScript(newTitle));
assertEquals(value == ENABLED ? newTitle : oldTitle, getTitleOnUiThread());
}
private String getScript(String title) {
return "document.title='" + title + "';";
}
}
class AwSettingsPluginsTestHelper extends AwSettingsTestHelper<Boolean> {
private static final String PLUGINS_ENABLED_STRING = "Embed";
private static final String PLUGINS_DISABLED_STRING = "NoEmbed";
AwSettingsPluginsTestHelper(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.getPluginsEnabled();
}
@Override
protected void setCurrentValue(Boolean value) {
mAwSettings.setPluginsEnabled(value);
}
@Override
protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
loadDataSync(getData());
assertEquals(
value == ENABLED ? PLUGINS_ENABLED_STRING : PLUGINS_DISABLED_STRING,
getTitleOnUiThread());
}
private String getData() {
return "<html><body onload=\"document.title = document.body.innerText;\">"
+ "<noembed>No</noembed><span>Embed</span></body></html>";
}
}
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());
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());
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());
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);
AwSettingsTest.this.loadUrlSync(
mAwContents,
mContentViewClient.getOnPageFinishedHelper(),
httpImageUrl);
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 "utf-8";
}
@Override
protected String getInitialValue() {
return "Latin-1";
}
@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());
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() {
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());
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 = "webview/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.getTestFilePath(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 {
loadUrlSync(UrlUtils.getTestFileUrl(TEST_FILE));
assertEquals(
value == ENABLED ? HAS_LOCAL_STORAGE : NO_LOCAL_STORAGE,
getTitleOnUiThread());
}
}
class AwSettingsDatabaseTestHelper extends AwSettingsTestHelper<Boolean> {
private static final String TEST_FILE = "webview/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.getTestFilePath(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 {
loadUrlSync(UrlUtils.getTestFileUrl(TEST_FILE));
assertEquals(
value == ENABLED ? HAS_DATABASE : NO_DATABASE,
getTitleOnUiThread());
}
}
class AwSettingsUniversalAccessFromFilesTestHelper extends AwSettingsTestHelper<Boolean> {
private static final String TEST_CONTAINER_FILE = "webview/iframe_access.html";
private static final String TEST_FILE = "webview/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.getTestFilePath(TEST_CONTAINER_FILE));
AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_FILE));
mIframeContainerUrl = UrlUtils.getTestFileUrl(TEST_CONTAINER_FILE);
mIframeUrl = UrlUtils.getTestFileUrl(TEST_FILE);
mAwSettings.setAllowUniversalAccessFromFileURLs(false);
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);
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 = "webview/iframe_access.html";
private static final String TEST_FILE = "webview/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.getTestFilePath(TEST_CONTAINER_FILE));
AwSettingsTest.assertFileIsReadable(UrlUtils.getTestFilePath(TEST_FILE));
mIframeContainerUrl = UrlUtils.getTestFileUrl(TEST_CONTAINER_FILE);
mIframeUrl = UrlUtils.getTestFileUrl(TEST_FILE);
mAwSettings.setAllowUniversalAccessFromFileURLs(false);
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);
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 = "webview/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.getTestFilePath(TEST_FILE));
mXhrContainerUrl = UrlUtils.getTestFileUrl(TEST_FILE);
mAwSettings.setAllowUniversalAccessFromFileURLs(false);
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);
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 = "webview/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.getTestFilePath(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 {
String fileUrl = UrlUtils.getTestFileUrl(TEST_FILE + "?id=" + mIndex);
mIndex += 2;
if (value == ENABLED) {
loadUrlSync(fileUrl);
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 {
AwSettingsTest.this.resetResourceRequestCountInContentProvider(mTarget);
loadUrlSync(AwSettingsTest.this.createContentUrl(mTarget));
if (value == ENABLED) {
AwSettingsTest.this.ensureResourceRequestCountInContentProvider(mTarget, 1);
} else {
AwSettingsTest.this.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 = 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 {
AwSettingsTest.this.resetResourceRequestCountInContentProvider(TARGET);
final String fileName = mTempDir + "/" + TARGET + ".html";
try {
TestFileUtil.createNewHtmlFile(fileName,
TARGET,
"<img src=\"" +
AwSettingsTest.this.createContentUrl(TARGET + "?id=" + mIndex) + "\">");
mIndex += 2;
loadUrlSync("file://" + fileName);
if (value == ENABLED) {
AwSettingsTest.this.ensureResourceRequestCountInContentProvider(TARGET, 1);
} else {
AwSettingsTest.this.ensureResourceRequestCountInContentProvider(TARGET, 0);
}
} finally {
TestFileUtil.deleteFile(fileName);
}
}
private int mIndex;
private String mTempDir;
}
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;
poll(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
executeJavaScriptAndWaitForResult("setTitleToActualFontSize()");
float newFontSize = Float.parseFloat(getTitleOnUiThread());
return newFontSize != oldFontSize;
}
});
mNeedToWaitForFontSizeChange = false;
}
return Float.parseFloat(getTitleOnUiThread());
}
protected String getData() {
DeviceDisplayInfo deviceInfo = DeviceDisplayInfo.create(mContext);
int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
int layoutWidth = (int) (displayWidth * 2.5f);
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() {" +
" 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;\">");
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<LayoutAlgorithm> {
AwSettingsLayoutAlgorithmTestHelper(
AwTestContainerView containerView,
TestAwContentsClient contentViewClient) throws Throwable {
super(containerView, contentViewClient);
mAwSettings.setUseWideViewPort(true);
}
@Override
protected LayoutAlgorithm getAlteredValue() {
return LayoutAlgorithm.TEXT_AUTOSIZING;
}
@Override
protected LayoutAlgorithm getInitialValue() {
return LayoutAlgorithm.NARROW_COLUMNS;
}
@Override
protected LayoutAlgorithm getCurrentValue() {
return mAwSettings.getLayoutAlgorithm();
}
@Override
protected void setCurrentValue(LayoutAlgorithm value) throws Throwable {
super.setCurrentValue(value);
mAwSettings.setLayoutAlgorithm(value);
}
@Override
protected void doEnsureSettingHasValue(LayoutAlgorithm value) throws Throwable {
final float actualFontSize = getActualFontSize();
if (value == LayoutAlgorithm.TEXT_AUTOSIZING) {
assertFalse("Actual font size: " + actualFontSize,
actualFontSize == PARAGRAPH_FONT_SIZE);
} else {
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();
final float ratiosDelta = Math.abs(
(actualFontSize / mInitialActualFontSize) -
(value / (float) INITIAL_TEXT_ZOOM));
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(LayoutAlgorithm.TEXT_AUTOSIZING);
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();
final float ratiosDelta = Math.abs(
(actualFontSize / mInitialActualFontSize) -
(value / (float) INITIAL_TEXT_ZOOM));
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) throws Throwable {
super(containerView, contentViewClient, true);
}
@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;
poll(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
String title = getTitleOnUiThread();
return expectPopupEnabled ? POPUP_ENABLED.equals(title) :
POPUP_BLOCKED.equals(title);
}
});
assertEquals(value ? POPUP_ENABLED : POPUP_BLOCKED, getTitleOnUiThread());
}
private String getData() {
return "<html><head>" +
"<script>" +
" function tryOpenWindow() {" +
" var newWindow = window.open(" +
" 'data:text/html;charset=utf-8," +
" <html><head><title>" + POPUP_ENABLED + "</title></head></html>');" +
" if (!newWindow) document.title = '" + POPUP_BLOCKED + "';" +
" }" +
"</script></head>" +
"<body onload='tryOpenWindow()'></body></html>";
}
}
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() {
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);
assertEquals(0, mWebServer.getRequestCount(htmlPath));
if (value == WebSettings.LOAD_DEFAULT) {
loadUrlSync(url);
assertEquals(1, mWebServer.getRequestCount(htmlPath));
} else {
loadUrlSyncAndExpectError(url);
assertEquals(0, mWebServer.getRequestCount(htmlPath));
}
}
private int mIndex;
private TestWebServer mWebServer;
}
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) {
assertTrue(bodyWidth, VIEWPORT_TAG_LAYOUT_WIDTH.equals(bodyWidth));
} else {
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 = AwSettingsTest.this.getScaleOnUiThread(mAwContents);
if (value) {
assertTrue("Expected: " + currentScale + " < " + DEFAULT_PAGE_SCALE,
currentScale < DEFAULT_PAGE_SCALE);
} else {
assertEquals(DEFAULT_PAGE_SCALE, currentScale);
}
}
private String getData() {
return "<html><head>" +
(mWithViewPortTag ? "<meta name='viewport' content='width=3000' />" : "") +
"</head>" +
"<body></body></html>";
}
private final boolean mWithViewPortTag;
private boolean mExpectScaleChange;
private int mOnScaleChangedCallCount;
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testJavaScriptDisabledByDefault() throws Throwable {
final String JS_ENABLED_STRING = "JS has run";
final String JS_DISABLED_STRING = "JS has not run";
final String TEST_PAGE_HTML =
"<html><head><title>" + JS_DISABLED_STRING + "</title>"
+ "</head><body onload=\"document.title='" + JS_ENABLED_STRING
+ "';\"></body></html>";
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
loadDataSync(
awContents,
contentClient.getOnPageFinishedHelper(),
TEST_PAGE_HTML,
"text/html",
false);
assertEquals(JS_DISABLED_STRING, getTitleOnUiThread(awContents));
}
@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()));
}
@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()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testPluginsEnabledWithTwoViews() throws Throwable {
ViewPair views = createViews();
runPerViewSettingsTest(
new AwSettingsPluginsTestHelper(views.getContainer0(), views.getClient0()),
new AwSettingsPluginsTestHelper(views.getContainer1(), views.getClient1()));
}
@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()));
}
@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()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testLoadsImagesAutomaticallyNoPageReload() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
settings.setJavaScriptEnabled(true);
ImagePageGenerator generator = new ImagePageGenerator(0, false);
settings.setLoadsImagesAutomatically(false);
loadDataSync(awContents,
contentClient.getOnPageFinishedHelper(),
generator.getPageSource(),
"text/html", false);
assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
getTitleOnUiThread(awContents));
settings.setLoadsImagesAutomatically(true);
poll(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return !ImagePageGenerator.IMAGE_NOT_LOADED_STRING.equals(
getTitleOnUiThread(awContents));
}
});
assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, getTitleOnUiThread(awContents));
}
@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"})
public void testDefaultTextEncodingWithTwoViews() throws Throwable {
ViewPair views = createViews();
runPerViewSettingsTest(
new AwSettingsDefaultTextEncodingTestHelper(views.getContainer0(), views.getClient0()),
new AwSettingsDefaultTextEncodingTestHelper(views.getContainer1(), views.getClient1()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testUserAgentStringDefault() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
final String actualUserAgentString = settings.getUserAgentString();
assertEquals(actualUserAgentString, AwSettings.getDefaultUserAgent());
final String patternString =
"Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?" +
"\\s?(.*)\\sBuild/(.+)\\) 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);
assertTrue(String.format("User agent string did not match expected pattern. %nExpected " +
"pattern:%n%s%nActual:%n%s", patternString, actualUserAgentString),
patternMatcher.find());
assertEquals(null, patternMatcher.group(3));
if ("REL".equals(Build.VERSION.CODENAME)) {
assertEquals(Build.MODEL, patternMatcher.group(6));
assertEquals(Build.VERSION.RELEASE, patternMatcher.group(2));
}
assertEquals(Build.ID, patternMatcher.group(7));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testUserAgentStringOverride() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
final String defaultUserAgentString = settings.getUserAgentString();
settings.setUserAgentString(null);
assertEquals(defaultUserAgentString, settings.getUserAgentString());
settings.setUserAgentString("");
assertEquals(defaultUserAgentString, settings.getUserAgentString());
settings.setUserAgentString(defaultUserAgentString);
assertEquals(defaultUserAgentString, settings.getUserAgentString());
final String customUserAgentString = "AwSettingsTest";
settings.setUserAgentString(customUserAgentString);
assertEquals(customUserAgentString, settings.getUserAgentString());
settings.setUserAgentString(null);
assertEquals(defaultUserAgentString, settings.getUserAgentString());
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testUserAgentStringOverrideForHistory() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
final ContentViewCore contentView = testContainerView.getContentViewCore();
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
AwSettings settings = getAwSettingsOnUiThread(awContents);
settings.setJavaScriptEnabled(true);
final String defaultUserAgentString = settings.getUserAgentString();
final String customUserAgentString = "AwSettingsTest";
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);
loadDataSync(
awContents, onPageFinishedHelper, page1, "text/html", false);
assertEquals(page1Title + customUserAgentString, getTitleOnUiThread(awContents));
loadDataSync(
awContents, onPageFinishedHelper, page2, "text/html", false);
assertEquals(page2Title + customUserAgentString, getTitleOnUiThread(awContents));
settings.setUserAgentString(null);
assertEquals(page2Title + customUserAgentString, getTitleOnUiThread(awContents));
HistoryUtils.goBackSync(getInstrumentation(), contentView, onPageFinishedHelper);
assertEquals(page1Title + defaultUserAgentString, getTitleOnUiThread(awContents));
HistoryUtils.goForwardSync(getInstrumentation(), contentView,
onPageFinishedHelper);
assertEquals(page2Title + defaultUserAgentString, getTitleOnUiThread(awContents));
}
@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()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testUserAgentWithTestServer() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
final String customUserAgentString =
"testUserAgentWithTestServerUserAgent";
TestWebServer webServer = null;
String fileName = null;
try {
webServer = new TestWebServer(false);
final String httpPath = "/testUserAgentWithTestServer.html";
final String url = webServer.setResponse(httpPath, "foo", null);
settings.setUserAgentString(customUserAgentString);
loadUrlSync(awContents,
contentClient.getOnPageFinishedHelper(),
url);
assertEquals(1, webServer.getRequestCount(httpPath));
HttpRequest request = webServer.getLastRequest(httpPath);
Header[] matchingHeaders = request.getHeaders("User-Agent");
assertEquals(1, matchingHeaders.length);
Header header = matchingHeaders[0];
assertEquals(customUserAgentString, header.getValue());
} finally {
if (webServer != null) webServer.shutdown();
}
}
@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()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testDatabaseInitialValue() throws Throwable {
TestAwContentsClient client = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(client);
AwSettingsDatabaseTestHelper helper =
new AwSettingsDatabaseTestHelper(testContainerView, client);
helper.ensureSettingHasInitialValue();
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testDatabaseEnabled() throws Throwable {
TestAwContentsClient client = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(client);
AwSettingsDatabaseTestHelper helper =
new AwSettingsDatabaseTestHelper(testContainerView, client);
helper.setAlteredSettingValue();
helper.ensureSettingHasAlteredValue();
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testDatabaseDisabled() throws Throwable {
TestAwContentsClient client = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(client);
AwSettingsDatabaseTestHelper helper =
new AwSettingsDatabaseTestHelper(testContainerView, client);
helper.setInitialSettingValue();
helper.ensureSettingHasInitialValue();
}
@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()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testFileAccessFromFilesImage() throws Throwable {
final String testFile = "webview/image_access.html";
assertFileIsReadable(UrlUtils.getTestFilePath(testFile));
final String imageContainerUrl = UrlUtils.getTestFileUrl(testFile);
final String imageHeight = "16";
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
settings.setJavaScriptEnabled(true);
settings.setAllowUniversalAccessFromFileURLs(false);
settings.setAllowFileAccessFromFileURLs(false);
loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), imageContainerUrl);
assertEquals(imageHeight, getTitleOnUiThread(awContents));
}
@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()));
}
@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()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testFileUrlAccessWithTwoViews() throws Throwable {
ViewPair views = createViews();
runPerViewSettingsTest(
new AwSettingsFileUrlAccessTestHelper(views.getContainer0(), views.getClient0(), 0),
new AwSettingsFileUrlAccessTestHelper(views.getContainer1(), views.getClient1(), 1));
}
@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));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences", "Navigation"})
public void testBlockingContentUrlsFromDataUrls() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
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);
loadDataSync(
awContents,
contentClient.getOnPageFinishedHelper(),
page,
"text/html",
false);
ensureResourceRequestCountInContentProvider(target, 0);
}
@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));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testBlockNetworkImagesDoesNotBlockDataUrlImage() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
final AwSettings settings = getAwSettingsOnUiThread(awContents);
ImagePageGenerator generator = new ImagePageGenerator(0, false);
settings.setJavaScriptEnabled(true);
settings.setImagesEnabled(false);
loadDataSync(awContents,
contentClient.getOnPageFinishedHelper(),
generator.getPageSource(),
"text/html",
false);
assertEquals(ImagePageGenerator.IMAGE_LOADED_STRING, getTitleOnUiThread(awContents));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testBlockNetworkImagesBlocksNetworkImageAndReloadInPlace() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
final AwSettings settings = getAwSettingsOnUiThread(awContents);
settings.setJavaScriptEnabled(true);
ImagePageGenerator generator = new ImagePageGenerator(0, false);
TestWebServer webServer = null;
try {
webServer = new TestWebServer(false);
final String httpImageUrl = generator.getPageUrl(webServer);
settings.setImagesEnabled(false);
loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), httpImageUrl);
assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
getTitleOnUiThread(awContents));
settings.setImagesEnabled(true);
poll(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return ImagePageGenerator.IMAGE_LOADED_STRING.equals(
getTitleOnUiThread(awContents));
}
});
} finally {
if (webServer != null) webServer.shutdown();
}
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testBlockNetworkImagesWithTwoViews() throws Throwable {
ViewPair views = createViews();
TestWebServer webServer = null;
try {
webServer = new TestWebServer(false);
runPerViewSettingsTest(
new AwSettingsImagesEnabledHelper(
views.getContainer0(),
views.getClient0(),
webServer,
new ImagePageGenerator(0, true)),
new AwSettingsImagesEnabledHelper(
views.getContainer1(),
views.getClient1(),
webServer,
new ImagePageGenerator(1, true)));
} finally {
if (webServer != null) webServer.shutdown();
}
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testBlockNetworkLoadsWithHttpResources() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainer =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainer.getAwContents();
final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
awSettings.setJavaScriptEnabled(true);
ImagePageGenerator generator = new ImagePageGenerator(0, false);
TestWebServer webServer = null;
String fileName = null;
try {
webServer = new TestWebServer(false);
final String httpPath = "/image.png";
final String imageUrl = webServer.setResponseBase64(
httpPath, generator.getImageSourceNoAdvance(),
CommonResources.getImagePngHeaders(true));
String pageHtml = "<img src='" + imageUrl + "' " +
"onload=\"document.title='img_onload_fired';\" " +
"onerror=\"document.title='img_onerror_fired';\" />";
Context context = getInstrumentation().getTargetContext();
fileName = context.getCacheDir() + "/block_network_loads_test.html";
TestFileUtil.deleteFile(fileName);
TestFileUtil.createNewHtmlFile(fileName, "unset", pageHtml);
awSettings.setBlockNetworkLoads(true);
loadUrlSync(
awContents,
contentClient.getOnPageFinishedHelper(),
"file:///" + fileName);
assertEquals(0, webServer.getRequestCount(httpPath));
assertEquals("img_onerror_fired", getTitleOnUiThread(awContents));
awSettings.setBlockNetworkLoads(false);
loadUrlSync(
awContents,
contentClient.getOnPageFinishedHelper(),
"file:///" + fileName);
assertEquals(1, webServer.getRequestCount(httpPath));
assertEquals("img_onload_fired", getTitleOnUiThread(awContents));
} finally {
if (fileName != null) TestFileUtil.deleteFile(fileName);
if (webServer != null) webServer.shutdown();
}
}
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();
}
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testBlockNetworkLoadsWithAudio() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainer =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainer.getAwContents();
final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
CallbackHelper callback = new CallbackHelper();
awSettings.setJavaScriptEnabled(true);
TestWebServer webServer = null;
try {
webServer = new TestWebServer(false);
final String httpPath = "/audio.mp3";
final String audioUrl = webServer.setResponse(httpPath, "1", null);
String pageHtml = "<html><body><audio controls src='" + audioUrl + "' " +
"oncanplay=\"AudioEvent.onCanPlay();\" " +
"onerror=\"AudioEvent.onError();\" /> </body></html>";
awSettings.setBlockNetworkLoads(true);
awContents.addPossiblyUnsafeJavascriptInterface(
new AudioEvent(callback), "AudioEvent", null);
int count = callback.getCallCount();
loadDataSync(awContents, contentClient.getOnPageFinishedHelper(), pageHtml,
"text/html", false);
callback.waitForCallback(count, 1);
assertEquals(0, webServer.getRequestCount(httpPath));
} finally {
if (webServer != null) webServer.shutdown();
}
}
@SmallTest
@Feature({"AndroidWebView", "Navigation"})
public void testAssetUrl() throws Throwable {
final String expectedTitle = "Asset File";
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
loadUrlSync(awContents,
contentClient.getOnPageFinishedHelper(),
"file:///android_asset/asset_file.html");
assertEquals(expectedTitle, getTitleOnUiThread(awContents));
}
@SmallTest
@Feature({"AndroidWebView", "Navigation"})
public void testResourceUrl() throws Throwable {
final String expectedTitle = "Resource File";
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
loadUrlSync(awContents,
contentClient.getOnPageFinishedHelper(),
"file:///android_res/raw/resource_file.html");
assertEquals(expectedTitle, getTitleOnUiThread(awContents));
}
@SmallTest
@Feature({"AndroidWebView", "Navigation"})
public void testFileUrlAccessToggleDoesNotBlockAssetUrls() throws Throwable {
final String expectedTitle = "Asset File";
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
final AwSettings settings = getAwSettingsOnUiThread(awContents);
settings.setAllowFileAccess(false);
loadUrlSync(awContents,
contentClient.getOnPageFinishedHelper(),
"file:///android_asset/asset_file.html");
assertEquals(expectedTitle, getTitleOnUiThread(awContents));
}
@SmallTest
@Feature({"AndroidWebView", "Navigation"})
public void testFileUrlAccessToggleDoesNotBlockResourceUrls() throws Throwable {
final String expectedTitle = "Resource File";
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
final AwSettings settings = getAwSettingsOnUiThread(awContents);
settings.setAllowFileAccess(false);
loadUrlSync(awContents,
contentClient.getOnPageFinishedHelper(),
"file:///android_res/raw/resource_file.html");
assertEquals(expectedTitle, getTitleOnUiThread(awContents));
}
@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()));
}
@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()));
}
@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()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testJavaScriptPopupsWithTwoViews() throws Throwable {
ViewPair views = createViews();
runPerViewSettingsTest(
new AwSettingsJavaScriptPopupsTestHelper(views.getContainer0(), views.getClient0()),
new AwSettingsJavaScriptPopupsTestHelper(views.getContainer1(), views.getClient1()));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testCacheMode() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainer =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainer.getAwContents();
final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents());
clearCacheOnUiThread(awContents, true);
assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode());
TestWebServer webServer = null;
try {
webServer = new TestWebServer(false);
final String htmlPath = "/testCacheMode.html";
final String url = webServer.setResponse(htmlPath, "response", null);
awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
assertEquals(1, webServer.getRequestCount(htmlPath));
loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
assertEquals(1, webServer.getRequestCount(htmlPath));
awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
assertEquals(2, webServer.getRequestCount(htmlPath));
loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
assertEquals(3, webServer.getRequestCount(htmlPath));
awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
assertEquals(3, webServer.getRequestCount(htmlPath));
loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), url);
assertEquals(3, webServer.getRequestCount(htmlPath));
final String htmlNotInCachePath = "/testCacheMode-not-in-cache.html";
final String urlNotInCache = webServer.setResponse(htmlNotInCachePath, "", null);
loadUrlSyncAndExpectError(awContents,
contentClient.getOnPageFinishedHelper(),
contentClient.getOnReceivedErrorHelper(),
urlNotInCache);
assertEquals(0, webServer.getRequestCount(htmlNotInCachePath));
} finally {
if (webServer != null) webServer.shutdown();
}
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testCacheModeWithBlockedNetworkLoads() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainer =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainer.getAwContents();
final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents());
clearCacheOnUiThread(awContents, true);
assertEquals(WebSettings.LOAD_DEFAULT, awSettings.getCacheMode());
awSettings.setBlockNetworkLoads(true);
TestWebServer webServer = null;
try {
webServer = new TestWebServer(false);
final String htmlPath = "/testCacheModeWithBlockedNetworkLoads.html";
final String url = webServer.setResponse(htmlPath, "response", null);
loadUrlSyncAndExpectError(awContents,
contentClient.getOnPageFinishedHelper(),
contentClient.getOnReceivedErrorHelper(),
url);
assertEquals(0, webServer.getRequestCount(htmlPath));
awSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
loadUrlSyncAndExpectError(awContents,
contentClient.getOnPageFinishedHelper(),
contentClient.getOnReceivedErrorHelper(),
url);
assertEquals(0, webServer.getRequestCount(htmlPath));
awSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
loadUrlSyncAndExpectError(awContents,
contentClient.getOnPageFinishedHelper(),
contentClient.getOnReceivedErrorHelper(),
url);
assertEquals(0, webServer.getRequestCount(htmlPath));
awSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
loadUrlSyncAndExpectError(awContents,
contentClient.getOnPageFinishedHelper(),
contentClient.getOnReceivedErrorHelper(),
url);
assertEquals(0, webServer.getRequestCount(htmlPath));
} finally {
if (webServer != null) webServer.shutdown();
}
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testCacheModeWithTwoViews() throws Throwable {
ViewPair views = createViews();
TestWebServer webServer = null;
try {
webServer = new TestWebServer(false);
runPerViewSettingsTest(
new AwSettingsCacheModeTestHelper(
views.getContainer0(), views.getClient0(), 0, webServer),
new AwSettingsCacheModeTestHelper(
views.getContainer1(), views.getClient1(), 1, webServer));
} finally {
if (webServer != null) 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 {
poll(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return mWebServer.getRequestCount(path) > initialRequestCount;
}
});
return mWebServer.getRequestCount(path);
}
}
@SmallTest
@Feature({"AndroidWebView", "Preferences", "AppCache"})
public void testAppCache() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainer =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainer.getAwContents();
final AwSettings settings = getAwSettingsOnUiThread(awContents);
settings.setJavaScriptEnabled(true);
settings.setAppCacheEnabled(true);
TestWebServer webServer = null;
try {
webServer = new TestWebServer(false);
ManifestTestHelper helper = new ManifestTestHelper(
webServer, "testAppCache.html", "appcache.manifest");
loadUrlSync(
awContents,
contentClient.getOnPageFinishedHelper(),
helper.getHtmlUrl());
helper.waitUntilHtmlIsRequested(0);
Thread.sleep(1000);
assertEquals(0, webServer.getRequestCount(helper.getManifestPath()));
settings.setAppCachePath("whatever");
loadUrlSync(
awContents,
contentClient.getOnPageFinishedHelper(),
helper.getHtmlUrl());
helper.waitUntilManifestIsRequested(0);
} finally {
if (webServer != null) webServer.shutdown();
}
}
@SmallTest
@Feature({"AndroidWebView", "Preferences", "AppCache"})
public void testAppCacheWithTwoViews() throws Throwable {
ViewPair views = createViews();
AwSettings settings0 = getAwSettingsOnUiThread(views.getContents0());
settings0.setJavaScriptEnabled(true);
settings0.setAppCachePath("whatever");
settings0.setAppCacheEnabled(true);
AwSettings settings1 = getAwSettingsOnUiThread(views.getContents1());
settings1.setJavaScriptEnabled(true);
settings1.setAppCacheEnabled(true);
TestWebServer webServer = null;
try {
webServer = new TestWebServer(false);
ManifestTestHelper helper0 = new ManifestTestHelper(
webServer, "testAppCache_0.html", "appcache.manifest_0");
loadUrlSync(
views.getContents0(),
views.getClient0().getOnPageFinishedHelper(),
helper0.getHtmlUrl());
int manifestRequests0 = helper0.waitUntilManifestIsRequested(0);
ManifestTestHelper helper1 = new ManifestTestHelper(
webServer, "testAppCache_1.html", "appcache.manifest_1");
loadUrlSync(
views.getContents1(),
views.getClient1().getOnPageFinishedHelper(),
helper1.getHtmlUrl());
helper1.waitUntilManifestIsRequested(0);
settings1.setAppCacheEnabled(false);
loadUrlSync(
views.getContents0(),
views.getClient0().getOnPageFinishedHelper(),
helper0.getHtmlUrl());
helper0.waitUntilManifestIsRequested(manifestRequests0);
final int prevManifestRequestCount =
webServer.getRequestCount(helper1.getManifestPath());
int htmlRequests1 = webServer.getRequestCount(helper1.getHtmlPath());
loadUrlSync(
views.getContents1(),
views.getClient1().getOnPageFinishedHelper(),
helper1.getHtmlUrl());
helper1.waitUntilHtmlIsRequested(htmlRequests1);
Thread.sleep(1000);
assertEquals(
prevManifestRequestCount, webServer.getRequestCount(helper1.getManifestPath()));
} finally {
if (webServer != null) webServer.shutdown();
}
}
@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()));
}
@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 = 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 + "' />");
DeviceDisplayInfo deviceInfo = DeviceDisplayInfo.create(testContainer.getContext());
int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
settings.setJavaScriptEnabled(true);
assertFalse(settings.getUseWideViewPort());
loadDataSync(awContents, onPageFinishedHelper, pageNoViewport, "text/html", false);
int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
Math.abs(displayWidth - actualWidth) <= 1);
loadDataSync(awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false);
actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
Math.abs(displayWidth - actualWidth) <= 1);
loadDataSync(
awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false);
actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
Math.abs(displayWidth - actualWidth) <= 1);
settings.setUseWideViewPort(true);
loadDataSync(awContents, onPageFinishedHelper, pageNoViewport, "text/html", false);
actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertTrue("Expected: >= 980 , Actual: " + actualWidth, actualWidth >= 980);
loadDataSync(awContents, onPageFinishedHelper, pageViewportDeviceWidth, "text/html", false);
actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertTrue("Expected: " + displayWidth + ", Actual: " + actualWidth,
Math.abs(displayWidth - actualWidth) <= 1);
loadDataSync(
awContents, onPageFinishedHelper, pageViewportSpecifiedWidth, "text/html", false);
assertEquals(viewportTagSpecifiedWidth, getTitleOnUiThread(awContents));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testUseWideViewportLayoutWidth() throws Throwable {
TestAwContentsClient contentClient = new TestAwContentsClient();
AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper());
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testUseWideViewportLayoutWidthNoQuirks() throws Throwable {
TestAwContentsClient contentClient = new TestAwContentsClient();
AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient, false);
useWideViewportLayoutWidthTest(testContainerView, contentClient.getOnPageFinishedHelper());
}
@MediumTest
@Feature({"AndroidWebView", "Preferences"})
public void testUseWideViewportControlsDoubleTabToZoom() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
AwSettings settings = getAwSettingsOnUiThread(awContents);
settings.setBuiltInZoomControls(true);
DeviceDisplayInfo deviceInfo =
DeviceDisplayInfo.create(testContainerView.getContext());
int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
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>";
assertFalse(settings.getUseWideViewPort());
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
final float initialScale = getScaleOnUiThread(awContents);
simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView);
Thread.sleep(1000);
assertEquals(initialScale, getScaleOnUiThread(awContents));
settings.setUseWideViewPort(true);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
simulateDoubleTapCenterOfWebViewOnUiThread(testContainerView);
contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
final float zoomedOutScale = getScaleOnUiThread(awContents);
assertTrue("zoomedOut: " + zoomedOutScale + ", initial: " + initialScale,
zoomedOutScale < initialScale);
}
@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));
}
@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"})
public void testSetInitialScale() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
final AwSettings awSettings = getAwSettingsOnUiThread(awContents);
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
WindowManager wm = (WindowManager) getInstrumentation().getTargetContext()
.getSystemService(Context.WINDOW_SERVICE);
Point screenSize = new Point();
wm.getDefaultDisplay().getSize(screenSize);
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 =
getInstrumentation().getTargetContext().getResources().getDisplayMetrics().density;
assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
awSettings.setInitialPageScale(50);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
assertEquals(0.5f, getPixelScaleOnUiThread(awContents), .01f);
onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
awSettings.setInitialPageScale(500);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
assertEquals(5.0f, getPixelScaleOnUiThread(awContents), .01f);
onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
awSettings.setInitialPageScale(0);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
}
private boolean runVideoTest(final boolean requiredUserGesture, long waitTime)
throws Throwable {
final JavascriptEventObserver observer = new JavascriptEventObserver();
TestAwContentsClient client = new TestAwContentsClient();
final AwContents awContents = createAwTestContainerViewOnMainSync(client).getAwContents();
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
AwSettings awSettings = awContents.getSettings();
awSettings.setJavaScriptEnabled(true);
awSettings.setMediaPlaybackRequiresUserGesture(requiredUserGesture);
observer.register(awContents.getContentViewCore(), "javaObserver");
}
});
VideoTestWebServer webServer = new VideoTestWebServer(getActivity());
try {
String data = "<html><head><script>" +
"addEventListener('DOMContentLoaded', function() { " +
" document.getElementById('video').addEventListener('play', function() { " +
" javaObserver.notifyJava(); " +
" }, false); " +
"}, false); " +
"</script></head><body>" +
"<video id='video' autoplay control src='" +
webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
loadDataAsync(awContents, data, "text/html", false);
if (waitTime == -1) {
observer.waitForEvent();
return true;
} else {
return observer.waitForEvent(waitTime);
}
} finally {
if (webServer != null && webServer.getTestWebServer() != null)
webServer.getTestWebServer().shutdown();
}
}
@DisabledTest
public void testMediaPlaybackWithoutUserGesture() throws Throwable {
assertTrue(runVideoTest(false, -1));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testMediaPlaybackWithUserGesture() throws Throwable {
assertFalse(runVideoTest(true, 5000));
}
@SmallTest
@Feature({"AndroidWebView", "Preferences"})
public void testDefaultVideoPosterURL() throws Throwable {
final CallbackHelper videoPosterAccessedCallbackHelper = new CallbackHelper();
final String DEFAULT_VIDEO_POSTER_URL = "http://default_video_poster/";
TestAwContentsClient client = new TestAwContentsClient() {
@Override
public InterceptedRequestData shouldInterceptRequest(String url) {
if (url.equals(DEFAULT_VIDEO_POSTER_URL)) {
videoPosterAccessedCallbackHelper.notifyCalled();
}
return null;
}
};
final AwContents awContents = createAwTestContainerViewOnMainSync(client).getAwContents();
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
AwSettings awSettings = awContents.getSettings();
awSettings.setDefaultVideoPosterURL(DEFAULT_VIDEO_POSTER_URL);
}
});
VideoTestWebServer webServer = new VideoTestWebServer(
getInstrumentation().getTargetContext());
try {
String data = "<html><head><body>" +
"<video id='video' control src='" +
webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
loadDataAsync(awContents, data, "text/html", false);
videoPosterAccessedCallbackHelper.waitForCallback(0, 1, 20, TimeUnit.SECONDS);
} finally {
if (webServer.getTestWebServer() != null)
webServer.getTestWebServer().shutdown();
}
}
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;
}
}
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(
createAwTestContainerViewOnMainSync(client0, supportsLegacyQuirks),
client0,
createAwTestContainerViewOnMainSync(client1, supportsLegacyQuirks),
client1);
}
static void assertFileIsReadable(String filePath) {
File file = new File(filePath);
try {
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) {
fail("Got a SecurityException for \"" + filePath + "\": " + e.toString());
}
}
private void ensureResourceRequestCountInContentProvider(String resource, int expectedCount) {
Context context = getInstrumentation().getTargetContext();
int actualCount = TestContentProvider.getResourceRequestCount(context, resource);
assertEquals(expectedCount, actualCount);
}
private void resetResourceRequestCountInContentProvider(String resource) {
Context context = 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();
runTestOnUiThread(new Runnable() {
@Override
public void run() {
awContents.getContentViewCore().sendDoubleTapForTest(
SystemClock.uptimeMillis(), x, y);
}
});
}
}