diff --git a/build/automation.py.in b/build/automation.py.in index 08648b5d838..dd713ac6392 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -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.testing", true); +user_pref("geo.ignore.location_filter", true); user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others diff --git a/dom/src/geolocation/NetworkGeolocationProvider.js b/dom/src/geolocation/NetworkGeolocationProvider.js index 758433afb69..26ff9c211ac 100755 --- a/dom/src/geolocation/NetworkGeolocationProvider.js +++ b/dom/src/geolocation/NetworkGeolocationProvider.js @@ -237,24 +237,15 @@ WifiGeoPositionProvider.prototype = { prefService: null, - provider_url: null, wifi_service: null, timer: null, protocol: null, hasSeenWiFi: false, startup: function() { - LOG("startup called"); - this.provider_url = this.prefService.getCharPref("geo.wifi.uri"); - LOG("provider url = " + this.provider_url); + LOG("startup called. testing mode is" + gTestingEnabled); - 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 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. @@ -263,7 +254,7 @@ WifiGeoPositionProvider.prototype = { if (gTestingEnabled == false) this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT); else - this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK); + this.timer.initWithCallback(this, 750, this.timer.TYPE_REPEATING_SLACK); }, watch: function(c) { @@ -327,16 +318,22 @@ WifiGeoPositionProvider.prototype = { LOG("onChange called"); 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: var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest); // This is a background load 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 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 var response; - switch (this.protocol) { + switch (protocol) { case 1: LOG("service returned: " + req.target.responseXML); response = HELD.decode(req.target.responseXML); @@ -398,7 +395,7 @@ WifiGeoPositionProvider.prototype = { update.update(newLocation); }; - var accessToken = this.getAccessTokenForURL(this.provider_url); + var accessToken = this.getAccessTokenForURL(provider_url); var request = { version: "1.1.0", @@ -439,9 +436,14 @@ WifiGeoPositionProvider.prototype = { }, notify: function (timer) { - if (this.hasSeenWiFi == false) - this.onChange(null); - this.timer = null; + if (!gTestingEnabled) { + if (this.hasSeenWiFi == false) + this.onChange(null); + this.timer = null; + return; + } + // if we are testing, we need to hammer this. + this.onChange(null); }, }; diff --git a/dom/src/geolocation/nsGeolocation.cpp b/dom/src/geolocation/nsGeolocation.cpp index 00cd3af3d9d..f9d85710679 100644 --- a/dom/src/geolocation/nsGeolocation.cpp +++ b/dom/src/geolocation/nsGeolocation.cpp @@ -134,7 +134,6 @@ nsGeolocationRequest::nsGeolocationRequest(nsGeolocation* aLocator, nsIDOMGeoPositionOptions* aOptions) : mAllowed(PR_FALSE), mCleared(PR_FALSE), - mHasSentData(PR_FALSE), mCallback(aCallback), mErrorCallback(aErrorCallback), mOptions(aOptions), @@ -191,11 +190,9 @@ nsGeolocationRequest::Notify(nsITimer* aTimer) // provider yet, cancel the request. Same logic as // ::Cancel, just a different error - if (!mHasSentData) { - NotifyError(nsIDOMGeoPositionError::TIMEOUT); - // remove ourselves from the locator's callback lists. - mLocator->RemoveRequest(this); - } + NotifyError(nsIDOMGeoPositionError::TIMEOUT); + // remove ourselves from the locator's callback lists. + mLocator->RemoveRequest(this); mTimeoutTimer = nsnull; return NS_OK; @@ -277,6 +274,19 @@ nsGeolocationRequest::Allow() SendLocation(lastPosition); } + SetTimeoutTimer(); + + mAllowed = PR_TRUE; + return NS_OK; +} + +void +nsGeolocationRequest::SetTimeoutTimer() +{ + if (mTimeoutTimer) { + mTimeoutTimer->Cancel(); + mTimeoutTimer = nsnull; + } PRInt32 timeout; if (mOptions && NS_SUCCEEDED(mOptions->GetTimeout(&timeout)) && timeout > 0) { @@ -286,9 +296,6 @@ nsGeolocationRequest::Allow() mTimeoutTimer = do_CreateInstance("@mozilla.org/timer;1"); mTimeoutTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT); } - - mAllowed = PR_TRUE; - return NS_OK; } void @@ -303,6 +310,11 @@ nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition) if (mCleared || !mAllowed) return; + if (mTimeoutTimer) { + mTimeoutTimer->Cancel(); + mTimeoutTimer = nsnull; + } + // we should not pass null back to the DOM. if (!aPosition) { NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE); @@ -320,7 +332,7 @@ nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition) JSContext* cx; stack->Pop(&cx); - mHasSentData = PR_TRUE; + SetTimeoutTimer(); } void @@ -345,6 +357,8 @@ NS_IMPL_THREADSAFE_RELEASE(nsGeolocationService) static PRBool sGeoEnabled = PR_TRUE; +static PRBool sGeoIgnoreLocationFilter = PR_FALSE; + static int GeoEnabledChangedCallback(const char *aPrefName, void *aClosure) { @@ -476,7 +490,7 @@ nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere) PRBool nsGeolocationService::IsBetterPosition(nsIDOMGeoPosition *aSomewhere) -{ +{ if (!aSomewhere) return PR_FALSE; @@ -484,6 +498,9 @@ nsGeolocationService::IsBetterPosition(nsIDOMGeoPosition *aSomewhere) if (!geoService) return PR_FALSE; + if (sGeoIgnoreLocationFilter) + return PR_TRUE; + nsCOMPtr lastPosition = geoService->GetCachedPosition(); if (!lastPosition) return PR_TRUE; diff --git a/dom/src/geolocation/nsGeolocation.h b/dom/src/geolocation/nsGeolocation.h index aa9bd527b2a..9baa17f1f5b 100644 --- a/dom/src/geolocation/nsGeolocation.h +++ b/dom/src/geolocation/nsGeolocation.h @@ -80,6 +80,7 @@ class nsGeolocationRequest : public nsIGeolocationRequest, public nsITimerCallba void SendLocation(nsIDOMGeoPosition* location); void MarkCleared(); PRBool Allowed() {return mAllowed;} + void SetTimeoutTimer(); ~nsGeolocationRequest(); @@ -88,7 +89,6 @@ class nsGeolocationRequest : public nsIGeolocationRequest, public nsITimerCallba void NotifyError(PRInt16 errorCode); PRPackedBool mAllowed; PRPackedBool mCleared; - PRPackedBool mHasSentData; nsCOMPtr mTimeoutTimer; nsCOMPtr mCallback; diff --git a/dom/tests/mochitest/geolocation/Makefile.in b/dom/tests/mochitest/geolocation/Makefile.in index b4b9d98d9e5..687b9d2fefd 100644 --- a/dom/tests/mochitest/geolocation/Makefile.in +++ b/dom/tests/mochitest/geolocation/Makefile.in @@ -45,6 +45,7 @@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk _TEST_FILES = \ + test_timerRestartWatch.html \ test_manyCurrentSerial.html \ test_manyCurrentConcurrent.html \ test_garbageWatch.html \ diff --git a/dom/tests/mochitest/geolocation/test_timerRestartWatch.html b/dom/tests/mochitest/geolocation/test_timerRestartWatch.html new file mode 100644 index 00000000000..a715ee3cf24 --- /dev/null +++ b/dom/tests/mochitest/geolocation/test_timerRestartWatch.html @@ -0,0 +1,64 @@ + + + + + Test for watchPosition + + + + + + + +Mozilla Bug 526326 +

+ +
+
+
+ + +