forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a mechanism to pause and resume geolocation requests. Currently A…
…ndroid WebView is the only platform to make use of this new API. We implement this as a new API on the Browser-side GeolocationDispatcherHost. In doing so: - Refactor the current LocationProvider such that it doesn't rely on ActivityStatus, updating LocationProviderTest accordingly - Introduce ContentViewLocationTest.java that verifies the LocationProvider implementation is paused and resumed when the ContentView is hidde/shown - Introduce a AwGeolocationTest that verifies the LocationProvider implementation is paused and resumed when the new API is invoked - Introduce LocationProviderFactory and a MockLocationProvider to avoid relying on the system location provider when running tests, as it's not possible to enable mock locations on Android user builds without physical access to the device. BUG=b/11336074 Review URL: https://codereview.chromium.org/65273002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240719 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
benm@chromium.org
committed
Dec 13, 2013
1 parent
139574d
commit 36d6a43
Showing
17 changed files
with
855 additions
and
280 deletions.
There are no files selected for viewing
267 changes: 267 additions & 0 deletions
267
android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.