afcf1272ee933184a7338c2b8baf50a8ea0c0c55
[platform/framework/web/crosswalk.git] / src / android_webview / javatests / src / org / chromium / android_webview / test / AwZoomTest.java
1 // Copyright 2012 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.app.Activity;
8 import android.content.pm.ActivityInfo;
9 import android.test.suitebuilder.annotation.SmallTest;
10 import android.view.View;
11 import android.view.ViewConfiguration;
12
13 import org.chromium.android_webview.AwContents;
14 import org.chromium.android_webview.AwSettings;
15 import org.chromium.base.ThreadUtils;
16 import org.chromium.base.test.util.Feature;
17
18 import java.util.concurrent.Callable;
19
20 /**
21  * A test suite for zooming-related methods and settings.
22  */
23 public class AwZoomTest extends AwTestBase {
24     private TestAwContentsClient mContentsClient;
25     private AwContents mAwContents;
26
27     @Override
28     public void setUp() throws Exception {
29         super.setUp();
30         mContentsClient = new TestAwContentsClient();
31         final AwTestContainerView testContainerView =
32                 createAwTestContainerViewOnMainSync(mContentsClient);
33         mAwContents = testContainerView.getAwContents();
34     }
35
36     private String getZoomableHtml() {
37         return "<html><head><meta name=\"viewport\" content=\"" +
38                 "width=device-width, minimum-scale=0.5, maximum-scale=2.0, initial-scale=0.5" +
39                 "\"/></head><body>Zoomable</body></html>";
40     }
41
42     private String getNonZoomableHtml() {
43         // This page can't be zoomed because its viewport fully occupies
44         // view area and is explicitly made non user-scalable.
45         return "<html><head>" +
46                 "<meta name=\"viewport\" " +
47                 "content=\"width=device-width,height=device-height," +
48                 "initial-scale=1,maximum-scale=1,user-scalable=no\">" +
49                 "</head><body>Non-zoomable</body></html>";
50     }
51
52     private boolean isMultiTouchZoomSupportedOnUiThread() throws Throwable {
53         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
54             @Override
55             public Boolean call() throws Exception {
56                 return mAwContents.isMultiTouchZoomSupported();
57             }
58         });
59     }
60
61     private int getVisibilityOnUiThread(final View view) throws Throwable {
62         return runTestOnUiThreadAndGetResult(new Callable<Integer>() {
63             @Override
64             public Integer call() throws Exception {
65                 return view.getVisibility();
66             }
67         });
68     }
69
70     private View getZoomControlsOnUiThread() throws Throwable {
71         return runTestOnUiThreadAndGetResult(new Callable<View>() {
72             @Override
73             public View call() throws Exception {
74                 return mAwContents.getZoomControlsForTest();
75             }
76         });
77     }
78
79     private void invokeZoomPickerOnUiThread() throws Throwable {
80         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
81             @Override
82             public void run() {
83                 mAwContents.invokeZoomPicker();
84             }
85         });
86     }
87
88     private void zoomInOnUiThreadAndWait() throws Throwable {
89         final float previousScale = getPixelScaleOnUiThread(mAwContents);
90         assertTrue(runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
91             @Override
92             public Boolean call() throws Exception {
93                 return mAwContents.zoomIn();
94             }
95         }));
96         // The zoom level is updated asynchronously.
97         waitForScaleChange(previousScale);
98     }
99
100     private void zoomOutOnUiThreadAndWait() throws Throwable {
101         final float previousScale = getPixelScaleOnUiThread(mAwContents);
102         assertTrue(runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
103             @Override
104             public Boolean call() throws Exception {
105                 return mAwContents.zoomOut();
106             }
107         }));
108         // The zoom level is updated asynchronously.
109         waitForScaleChange(previousScale);
110     }
111
112     private void waitForScaleChange(final float previousScale) throws Throwable {
113         poll(new Callable<Boolean>() {
114             @Override
115             public Boolean call() throws Exception {
116                 return previousScale != getPixelScaleOnUiThread(mAwContents);
117             }
118         });
119     }
120
121     private void waitUntilCanZoomIn() throws Throwable {
122         poll(new Callable<Boolean>() {
123             @Override
124             public Boolean call() throws Exception {
125                 return canZoomInOnUiThread(mAwContents);
126             }
127         });
128     }
129
130     private void waitUntilCanNotZoom() throws Throwable {
131         poll(new Callable<Boolean>() {
132             @Override
133             public Boolean call() throws Exception {
134                 return !canZoomInOnUiThread(mAwContents) &&
135                         !canZoomOutOnUiThread(mAwContents);
136             }
137         });
138     }
139
140     private void runMagnificationTest() throws Throwable {
141         getAwSettingsOnUiThread(mAwContents).setUseWideViewPort(true);
142         assertFalse("Should not be able to zoom in", canZoomInOnUiThread(mAwContents));
143         loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
144                 getZoomableHtml(), "text/html", false);
145         waitUntilCanZoomIn();
146         assertTrue("Should be able to zoom in", canZoomInOnUiThread(mAwContents));
147         assertFalse("Should not be able to zoom out", canZoomOutOnUiThread(mAwContents));
148
149         while (canZoomInOnUiThread(mAwContents)) {
150             zoomInOnUiThreadAndWait();
151         }
152         assertTrue("Should be able to zoom out", canZoomOutOnUiThread(mAwContents));
153
154         while (canZoomOutOnUiThread(mAwContents)) {
155             zoomOutOnUiThreadAndWait();
156         }
157         assertTrue("Should be able to zoom in", canZoomInOnUiThread(mAwContents));
158     }
159
160     @SmallTest
161     @Feature({"AndroidWebView"})
162     public void testMagnification() throws Throwable {
163         getAwSettingsOnUiThread(mAwContents).setSupportZoom(true);
164         runMagnificationTest();
165     }
166
167     // According to Android CTS test, zoomIn/Out must work
168     // even if supportZoom is turned off.
169     @SmallTest
170     @Feature({"AndroidWebView"})
171     public void testMagnificationWithZoomSupportOff() throws Throwable {
172         getAwSettingsOnUiThread(mAwContents).setSupportZoom(false);
173         runMagnificationTest();
174     }
175
176     @SmallTest
177     @Feature({"AndroidWebView"})
178     public void testZoomUsingMultiTouch() throws Throwable {
179         AwSettings webSettings = getAwSettingsOnUiThread(mAwContents);
180         loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
181                 getZoomableHtml(), "text/html", false);
182
183         assertTrue(webSettings.supportZoom());
184         assertFalse(webSettings.getBuiltInZoomControls());
185         assertFalse(isMultiTouchZoomSupportedOnUiThread());
186
187         webSettings.setBuiltInZoomControls(true);
188         assertTrue(isMultiTouchZoomSupportedOnUiThread());
189
190         webSettings.setSupportZoom(false);
191         assertFalse(isMultiTouchZoomSupportedOnUiThread());
192     }
193
194     @SmallTest
195     @Feature({"AndroidWebView"})
196     public void testZoomControls() throws Throwable {
197         AwSettings webSettings = getAwSettingsOnUiThread(mAwContents);
198         webSettings.setUseWideViewPort(true);
199         assertFalse("Should not be able to zoom in", canZoomInOnUiThread(mAwContents));
200         loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
201                 getZoomableHtml(), "text/html", false);
202         waitUntilCanZoomIn();
203         // It must be possible to zoom in (or zoom out) for zoom controls to be shown
204         assertTrue("Should be able to zoom in", canZoomInOnUiThread(mAwContents));
205
206         assertTrue(webSettings.supportZoom());
207         webSettings.setBuiltInZoomControls(true);
208         webSettings.setDisplayZoomControls(false);
209
210         // With DisplayZoomControls set to false, attempts to display zoom
211         // controls must be ignored.
212         assertNull(getZoomControlsOnUiThread());
213         invokeZoomPickerOnUiThread();
214         assertNull(getZoomControlsOnUiThread());
215
216         webSettings.setDisplayZoomControls(true);
217         assertNull(getZoomControlsOnUiThread());
218         invokeZoomPickerOnUiThread();
219         View zoomControls = getZoomControlsOnUiThread();
220         assertEquals(View.VISIBLE, getVisibilityOnUiThread(zoomControls));
221     }
222
223     @SmallTest
224     @Feature({"AndroidWebView"})
225     public void testZoomControlsOnNonZoomableContent() throws Throwable {
226         AwSettings webSettings = getAwSettingsOnUiThread(mAwContents);
227         loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
228                 getNonZoomableHtml(), "text/html", false);
229
230         // ContentView must update itself according to the viewport setup.
231         waitUntilCanNotZoom();
232
233         assertTrue(webSettings.supportZoom());
234         webSettings.setBuiltInZoomControls(true);
235         webSettings.setDisplayZoomControls(true);
236         assertNull(getZoomControlsOnUiThread());
237         invokeZoomPickerOnUiThread();
238         View zoomControls = getZoomControlsOnUiThread();
239         assertEquals(View.GONE, getVisibilityOnUiThread(zoomControls));
240     }
241
242     @SmallTest
243     @Feature({"AndroidWebView"})
244     public void testZoomControlsOnOrientationChange() throws Throwable {
245         AwSettings webSettings = getAwSettingsOnUiThread(mAwContents);
246         loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
247                 getZoomableHtml(), "text/html", false);
248
249         assertTrue(webSettings.supportZoom());
250         webSettings.setBuiltInZoomControls(true);
251         webSettings.setDisplayZoomControls(true);
252         invokeZoomPickerOnUiThread();
253
254         // Now force an orientation change, and try to display the zoom picker
255         // again. Make sure that we don't crash when the ZoomPicker registers
256         // it's receiver.
257
258         Activity activity = getActivity();
259         int orientation = activity.getRequestedOrientation();
260         activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
261         activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
262         activity.setRequestedOrientation(orientation);
263         invokeZoomPickerOnUiThread();
264
265         // We may crash shortly (as the zoom picker has a short delay in it before
266         // it tries to register it's BroadcastReceiver), so sleep to verify we don't.
267         // The delay is encoded in ZoomButtonsController#ZOOM_CONTROLS_TIMEOUT,
268         // if that changes we may need to update this test.
269         Thread.sleep(ViewConfiguration.getZoomControlsTimeout());
270     }
271 }