Bug 645325 - Part 4: Handle null listener when xhr callbacks are called after WifiGeoPositionProvider shutdown. r=garvank r?jdm
I hit this error when testing geolocation with Wi-Fi disabled. There is a race where the WifiGeoPositionProvider gets shut down (settting this.listener to null) but the xhr request is still alive (and the xhr callback later hits the null this.listener).
MozReview-Commit-ID: E3jCFM3om5A
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -378,45 +378,53 @@ WifiGeoPositionProvider.prototype = {
let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
LOG("Sending request");
let xhr = new XMLHttpRequest();
try {
xhr.open("POST", url, true);
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
} catch (e) {
- this.listener.notifyError(POSITION_UNAVAILABLE);
+ notifyPositionUnavailable(this.listener);
return;
}
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
xhr.responseType = "json";
xhr.mozBackgroundRequest = true;
xhr.timeout = Services.prefs.getIntPref("geo.wifi.xhr.timeout");
xhr.ontimeout = () => {
LOG("Location request XHR timed out.")
- this.listener.notifyError(POSITION_UNAVAILABLE);
+ notifyPositionUnavailable(this.listener);
};
xhr.onerror = () => {
- this.listener.notifyError(POSITION_UNAVAILABLE);
+ notifyPositionUnavailable(this.listener);
};
xhr.onload = () => {
LOG("server returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response));
if ((xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) ||
!xhr.response || !xhr.response.location) {
- this.listener.notifyError(POSITION_UNAVAILABLE);
+ notifyPositionUnavailable(this.listener);
return;
}
let newLocation = new WifiGeoPositionObject(xhr.response.location.lat,
xhr.response.location.lng,
xhr.response.accuracy);
- this.listener.update(newLocation);
+ if (this.listener) {
+ this.listener.update(newLocation);
+ }
gCachedRequest = new CachedRequest(newLocation, data.cellTowers, data.wifiAccessPoints);
};
var requestData = JSON.stringify(data);
LOG("sending " + requestData);
xhr.send(requestData);
+
+ function notifyPositionUnavailable(listener) {
+ if (listener) {
+ listener.notifyError(POSITION_UNAVAILABLE);
+ }
+ }
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);