Bug 684722 - Invoke geolocation error handlers when xhr fails. r=jdm

This commit is contained in:
Bharath Thiruveedula 2013-10-08 08:22:42 -04:00
Родитель db6beebeeb
Коммит dde90bad3e
6 изменённых файлов: 87 добавлений и 7 удалений

Просмотреть файл

@ -79,6 +79,7 @@ class nsGeolocationRequest
void SendLocation(nsIDOMGeoPosition* location); void SendLocation(nsIDOMGeoPosition* location);
bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;} bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;}
void SetTimeoutTimer(); void SetTimeoutTimer();
void NotifyErrorAndShutdown(uint16_t);
nsIPrincipal* GetPrincipal(); nsIPrincipal* GetPrincipal();
~nsGeolocationRequest(); ~nsGeolocationRequest();
@ -366,6 +367,13 @@ NS_IMPL_CYCLE_COLLECTION_3(nsGeolocationRequest, mCallback, mErrorCallback, mLoc
NS_IMETHODIMP NS_IMETHODIMP
nsGeolocationRequest::Notify(nsITimer* aTimer) nsGeolocationRequest::Notify(nsITimer* aTimer)
{
NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT);
return NS_OK;
}
void
nsGeolocationRequest::NotifyErrorAndShutdown(uint16_t aErrorCode)
{ {
MOZ_ASSERT(!mShutdown, "timeout after shutdown"); MOZ_ASSERT(!mShutdown, "timeout after shutdown");
@ -374,13 +382,11 @@ nsGeolocationRequest::Notify(nsITimer* aTimer)
mLocator->RemoveRequest(this); mLocator->RemoveRequest(this);
} }
NotifyError(nsIDOMGeoPositionError::TIMEOUT); NotifyError(aErrorCode);
if (!mShutdown) { if (!mShutdown) {
SetTimeoutTimer(); SetTimeoutTimer();
} }
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -1160,13 +1166,13 @@ Geolocation::NotifyError(uint16_t aErrorCode)
} }
for (uint32_t i = mPendingCallbacks.Length(); i > 0; i--) { for (uint32_t i = mPendingCallbacks.Length(); i > 0; i--) {
mPendingCallbacks[i-1]->NotifyError(aErrorCode); mPendingCallbacks[i-1]->NotifyErrorAndShutdown(aErrorCode);
RemoveRequest(mPendingCallbacks[i-1]); //NotifyErrorAndShutdown() removes the request from the array
} }
// notify everyone that is watching // notify everyone that is watching
for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) { for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) {
mWatchingCallbacks[i]->NotifyError(aErrorCode); mWatchingCallbacks[i]->NotifyErrorAndShutdown(aErrorCode);
} }
return NS_OK; return NS_OK;

Просмотреть файл

@ -170,22 +170,30 @@ WifiGeoPositionProvider.prototype = {
// This is a background load // This is a background load
xhr.open("POST", url, true); try {
xhr.open("POST", url, true);
} catch (e) {
triggerError();
return;
}
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8"); xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
xhr.responseType = "json"; xhr.responseType = "json";
xhr.mozBackgroundRequest = true; xhr.mozBackgroundRequest = true;
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS; xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
xhr.onerror = function() { xhr.onerror = function() {
LOG("onerror: " + xhr); LOG("onerror: " + xhr);
triggerError();
}; };
xhr.onload = function() { xhr.onload = function() {
LOG("gls returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response)); LOG("gls returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response));
if (xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) { if (xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) {
triggerError();
return; return;
} }
if (!xhr.response || !xhr.response.location) { if (!xhr.response || !xhr.response.location) {
triggerError();
return; return;
} }
@ -218,4 +226,8 @@ WifiGeoPositionProvider.prototype = {
}, },
}; };
function triggerError() {
Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
.notifyError(Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE);
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]); this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);

Просмотреть файл

@ -51,6 +51,11 @@ function delay_geolocationProvider(delay, callback)
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay]]}, callback); SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay]]}, callback);
} }
function send404_geolocationProvider(callback)
{
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=send404"]]}, callback);
}
function check_geolocation(location) { function check_geolocation(location) {
ok(location, "Check to see if this location is non-null"); ok(location, "Check to see if this location is non-null");

Просмотреть файл

@ -12,6 +12,7 @@ support-files =
[test_cancelWatch.html] [test_cancelWatch.html]
[test_clearWatch.html] [test_clearWatch.html]
[test_clearWatch_invalid.html] [test_clearWatch_invalid.html]
[test_errorcheck.html]
[test_geolocation_is_undefined_when_pref_is_off.html] [test_geolocation_is_undefined_when_pref_is_off.html]
[test_handlerSpinsEventLoop.html] [test_handlerSpinsEventLoop.html]
[test_manyCurrentConcurrent.html] [test_manyCurrentConcurrent.html]

Просмотреть файл

@ -37,6 +37,7 @@ function handleRequest(request, response)
var params = parseQueryString(request.queryString); var params = parseQueryString(request.queryString);
if (params.action == "stop-responding") { if (params.action == "stop-responding") {
response.processAsync();
return; return;
} }
@ -64,6 +65,11 @@ function handleRequest(request, response)
if ('delay' in params) { if ('delay' in params) {
delay = params.delay; delay = params.delay;
} }
if (params.action === "send404") {
response.setStatusLine("1.0", 404, "Not Found");
response.finish();
return;
}
timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer); timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
timer.initWithCallback(function() { timer.initWithCallback(function() {
response.write(position); response.write(position);

Просмотреть файл

@ -0,0 +1,50 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=684722
-->
<head>
<title>Test for ErrorChecking </title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="geolocation_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=684722">Mozilla Bug 684722</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
function test1() {
send404_geolocationProvider(test2);
}
function errorCallback(error) {
is(error.code,
SpecialPowers.Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE, "Geolocation error handler fired");
SimpleTest.finish();
}
function successCallback(position) {
ok(0,"Success callback called, which shouldn't be done");
SimpleTest.finish();
}
function test2() {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
}
</script>
</pre>
</body>
</html>