Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / android_webview / javatests / src / org / chromium / android_webview / test / AwViewportTest.java
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.android_webview.test;
6
7 import android.test.suitebuilder.annotation.MediumTest;
8
9 import org.chromium.android_webview.AwContents;
10 import org.chromium.android_webview.AwSettings;
11 import org.chromium.base.test.util.Feature;
12 import org.chromium.content.browser.test.util.CallbackHelper;
13 import org.chromium.ui.gfx.DeviceDisplayInfo;
14
15 import java.util.Locale;
16 import java.util.concurrent.Callable;
17
18 /**
19  * Tests for usage and quirks of viewport related methods.
20  */
21 public class AwViewportTest extends AwTestBase {
22
23     @MediumTest
24     @Feature({"AndroidWebView"})
25     public void testTargetDensityDpi() throws Throwable {
26         final TestAwContentsClient contentClient = new TestAwContentsClient();
27         final AwTestContainerView testContainerView =
28                 createAwTestContainerViewOnMainSync(contentClient);
29         final AwContents awContents = testContainerView.getAwContents();
30         AwSettings settings = getAwSettingsOnUiThread(awContents);
31         CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
32
33         final String pageTemplate = "<html><head>" +
34                 "<meta name='viewport' content='width=device-width, target-densityDpi=%s' />" +
35                 "</head><body onload='document.title=document.body.clientWidth'></body></html>";
36         final String pageDeviceDpi = String.format((Locale)null, pageTemplate, "device-dpi");
37         final String pageHighDpi = String.format((Locale)null, pageTemplate, "high-dpi");
38         final String pageDpi100 = String.format((Locale)null, pageTemplate, "100");
39
40         settings.setJavaScriptEnabled(true);
41
42         DeviceDisplayInfo deviceInfo =
43                 DeviceDisplayInfo.create(getInstrumentation().getTargetContext());
44         loadDataSync(awContents, onPageFinishedHelper, pageDeviceDpi, "text/html", false);
45         int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
46         assertEquals(deviceInfo.getDisplayWidth(), actualWidth, 10f);
47
48         float displayWidth = (deviceInfo.getDisplayWidth());
49         float deviceDpi = (float) (160f * deviceInfo.getDIPScale());
50
51         loadDataSync(awContents, onPageFinishedHelper, pageHighDpi, "text/html", false);
52         actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
53         assertEquals(displayWidth * (240f / deviceDpi), actualWidth, 10f);
54
55         loadDataSync(awContents, onPageFinishedHelper, pageDpi100, "text/html", false);
56         actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
57         assertEquals(displayWidth * (100f / deviceDpi), actualWidth, 10f);
58     }
59
60     @MediumTest
61     @Feature({"AndroidWebView"})
62     public void testWideViewportInitialScaleDoesNotExpandFixedLayoutWidth() throws Throwable {
63         final TestAwContentsClient contentClient = new TestAwContentsClient();
64         final AwTestContainerView testContainerView =
65                 createAwTestContainerViewOnMainSync(contentClient);
66         final AwContents awContents = testContainerView.getAwContents();
67         AwSettings settings = getAwSettingsOnUiThread(awContents);
68         CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
69
70         final String page = "<html><head>" +
71                 "<meta name='viewport' content='width=device-width, initial-scale=0.5' />" +
72                 "</head><body onload='document.title=document.body.clientWidth'></body></html>";
73
74         settings.setJavaScriptEnabled(true);
75         settings.setUseWideViewPort(true);
76
77         DeviceDisplayInfo deviceInfo =
78                 DeviceDisplayInfo.create(getInstrumentation().getTargetContext());
79         loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
80         float displayWidth = (float) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
81         int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
82         assertEquals(displayWidth, actualWidth, 10f);
83         assertEquals(1.0f, getScaleOnUiThread(awContents));
84     }
85
86     @MediumTest
87     @Feature({"AndroidWebView"})
88     public void testZeroValuesQuirk() throws Throwable {
89         final TestAwContentsClient contentClient = new TestAwContentsClient();
90         final AwTestContainerView testContainerView =
91                 createAwTestContainerViewOnMainSync(contentClient);
92         final AwContents awContents = testContainerView.getAwContents();
93         AwSettings settings = getAwSettingsOnUiThread(awContents);
94         CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
95
96         final String page = "<html><head>" +
97                 "<meta name='viewport' content='width=0, height=0, initial-scale=0.0, " +
98                 "    minimum-scale=0.0, maximum-scale=0.0' />" +
99                 "</head><body onload='document.title=document.body.clientWidth'></body></html>";
100
101         settings.setJavaScriptEnabled(true);
102
103         DeviceDisplayInfo deviceInfo =
104                 DeviceDisplayInfo.create(getInstrumentation().getTargetContext());
105         loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
106         float displayWidth = (float) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
107         int actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
108         assertEquals(displayWidth, actualWidth, 10f);
109         assertEquals(1.0f, getScaleOnUiThread(awContents));
110
111         settings.setUseWideViewPort(true);
112         loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
113         actualWidth = Integer.parseInt(getTitleOnUiThread(awContents));
114         assertEquals(displayWidth, actualWidth, 10f);
115         assertEquals(1.0f, getScaleOnUiThread(awContents));
116     }
117
118     @MediumTest
119     @Feature({"AndroidWebView"})
120     public void testScreenSizeInPhysicalPixelsQuirk() throws Throwable {
121         final TestAwContentsClient contentClient = new TestAwContentsClient();
122         final AwTestContainerView testContainerView =
123                 createAwTestContainerViewOnMainSync(contentClient);
124         final AwContents awContents = testContainerView.getAwContents();
125         AwSettings settings = getAwSettingsOnUiThread(awContents);
126         CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
127
128         settings.setJavaScriptEnabled(true);
129
130         loadUrlSync(awContents, onPageFinishedHelper, "about:blank");
131
132         DeviceDisplayInfo deviceInfo =
133                 DeviceDisplayInfo.create(getInstrumentation().getTargetContext());
134         float dipScale = (float) deviceInfo.getDIPScale();
135         float physicalDisplayWidth = deviceInfo.getDisplayWidth();
136         float cssDisplayWidth = physicalDisplayWidth / dipScale;
137         float physicalDisplayHeight = deviceInfo.getDisplayHeight();
138         float cssDisplayHeight = physicalDisplayHeight / dipScale;
139
140         float screenWidth = Integer.parseInt(
141                 executeJavaScriptAndWaitForResult(awContents, contentClient, "screen.width"));
142         assertEquals(physicalDisplayWidth, screenWidth, 10f);
143         float screenAvailWidth = Integer.parseInt(
144                 executeJavaScriptAndWaitForResult(awContents, contentClient, "screen.availWidth"));
145         assertEquals(physicalDisplayWidth, screenAvailWidth, 10f);
146         float outerWidth = Integer.parseInt(
147                 executeJavaScriptAndWaitForResult(awContents, contentClient, "outerWidth"));
148         float innerWidth = Integer.parseInt(
149                 executeJavaScriptAndWaitForResult(awContents, contentClient, "innerWidth"));
150         assertEquals(innerWidth * dipScale, outerWidth, 10f);
151         String deviceWidthEqualsScreenWidth = executeJavaScriptAndWaitForResult(awContents,
152                 contentClient,
153                 "matchMedia(\"screen and (device-width:" + (int) screenWidth + "px)\").matches");
154         assertEquals("true", deviceWidthEqualsScreenWidth);
155
156         float screenHeight = Integer.parseInt(
157                 executeJavaScriptAndWaitForResult(awContents, contentClient, "screen.height"));
158         assertEquals(physicalDisplayHeight, screenHeight, 10f);
159         float screenAvailHeight = Integer.parseInt(
160                 executeJavaScriptAndWaitForResult(awContents, contentClient, "screen.availHeight"));
161         assertEquals(physicalDisplayHeight, screenAvailHeight, 10f);
162         float outerHeight = Integer.parseInt(
163                 executeJavaScriptAndWaitForResult(awContents, contentClient, "outerHeight"));
164         float innerHeight = Integer.parseInt(
165                 executeJavaScriptAndWaitForResult(awContents, contentClient, "innerHeight"));
166         assertEquals(innerHeight * dipScale, outerHeight, 10f);
167         String deviceHeightEqualsScreenHeight = executeJavaScriptAndWaitForResult(awContents,
168                 contentClient,
169                 "matchMedia(\"screen and (device-height:" + (int) screenHeight + "px)\").matches");
170         assertEquals("true", deviceHeightEqualsScreenHeight);
171     }
172
173     @MediumTest
174     @Feature({"AndroidWebView"})
175     public void testMetaMergeContentQuirk() throws Throwable {
176         final TestAwContentsClient contentClient = new TestAwContentsClient();
177         final AwTestContainerView testContainerView =
178                 createAwTestContainerViewOnMainSync(contentClient);
179         final AwContents awContents = testContainerView.getAwContents();
180         AwSettings settings = getAwSettingsOnUiThread(awContents);
181         CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
182
183         final int pageWidth = 3000;
184         final float pageScale = 1.0f;
185         final String page = String.format((Locale)null, "<html><head>" +
186                 "<meta name='viewport' content='width=%d' />" +
187                 "<meta name='viewport' content='initial-scale=%.1f' />" +
188                 "<meta name='viewport' content='user-scalable=0' />" +
189                 "</head><body onload='document.title=document.body.clientWidth'></body></html>",
190                 pageWidth, pageScale);
191
192         settings.setJavaScriptEnabled(true);
193         settings.setUseWideViewPort(true);
194         settings.setBuiltInZoomControls(true);
195         settings.setSupportZoom(true);
196
197         loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
198         int width = Integer.parseInt(getTitleOnUiThread(awContents));
199         assertEquals(pageWidth, width);
200         assertEquals(pageScale, getScaleOnUiThread(awContents));
201         assertEquals(false, canZoomInOnUiThread(awContents));
202         assertEquals(false, canZoomOutOnUiThread(awContents));
203     }
204
205     @MediumTest
206     @Feature({"AndroidWebView"})
207     public void testMetaMergeContentQuirkOverrides() throws Throwable {
208         final TestAwContentsClient contentClient = new TestAwContentsClient();
209         final AwTestContainerView testContainerView =
210                 createAwTestContainerViewOnMainSync(contentClient);
211         final AwContents awContents = testContainerView.getAwContents();
212         AwSettings settings = getAwSettingsOnUiThread(awContents);
213         CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
214
215         final int pageWidth = 3000;
216         final String page = String.format((Locale)null, "<html><head>" +
217                 "<meta name='viewport' content='width=device-width' />" +
218                 "<meta name='viewport' content='width=%d' />" +
219                 "</head><body onload='document.title=document.body.clientWidth'></body></html>",
220                 pageWidth);
221
222         settings.setJavaScriptEnabled(true);
223         settings.setUseWideViewPort(true);
224
225         loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
226         int width = Integer.parseInt(getTitleOnUiThread(awContents));
227         assertEquals(pageWidth, width);
228     }
229
230     @MediumTest
231     @Feature({"AndroidWebView"})
232     public void testInitialScaleClobberQuirk() throws Throwable {
233         final TestAwContentsClient contentClient = new TestAwContentsClient();
234         final AwTestContainerView testContainerView =
235                 createAwTestContainerViewOnMainSync(contentClient);
236         final AwContents awContents = testContainerView.getAwContents();
237         AwSettings settings = getAwSettingsOnUiThread(awContents);
238         CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
239
240         final String pageTemplate = "<html><head>" +
241                 "<meta name='viewport' content='initial-scale=%d' />" +
242                 "</head><body>" +
243                 "<div style='width:10000px;height:200px'>A big div</div>" +
244                 "</body></html>";
245         final String pageScale4 = String.format((Locale)null, pageTemplate, 4);
246         final String page = String.format((Locale)null, pageTemplate, 1);
247
248         // Page scale updates are asynchronous. There is an issue that we can't
249         // reliably check, whether the scale as NOT changed (i.e. remains to be 1.0).
250         // So we first change the scale to some non-default value, and then wait
251         // until it gets back to 1.0.
252         int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
253         loadDataSync(awContents, onPageFinishedHelper, pageScale4, "text/html", false);
254         contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
255         assertEquals(4.0f, getScaleOnUiThread(awContents));
256         // The following call to set initial scale will be ignored. However, a temporary
257         // page scale change may occur, and this makes the usual onScaleChanged-based workflow
258         // flaky. So instead, we are just polling the scale until it becomes 1.0.
259         settings.setInitialPageScale(50);
260         loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
261         ensureScaleBecomes(1.0f, awContents);
262     }
263
264     @MediumTest
265     @Feature({"AndroidWebView"})
266     public void testNoUserScalableQuirk() throws Throwable {
267         final TestAwContentsClient contentClient = new TestAwContentsClient();
268         final AwTestContainerView testContainerView =
269                 createAwTestContainerViewOnMainSync(contentClient);
270         final AwContents awContents = testContainerView.getAwContents();
271         CallbackHelper onPageFinishedHelper = contentClient.getOnPageFinishedHelper();
272
273         final String pageScale4 = "<html><head>" +
274                 "<meta name='viewport' content='initial-scale=4' />" +
275                 "</head><body>" +
276                 "<div style='width:10000px;height:200px'>A big div</div>" +
277                 "</body></html>";
278         final String page = "<html><head>" +
279                 "<meta name='viewport' " +
280                 "content='width=device-width,initial-scale=2,user-scalable=no' />" +
281                 "</head><body>" +
282                 "<div style='width:10000px;height:200px'>A big div</div>" +
283                 "</body></html>";
284
285         // Page scale updates are asynchronous. There is an issue that we can't
286         // reliably check, whether the scale as NOT changed (i.e. remains to be 1.0).
287         // So we first change the scale to some non-default value, and then wait
288         // until it gets back to 1.0.
289         int onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
290         loadDataSync(awContents, onPageFinishedHelper, pageScale4, "text/html", false);
291         contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
292         assertEquals(4.0f, getScaleOnUiThread(awContents));
293         onScaleChangedCallCount = contentClient.getOnScaleChangedHelper().getCallCount();
294         loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false);
295         contentClient.getOnScaleChangedHelper().waitForCallback(onScaleChangedCallCount);
296         assertEquals(1.0f, getScaleOnUiThread(awContents));
297     }
298
299     private void ensureScaleBecomes(final float targetScale, final AwContents awContents)
300             throws Throwable {
301         poll(new Callable<Boolean>() {
302             @Override
303             public Boolean call() throws Exception {
304                 return targetScale == getScaleOnUiThread(awContents);
305             }
306         });
307     }
308 }