Index: android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java |
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fc9752771ab61af82ff60deed423ac52e5c45535 |
--- /dev/null |
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java |
@@ -0,0 +1,267 @@ |
+// 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 android.webkit.GeolocationPermissions; |
+ |
+import org.chromium.android_webview.AwContents; |
+import org.chromium.base.test.util.Feature; |
+import org.chromium.content.browser.LocationProviderFactory; |
+import org.chromium.content.browser.test.util.Criteria; |
+import org.chromium.content.browser.test.util.CriteriaHelper; |
+import org.chromium.content.browser.test.util.MockLocationProvider; |
+ |
+/** |
+ * Test suite for Geolocation in AwContents. Smoke tests for |
+ * basic functionality, and tests to ensure the AwContents.onPause |
+ * and onResume APIs affect Geolocation as expected. |
+ */ |
+public class GeolocationTest extends AwTestBase { |
+ |
+ private static final long TEST_TIMEOUT_MS = 5000L; |
+ private static final int CHECK_INTERVAL_MS = 100; |
+ |
+ private TestAwContentsClient mContentsClient; |
+ private AwContents mAwContents; |
+ private MockLocationProvider mMockLocationProvider; |
+ |
+ private static final String RAW_HTML = |
+ "<!DOCTYPE html>\n" + |
+ "<html>\n" + |
+ " <head>\n" + |
+ " <title>Geolocation</title>\n" + |
+ " <script>\n" + |
+ " var positionCount = 0;\n" + |
+ " function gotPos(position) {\n" + |
+ " positionCount++;\n" + |
+ " }\n" + |
+ " function initiate_getCurrentPosition() {\n" + |
+ " navigator.geolocation.getCurrentPosition(\n" + |
+ " gotPos, function() { }, { });\n" + |
+ " }\n" + |
+ " function initiate_watchPosition() {\n" + |
+ " navigator.geolocation.watchPosition(\n" + |
+ " gotPos, function() { }, { });\n" + |
+ " }\n" + |
+ " </script>\n" + |
+ " </head>\n" + |
+ " <body>\n" + |
+ " </body>\n" + |
+ "</html>"; |
+ |
+ @Override |
+ public void setUp() throws Exception { |
+ super.setUp(); |
+ mContentsClient = new TestAwContentsClient() { |
+ @Override |
+ public void onGeolocationPermissionsShowPrompt(String origin, |
+ GeolocationPermissions.Callback callback) { |
+ callback.invoke(origin, true, true); |
+ } |
+ }; |
+ mAwContents = createAwTestContainerViewOnMainSync(mContentsClient).getAwContents(); |
+ enableJavaScriptOnUiThread(mAwContents); |
+ setupGeolocation(); |
+ } |
+ |
+ @Override |
+ public void tearDown() throws Exception { |
+ mMockLocationProvider.stopUpdates(); |
+ GeolocationPermissions.getInstance().clearAll(); |
+ super.tearDown(); |
+ } |
+ |
+ private void setupGeolocation() { |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAwContents.getSettings().setGeolocationEnabled(true); |
+ } |
+ }); |
+ mMockLocationProvider = new MockLocationProvider(); |
+ LocationProviderFactory.setLocationProviderImpl(mMockLocationProvider); |
+ } |
+ |
+ private int getPositionCountFromJS() { |
+ int result = -1; |
+ try { |
+ result = Integer.parseInt(executeJavaScriptAndWaitForResult( |
+ mAwContents, mContentsClient, "positionCount")); |
+ } catch (Exception e) { |
+ fail("Unable to get positionCount"); |
+ } |
+ return result; |
+ } |
+ |
+ private void ensureGeolocationRunning(final boolean running) throws Exception { |
+ assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return mMockLocationProvider.isRunning() == running; |
+ } |
+ }, TEST_TIMEOUT_MS, CHECK_INTERVAL_MS)); |
+ } |
+ |
+ |
+ /** |
+ * Ensure that a call to navigator.getCurrentPosition works in WebView. |
+ */ |
+ @MediumTest |
+ @Feature({"AndroidWebView"}) |
+ public void testGetPosition() throws Throwable { |
+ loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), |
+ RAW_HTML, "text/html", false); |
+ |
+ mAwContents.evaluateJavaScript("initiate_getCurrentPosition();", null); |
+ |
+ assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return getPositionCountFromJS() == 1; |
+ } |
+ }, TEST_TIMEOUT_MS, CHECK_INTERVAL_MS)); |
+ |
+ mAwContents.evaluateJavaScript("initiate_getCurrentPosition();", null); |
+ assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return getPositionCountFromJS() == 2; |
+ } |
+ }, TEST_TIMEOUT_MS, CHECK_INTERVAL_MS)); |
+ } |
+ |
+ /** |
+ * Ensure that a call to navigator.watchPosition works in WebView. |
+ */ |
+ @MediumTest |
+ @Feature({"AndroidWebView"}) |
+ public void testWatchPosition() throws Throwable { |
+ loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), |
+ RAW_HTML, "text/html", false); |
+ |
+ mAwContents.evaluateJavaScript("initiate_watchPosition();", null); |
+ |
+ assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return getPositionCountFromJS() > 1; |
+ } |
+ }, TEST_TIMEOUT_MS, CHECK_INTERVAL_MS)); |
+ } |
+ |
+ @MediumTest |
+ @Feature({"AndroidWebView"}) |
+ public void testPauseGeolocationOnPause() throws Throwable { |
+ // Start a watch going. |
+ loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), |
+ RAW_HTML, "text/html", false); |
+ |
+ mAwContents.evaluateJavaScript("initiate_watchPosition();", null); |
+ |
+ assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return getPositionCountFromJS() > 1; |
+ } |
+ }, TEST_TIMEOUT_MS, CHECK_INTERVAL_MS)); |
+ |
+ ensureGeolocationRunning(true); |
+ |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAwContents.onPause(); |
+ } |
+ }); |
+ |
+ ensureGeolocationRunning(false); |
+ |
+ try { |
+ executeJavaScriptAndWaitForResult(mAwContents, mContentsClient, "positionCount = 0"); |
+ } catch (Exception e) { |
+ fail("Unable to clear positionCount"); |
+ } |
+ assertEquals(0, getPositionCountFromJS()); |
+ |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAwContents.onResume(); |
+ } |
+ }); |
+ |
+ ensureGeolocationRunning(true); |
+ |
+ assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return getPositionCountFromJS() > 1; |
+ } |
+ }, TEST_TIMEOUT_MS, CHECK_INTERVAL_MS)); |
+ } |
+ |
+ @MediumTest |
+ @Feature({"AndroidWebView"}) |
+ public void testPauseAwContentsBeforeNavigating() throws Throwable { |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAwContents.onPause(); |
+ } |
+ }); |
+ |
+ // Start a watch going. |
+ loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), |
+ RAW_HTML, "text/html", false); |
+ |
+ mAwContents.evaluateJavaScript("initiate_watchPosition();", null); |
+ |
+ assertEquals(0, getPositionCountFromJS()); |
+ |
+ ensureGeolocationRunning(false); |
+ |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAwContents.onResume(); |
+ } |
+ }); |
+ |
+ ensureGeolocationRunning(true); |
+ |
+ assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return getPositionCountFromJS() > 1; |
+ } |
+ }, TEST_TIMEOUT_MS, CHECK_INTERVAL_MS)); |
+ |
+ } |
+ |
+ @MediumTest |
+ @Feature({"AndroidWebView"}) |
+ public void testResumeWhenNotStarted() throws Throwable { |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAwContents.onPause(); |
+ } |
+ }); |
+ |
+ loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), |
+ RAW_HTML, "text/html", false); |
+ |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAwContents.onResume(); |
+ } |
+ }); |
+ |
+ ensureGeolocationRunning(false); |
+ } |
+ |
+} |