blob: fab80989973161036970939b26230bf29d3c5fcc [file] [log] [blame]
// Copyright 2013 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 android.test.suitebuilder.annotation.MediumTest;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwSettings;
import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.test.util.CallbackHelper;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.ui.gfx.DeviceDisplayInfo;
public class AwViewportTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView"})
public void testTargetDensityDpi() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
final String pageTemplate = "<html><head>" +
"<meta name='viewport' content='width=device-width, target-densityDpi=%s' />" +
"</head><body onload='document.title=document.body.clientWidth'></body></html>";
final String pageDeviceDpi = String.format(pageTemplate, "device-dpi");
final String pageHighDpi = String.format(pageTemplate, "high-dpi");
final String pageDpi100 = String.format(pageTemplate, "100");
settings.setJavaScriptEnabled(true);
DeviceDisplayInfo deviceInfo =
DeviceDisplayInfo.create(getInstrumentation().getTargetContext());
loadDataSync(awContents, onPageFinishedHelper, pageDeviceDpi, "text/html", false);
int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertEquals(deviceInfo.getDisplayWidth(), actualWidth, 10f);
float displayWidth = (deviceInfo.getDisplayWidth());
float deviceDpi = (float) (160f * deviceInfo.getDIPScale());
loadDataSync(awContents, onPageFinishedHelper, pageHighDpi, "text/html", false);
actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertEquals(displayWidth * (240f / deviceDpi), actualWidth, 10f);
loadDataSync(awContents, onPageFinishedHelper, pageDpi100, "text/html", false);
actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertEquals(displayWidth * (100f / deviceDpi), actualWidth, 10f);
}
@MediumTest
@Feature({"AndroidWebView"})
public void testWideViewportInitialScaleDoesNotExpandFixedLayoutWidth() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
final String page = "<html><head>" +
"<meta name='viewport' content='width=device-width, initial-scale=0.5' />" +
"</head><body onload='document.title=document.body.clientWidth'></body></html>";
settings.setJavaScriptEnabled(true);
settings.setUseWideViewPort(true);
DeviceDisplayInfo deviceInfo =
DeviceDisplayInfo.create(getInstrumentation().getTargetContext());
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
float displayWidth = (float) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertEquals(displayWidth, actualWidth, 10f);
assertEquals(1.0f, getScaleOnUiThread(awContents));
}
@MediumTest
@Feature({"AndroidWebView"})
public void testZeroValuesQuirk() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
final String page = "<html><head>" +
"<meta name='viewport' content='width=0, height=0, initial-scale=0.0, " +
" minimum-scale=0.0, maximum-scale=0.0' />" +
"</head><body onload='document.title=document.body.clientWidth'></body></html>";
settings.setJavaScriptEnabled(true);
DeviceDisplayInfo deviceInfo =
DeviceDisplayInfo.create(getInstrumentation().getTargetContext());
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
float displayWidth = (float) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertEquals(displayWidth, actualWidth, 10f);
assertEquals(1.0f, getScaleOnUiThread(awContents));
settings.setUseWideViewPort(true);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
assertEquals(displayWidth, actualWidth, 10f);
assertEquals(1.0f, getScaleOnUiThread(awContents));
}
@MediumTest
@Feature({"AndroidWebView"})
public void testScreenSizeInPhysicalPixelsQuirk() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
settings.setJavaScriptEnabled(true);
loadUrlSync(awContents, onPageFinishedHelper, "about:blank");
DeviceDisplayInfo deviceInfo =
DeviceDisplayInfo.create(getInstrumentation().getTargetContext());
float dipScale = (float) deviceInfo.getDIPScale();
float physicalDisplayWidth = deviceInfo.getDisplayWidth();
float cssDisplayWidth = physicalDisplayWidth / dipScale;
float physicalDisplayHeight = deviceInfo.getDisplayHeight();
float cssDisplayHeight = physicalDisplayHeight / dipScale;
float screenWidth = Integer.parseInt(
executeJavaScriptAndWaitForResult(awContents, contentClient, "screen.width"));
assertEquals(physicalDisplayWidth, screenWidth, 10f);
float screenAvailWidth = Integer.parseInt(
executeJavaScriptAndWaitForResult(awContents, contentClient, "screen.availWidth"));
assertEquals(physicalDisplayWidth, screenAvailWidth, 10f);
float outerWidth = Integer.parseInt(
executeJavaScriptAndWaitForResult(awContents, contentClient, "outerWidth"));
float innerWidth = Integer.parseInt(
executeJavaScriptAndWaitForResult(awContents, contentClient, "innerWidth"));
assertEquals(innerWidth * dipScale, outerWidth, 10f);
String deviceWidthEqualsScreenWidth = executeJavaScriptAndWaitForResult(awContents,
contentClient,
"matchMedia(\"screen and (device-width:" + (int) screenWidth + "px)\").matches");
assertEquals("true", deviceWidthEqualsScreenWidth);
float screenHeight = Integer.parseInt(
executeJavaScriptAndWaitForResult(awContents, contentClient, "screen.height"));
assertEquals(physicalDisplayHeight, screenHeight, 10f);
float screenAvailHeight = Integer.parseInt(
executeJavaScriptAndWaitForResult(awContents, contentClient, "screen.availHeight"));
assertEquals(physicalDisplayHeight, screenAvailHeight, 10f);
float outerHeight = Integer.parseInt(
executeJavaScriptAndWaitForResult(awContents, contentClient, "outerHeight"));
float innerHeight = Integer.parseInt(
executeJavaScriptAndWaitForResult(awContents, contentClient, "innerHeight"));
assertEquals(innerHeight * dipScale, outerHeight, 10f);
String deviceHeightEqualsScreenHeight = executeJavaScriptAndWaitForResult(awContents,
contentClient,
"matchMedia(\"screen and (device-height:" + (int) screenHeight + "px)\").matches");
assertEquals("true", deviceHeightEqualsScreenHeight);
}
@MediumTest
@Feature({"AndroidWebView"})
public void testMetaMergeContentQuirk() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
final int pageWidth = 3000;
final float pageScale = 1.0f;
final String page = String.format("<html><head>" +
"<meta name='viewport' content='width=%d' />" +
"<meta name='viewport' content='initial-scale=%.1f' />" +
"<meta name='viewport' content='user-scalable=0' />" +
"</head><body onload='document.title=document.body.clientWidth'></body></html>",
pageWidth, pageScale);
settings.setJavaScriptEnabled(true);
settings.setUseWideViewPort(true);
settings.setBuiltInZoomControls(true);
settings.setSupportZoom(true);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
int width = Integer.parseInt(getTitleOnUiThread(awContents));
assertEquals(pageWidth, width);
assertEquals(pageScale, getScaleOnUiThread(awContents));
assertEquals(false, canZoomInOnUiThread(awContents));
assertEquals(false, canZoomOutOnUiThread(awContents));
}
@MediumTest
@Feature({"AndroidWebView"})
public void testMetaMergeContentQuirkOverrides() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
final int pageWidth = 3000;
final String page = String.format("<html><head>" +
"<meta name='viewport' content='width=device-width' />" +
"<meta name='viewport' content='width=%d' />" +
"</head><body onload='document.title=document.body.clientWidth'></body></html>",
pageWidth);
settings.setJavaScriptEnabled(true);
settings.setUseWideViewPort(true);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
int width = Integer.parseInt(getTitleOnUiThread(awContents));
assertEquals(pageWidth, width);
}
@MediumTest
@Feature({"AndroidWebView"})
public void testInitialScaleClobberQuirk() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
AwSettings settings = getAwSettingsOnUiThread(awContents);
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
final String pageTemplate = "<html><head>" +
"<meta name='viewport' content='initial-scale=%d' />" +
"</head><body>" +
"<div style='width:10000px;height:200px'>A big div</div>" +
"</body></html>";
final String pageScale4 = String.format(pageTemplate, 4);
final String page = String.format(pageTemplate, 1);
// Page scale updates are asynchronous. There is an issue that we can't
// reliably check, whether the scale as NOT changed (i.e. remains to be 1.0).
// So we first change the scale to some non-default value, and then wait
// until it gets back to 1.0.
int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
loadDataSync(awContents, onPageFinishedHelper, pageScale4, "text/html", false);
contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
assertEquals(4.0f, getScaleOnUiThread(awContents));
// The following call to set initial scale will be ignored. However, a temporary
// page scale change may occur, and this makes the usual onScaleChanged-based workflow
// flaky. So instead, we are just polling the scale until it becomes 1.0.
settings.setInitialPageScale(50);
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
assertTrue(waitUntilScaleBecomes(1.0f, awContents));
}
@MediumTest
@Feature({"AndroidWebView"})
public void testNoUserScalableQuirk() throws Throwable {
final TestAwContentsClient contentClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createAwTestContainerViewOnMainSync(contentClient);
final AwContents awContents = testContainerView.getAwContents();
CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
final String pageScale4 = "<html><head>" +
"<meta name='viewport' content='initial-scale=4' />" +
"</head><body>" +
"<div style='width:10000px;height:200px'>A big div</div>" +
"</body></html>";
final String page = "<html><head>" +
"<meta name='viewport' " +
"content='width=device-width,initial-scale=2,user-scalable=no' />" +
"</head><body>" +
"<div style='width:10000px;height:200px'>A big div</div>" +
"</body></html>";
// Page scale updates are asynchronous. There is an issue that we can't
// reliably check, whether the scale as NOT changed (i.e. remains to be 1.0).
// So we first change the scale to some non-default value, and then wait
// until it gets back to 1.0.
int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
loadDataSync(awContents, onPageFinishedHelper, pageScale4, "text/html", false);
contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
assertEquals(4.0f, getScaleOnUiThread(awContents));
onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
assertEquals(1.0f, getScaleOnUiThread(awContents));
}
private boolean waitUntilScaleBecomes(final float targetScale, final AwContents awContents)
throws Throwable {
return CriteriaHelper.pollForCriteria(new Criteria() {
@Override
public boolean isSatisfied() {
try {
return targetScale == getScaleOnUiThread(awContents);
} catch (Throwable t) {
t.printStackTrace();
fail("Failed to getScaleOnUiThread: " + t.toString());
return false;
}
}
}, TEST_TIMEOUT_MS, CHECK_INTERVAL_MS);
}
private static final long TEST_TIMEOUT_MS = 20000L;
private static final int CHECK_INTERVAL_MS = 100;
}