Bug 489813 - fire geolocation timeout error if the provider fails to response after initial response. r=olli

--HG--
extra : rebase_source : 03c08ca4f017302e8ae2e63cdb844c62f01c234e
This commit is contained in:
Doug Turner 2010-02-23 20:27:27 -08:00
Родитель 684d086beb
Коммит 6989594b87
6 изменённых файлов: 117 добавлений и 32 удалений

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

@ -276,6 +276,7 @@ user_pref("security.warn_viewing_mixed", false);
user_pref("geo.wifi.uri", "http://localhost:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"); user_pref("geo.wifi.uri", "http://localhost:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
user_pref("geo.wifi.testing", true); user_pref("geo.wifi.testing", true);
user_pref("geo.ignore.location_filter", true);
user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others

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

@ -237,24 +237,15 @@ WifiGeoPositionProvider.prototype = {
prefService: null, prefService: null,
provider_url: null,
wifi_service: null, wifi_service: null,
timer: null, timer: null,
protocol: null, protocol: null,
hasSeenWiFi: false, hasSeenWiFi: false,
startup: function() { startup: function() {
LOG("startup called");
this.provider_url = this.prefService.getCharPref("geo.wifi.uri"); LOG("startup called. testing mode is" + gTestingEnabled);
LOG("provider url = " + this.provider_url);
try {
this.protocol = this.prefService.getIntPref("geo.wifi.protocol");
LOG("protocol = " + this.protocol);
} catch (e) {
this.protocol = 0;
}
// if we don't see anything in 5 seconds, kick of one IP geo lookup. // if we don't see anything in 5 seconds, kick of one IP geo lookup.
// if we are testing, just hammer this callback so that we are more or less // if we are testing, just hammer this callback so that we are more or less
// always sending data. It doesn't matter if we have an access point or not. // always sending data. It doesn't matter if we have an access point or not.
@ -263,7 +254,7 @@ WifiGeoPositionProvider.prototype = {
if (gTestingEnabled == false) if (gTestingEnabled == false)
this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT); this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
else else
this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK); this.timer.initWithCallback(this, 750, this.timer.TYPE_REPEATING_SLACK);
}, },
watch: function(c) { watch: function(c) {
@ -327,16 +318,22 @@ WifiGeoPositionProvider.prototype = {
LOG("onChange called"); LOG("onChange called");
this.hasSeenWiFi = true; this.hasSeenWiFi = true;
// Cache the preferred protocol for use inside the XHR callback
var protocol = this.protocol;
// send our request to a wifi geolocation network provider: // send our request to a wifi geolocation network provider:
var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest); var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
// This is a background load // This is a background load
xhr.mozBackgroundRequest = true; xhr.mozBackgroundRequest = true;
xhr.open("POST", this.provider_url, false); var provider_url = this.prefService.getCharPref("geo.wifi.uri");
LOG("provider url = " + provider_url);
var protocol = 0;
try {
protocol = this.prefService.getIntPref("geo.wifi.protocol");
} catch (e) {}
LOG("protocol = " + protocol);
xhr.open("POST", provider_url, false);
// set something so that we can strip cookies // set something so that we can strip cookies
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS; xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
@ -351,7 +348,7 @@ WifiGeoPositionProvider.prototype = {
// if we get a bad response, we will throw and never report a location // if we get a bad response, we will throw and never report a location
var response; var response;
switch (this.protocol) { switch (protocol) {
case 1: case 1:
LOG("service returned: " + req.target.responseXML); LOG("service returned: " + req.target.responseXML);
response = HELD.decode(req.target.responseXML); response = HELD.decode(req.target.responseXML);
@ -398,7 +395,7 @@ WifiGeoPositionProvider.prototype = {
update.update(newLocation); update.update(newLocation);
}; };
var accessToken = this.getAccessTokenForURL(this.provider_url); var accessToken = this.getAccessTokenForURL(provider_url);
var request = { var request = {
version: "1.1.0", version: "1.1.0",
@ -439,9 +436,14 @@ WifiGeoPositionProvider.prototype = {
}, },
notify: function (timer) { notify: function (timer) {
if (this.hasSeenWiFi == false) if (!gTestingEnabled) {
this.onChange(null); if (this.hasSeenWiFi == false)
this.timer = null; this.onChange(null);
this.timer = null;
return;
}
// if we are testing, we need to hammer this.
this.onChange(null);
}, },
}; };

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

@ -134,7 +134,6 @@ nsGeolocationRequest::nsGeolocationRequest(nsGeolocation* aLocator,
nsIDOMGeoPositionOptions* aOptions) nsIDOMGeoPositionOptions* aOptions)
: mAllowed(PR_FALSE), : mAllowed(PR_FALSE),
mCleared(PR_FALSE), mCleared(PR_FALSE),
mHasSentData(PR_FALSE),
mCallback(aCallback), mCallback(aCallback),
mErrorCallback(aErrorCallback), mErrorCallback(aErrorCallback),
mOptions(aOptions), mOptions(aOptions),
@ -191,11 +190,9 @@ nsGeolocationRequest::Notify(nsITimer* aTimer)
// provider yet, cancel the request. Same logic as // provider yet, cancel the request. Same logic as
// ::Cancel, just a different error // ::Cancel, just a different error
if (!mHasSentData) { NotifyError(nsIDOMGeoPositionError::TIMEOUT);
NotifyError(nsIDOMGeoPositionError::TIMEOUT); // remove ourselves from the locator's callback lists.
// remove ourselves from the locator's callback lists. mLocator->RemoveRequest(this);
mLocator->RemoveRequest(this);
}
mTimeoutTimer = nsnull; mTimeoutTimer = nsnull;
return NS_OK; return NS_OK;
@ -277,6 +274,19 @@ nsGeolocationRequest::Allow()
SendLocation(lastPosition); SendLocation(lastPosition);
} }
SetTimeoutTimer();
mAllowed = PR_TRUE;
return NS_OK;
}
void
nsGeolocationRequest::SetTimeoutTimer()
{
if (mTimeoutTimer) {
mTimeoutTimer->Cancel();
mTimeoutTimer = nsnull;
}
PRInt32 timeout; PRInt32 timeout;
if (mOptions && NS_SUCCEEDED(mOptions->GetTimeout(&timeout)) && timeout > 0) { if (mOptions && NS_SUCCEEDED(mOptions->GetTimeout(&timeout)) && timeout > 0) {
@ -286,9 +296,6 @@ nsGeolocationRequest::Allow()
mTimeoutTimer = do_CreateInstance("@mozilla.org/timer;1"); mTimeoutTimer = do_CreateInstance("@mozilla.org/timer;1");
mTimeoutTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT); mTimeoutTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT);
} }
mAllowed = PR_TRUE;
return NS_OK;
} }
void void
@ -303,6 +310,11 @@ nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
if (mCleared || !mAllowed) if (mCleared || !mAllowed)
return; return;
if (mTimeoutTimer) {
mTimeoutTimer->Cancel();
mTimeoutTimer = nsnull;
}
// we should not pass null back to the DOM. // we should not pass null back to the DOM.
if (!aPosition) { if (!aPosition) {
NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE); NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
@ -320,7 +332,7 @@ nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
JSContext* cx; JSContext* cx;
stack->Pop(&cx); stack->Pop(&cx);
mHasSentData = PR_TRUE; SetTimeoutTimer();
} }
void void
@ -345,6 +357,8 @@ NS_IMPL_THREADSAFE_RELEASE(nsGeolocationService)
static PRBool sGeoEnabled = PR_TRUE; static PRBool sGeoEnabled = PR_TRUE;
static PRBool sGeoIgnoreLocationFilter = PR_FALSE;
static int static int
GeoEnabledChangedCallback(const char *aPrefName, void *aClosure) GeoEnabledChangedCallback(const char *aPrefName, void *aClosure)
{ {
@ -476,7 +490,7 @@ nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
PRBool PRBool
nsGeolocationService::IsBetterPosition(nsIDOMGeoPosition *aSomewhere) nsGeolocationService::IsBetterPosition(nsIDOMGeoPosition *aSomewhere)
{ {
if (!aSomewhere) if (!aSomewhere)
return PR_FALSE; return PR_FALSE;
@ -484,6 +498,9 @@ nsGeolocationService::IsBetterPosition(nsIDOMGeoPosition *aSomewhere)
if (!geoService) if (!geoService)
return PR_FALSE; return PR_FALSE;
if (sGeoIgnoreLocationFilter)
return PR_TRUE;
nsCOMPtr<nsIDOMGeoPosition> lastPosition = geoService->GetCachedPosition(); nsCOMPtr<nsIDOMGeoPosition> lastPosition = geoService->GetCachedPosition();
if (!lastPosition) if (!lastPosition)
return PR_TRUE; return PR_TRUE;

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

@ -80,6 +80,7 @@ class nsGeolocationRequest : public nsIGeolocationRequest, public nsITimerCallba
void SendLocation(nsIDOMGeoPosition* location); void SendLocation(nsIDOMGeoPosition* location);
void MarkCleared(); void MarkCleared();
PRBool Allowed() {return mAllowed;} PRBool Allowed() {return mAllowed;}
void SetTimeoutTimer();
~nsGeolocationRequest(); ~nsGeolocationRequest();
@ -88,7 +89,6 @@ class nsGeolocationRequest : public nsIGeolocationRequest, public nsITimerCallba
void NotifyError(PRInt16 errorCode); void NotifyError(PRInt16 errorCode);
PRPackedBool mAllowed; PRPackedBool mAllowed;
PRPackedBool mCleared; PRPackedBool mCleared;
PRPackedBool mHasSentData;
nsCOMPtr<nsITimer> mTimeoutTimer; nsCOMPtr<nsITimer> mTimeoutTimer;
nsCOMPtr<nsIDOMGeoPositionCallback> mCallback; nsCOMPtr<nsIDOMGeoPositionCallback> mCallback;

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

@ -45,6 +45,7 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
_TEST_FILES = \ _TEST_FILES = \
test_timerRestartWatch.html \
test_manyCurrentSerial.html \ test_manyCurrentSerial.html \
test_manyCurrentConcurrent.html \ test_manyCurrentConcurrent.html \
test_garbageWatch.html \ test_garbageWatch.html \

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

@ -0,0 +1,64 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=526326
-->
<head>
<title>Test for watchPosition </title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<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=526326">Mozilla Bug 526326</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var watchID;
var hasAccepted = false;
function errorCallback(err) {
ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
resume_geolocationProvider();
SimpleTest.finish();
}
function successCallback(position) {
ok(hasAccepted, "Ensure that accept was pressed");
// Now that we got a success callback, lets try to ensure
// that we get a timeout error.
stop_geolocationProvider();
}
function accept() {
hasAccepted = true;
clickNotificationButton(kAcceptButton);
}
/** Test for Bug **/
SimpleTest.waitForExplicitFinish();
var options = {
maximumAge: 0,
timeout: 1000
};
watchID = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
setTimeout(accept, 50);
</script>
</pre>
</body>
</html>