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.
5 package org.chromium.android_webview.test;
7 import android.test.suitebuilder.annotation.MediumTest;
8 import android.webkit.GeolocationPermissions;
10 import org.chromium.android_webview.AwContents;
11 import org.chromium.base.test.util.Feature;
12 import org.chromium.content.browser.LocationProviderFactory;
13 import org.chromium.content.browser.test.util.MockLocationProvider;
15 import java.util.concurrent.Callable;
18 * Test suite for Geolocation in AwContents. Smoke tests for
19 * basic functionality, and tests to ensure the AwContents.onPause
20 * and onResume APIs affect Geolocation as expected.
22 public class GeolocationTest extends AwTestBase {
23 private TestAwContentsClient mContentsClient;
24 private AwContents mAwContents;
25 private MockLocationProvider mMockLocationProvider;
27 private static final String RAW_HTML =
31 " <title>Geolocation</title>\n" +
33 " var positionCount = 0;\n" +
34 " function gotPos(position) {\n" +
35 " positionCount++;\n" +
37 " function initiate_getCurrentPosition() {\n" +
38 " navigator.geolocation.getCurrentPosition(\n" +
39 " gotPos, function() { }, { });\n" +
41 " function initiate_watchPosition() {\n" +
42 " navigator.geolocation.watchPosition(\n" +
43 " gotPos, function() { }, { });\n" +
52 public void setUp() throws Exception {
54 mContentsClient = new TestAwContentsClient() {
56 public void onGeolocationPermissionsShowPrompt(String origin,
57 GeolocationPermissions.Callback callback) {
58 callback.invoke(origin, true, true);
61 mAwContents = createAwTestContainerViewOnMainSync(mContentsClient).getAwContents();
62 enableJavaScriptOnUiThread(mAwContents);
67 public void tearDown() throws Exception {
68 mMockLocationProvider.stopUpdates();
72 private void setupGeolocation() {
73 getInstrumentation().runOnMainSync(new Runnable() {
76 mAwContents.getSettings().setGeolocationEnabled(true);
79 mMockLocationProvider = new MockLocationProvider();
80 LocationProviderFactory.setLocationProviderImpl(mMockLocationProvider);
83 private int getPositionCountFromJS() {
86 result = Integer.parseInt(executeJavaScriptAndWaitForResult(
87 mAwContents, mContentsClient, "positionCount"));
88 } catch (Exception e) {
89 fail("Unable to get positionCount");
94 private void ensureGeolocationRunning(final boolean running) throws Exception {
95 poll(new Callable<Boolean>() {
97 public Boolean call() throws Exception {
98 return mMockLocationProvider.isRunning() == running;
105 * Ensure that a call to navigator.getCurrentPosition works in WebView.
108 @Feature({"AndroidWebView"})
109 public void testGetPosition() throws Throwable {
110 loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
111 RAW_HTML, "text/html", false);
113 mAwContents.evaluateJavaScript("initiate_getCurrentPosition();", null);
115 poll(new Callable<Boolean>() {
117 public Boolean call() throws Exception {
118 return getPositionCountFromJS() == 1;
122 mAwContents.evaluateJavaScript("initiate_getCurrentPosition();", null);
123 poll(new Callable<Boolean>() {
125 public Boolean call() throws Exception {
126 return getPositionCountFromJS() == 2;
132 * Ensure that a call to navigator.watchPosition works in WebView.
135 @Feature({"AndroidWebView"})
136 public void testWatchPosition() throws Throwable {
137 loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
138 RAW_HTML, "text/html", false);
140 mAwContents.evaluateJavaScript("initiate_watchPosition();", null);
142 poll(new Callable<Boolean>() {
144 public Boolean call() throws Exception {
145 return getPositionCountFromJS() > 1;
151 @Feature({"AndroidWebView"})
152 public void testPauseGeolocationOnPause() throws Throwable {
153 // Start a watch going.
154 loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
155 RAW_HTML, "text/html", false);
157 mAwContents.evaluateJavaScript("initiate_watchPosition();", null);
159 poll(new Callable<Boolean>() {
161 public Boolean call() throws Exception {
162 return getPositionCountFromJS() > 1;
166 ensureGeolocationRunning(true);
168 getInstrumentation().runOnMainSync(new Runnable() {
171 mAwContents.onPause();
175 ensureGeolocationRunning(false);
178 executeJavaScriptAndWaitForResult(mAwContents, mContentsClient, "positionCount = 0");
179 } catch (Exception e) {
180 fail("Unable to clear positionCount");
182 assertEquals(0, getPositionCountFromJS());
184 getInstrumentation().runOnMainSync(new Runnable() {
187 mAwContents.onResume();
191 ensureGeolocationRunning(true);
193 poll(new Callable<Boolean>() {
195 public Boolean call() throws Exception {
196 return getPositionCountFromJS() > 1;
202 @Feature({"AndroidWebView"})
203 public void testPauseAwContentsBeforeNavigating() throws Throwable {
204 getInstrumentation().runOnMainSync(new Runnable() {
207 mAwContents.onPause();
211 // Start a watch going.
212 loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
213 RAW_HTML, "text/html", false);
215 mAwContents.evaluateJavaScript("initiate_watchPosition();", null);
217 assertEquals(0, getPositionCountFromJS());
219 ensureGeolocationRunning(false);
221 getInstrumentation().runOnMainSync(new Runnable() {
224 mAwContents.onResume();
228 ensureGeolocationRunning(true);
230 poll(new Callable<Boolean>() {
232 public Boolean call() throws Exception {
233 return getPositionCountFromJS() > 1;
239 @Feature({"AndroidWebView"})
240 public void testResumeWhenNotStarted() throws Throwable {
241 getInstrumentation().runOnMainSync(new Runnable() {
244 mAwContents.onPause();
248 loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
249 RAW_HTML, "text/html", false);
251 getInstrumentation().runOnMainSync(new Runnable() {
254 mAwContents.onResume();
258 ensureGeolocationRunning(false);