Bug 978593 - refactor and cleanup NetworkLocationProvider. Prep work to enable celluar support. r=jdm
authorDoug Turner <doug.turner@gmail.com>
Sat, 01 Mar 2014 23:46:02 -0800
changeset 190894 1cee27f0547d7929e93d31fb844959b765f4408d
parent 190893 9cfebec86c16c1f84cc3667bde8dd87eec0fd71f
child 190905 fc9947c00b51182fbf095fa4f3d90384152e86bb
child 190906 b91e62bdacba2d2cd00f2988a9a6673627a8c6d4
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs978593
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 978593 - refactor and cleanup NetworkLocationProvider. Prep work to enable celluar support. r=jdm
dom/system/NetworkGeolocationProvider.js
testing/profiles/prefs_general.js
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -5,23 +5,28 @@
 // See https://developers.google.com/maps/documentation/business/geolocation/
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 
+const POSITION_UNAVAILABLE = Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE;
+
 let gLoggingEnabled = false;
-let gTestingEnabled = false;
-let gUseScanning = true;
+
+// if we don't see any wifi responses in 5 seconds, send the request.
+let gTimeToWaitBeforeSending = 5000; //ms
+
+let gWifiScanningEnabled = true;
+let gWifiResults;
 
 function LOG(aMsg) {
-  if (gLoggingEnabled)
-  {
+  if (gLoggingEnabled) {
     aMsg = "*** WIFI GEO: " + aMsg + "\n";
     Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(aMsg);
     dump(aMsg);
   }
 }
 
 function WifiGeoCoordsObject(lat, lon, acc, alt, altacc) {
   this.latitude = lat;
@@ -57,185 +62,143 @@ WifiGeoPositionObject.prototype = {
 };
 
 function WifiGeoPositionProvider() {
   try {
     gLoggingEnabled = Services.prefs.getBoolPref("geo.wifi.logging.enabled");
   } catch (e) {}
 
   try {
-    gTestingEnabled = Services.prefs.getBoolPref("geo.wifi.testing");
+    gTimeToWaitBeforeSending = Services.prefs.getIntPref("geo.wifi.timeToWaitBeforeSending");
   } catch (e) {}
 
   try {
-    gUseScanning = Services.prefs.getBoolPref("geo.wifi.scan");
+    gWifiScanningEnabled = Services.prefs.getBoolPref("geo.wifi.scan");
   } catch (e) {}
 
   this.wifiService = null;
-  this.timer = null;
-  this.hasSeenWiFi = false;
+  this.timeoutTimer = null;
   this.started = false;
-  // this is only used when logging is enabled, to debug interactions with the
-  // geolocation service
-  this.highAccuracy = false;
 }
 
 WifiGeoPositionProvider.prototype = {
   classID:          Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
   QueryInterface:   XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
                                            Ci.nsIWifiListener,
                                            Ci.nsITimerCallback]),
   startup:  function() {
     if (this.started)
       return;
     this.started = true;
-    this.hasSeenWiFi = false;
 
-    LOG("startup called.  testing mode is" + gTestingEnabled);
-
-    // 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.
-    this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    if (!gTestingEnabled)
-      this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
-    else
-      this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK);
+    if (gWifiScanningEnabled) {
+      this.wifiService = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
+      this.wifiService.startWatching(this);
+    }
+    this.timeoutTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+    this.timeoutTimer.initWithCallback(this,
+                                       gTimeToWaitBeforeSending,
+                                       this.timeoutTimer.TYPE_REPEATING_SLACK);
+    LOG("startup called.");
   },
 
   watch: function(c) {
-    LOG("watch called");
-
-    if (!this.wifiService && gUseScanning) {
-      this.wifiService = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
-      this.wifiService.startWatching(this);
-    }
-    if (this.hasSeenWiFi) {
-      this.hasSeenWiFi = false;
-      if (gUseScanning) {
-        this.wifiService.stopWatching(this);
-        this.wifiService.startWatching(this);
-      } else {
-        // For testing situations, ensure that we always trigger an update.
-        this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
-      }
-    }
   },
 
-  shutdown: function() { 
+  shutdown: function() {
     LOG("shutdown called");
+    if (this.started == false) {
+      return;
+    }
+
+    if (this.timeoutTimer) {
+      this.timeoutTimer.cancel();
+      this.timeoutTimer = null;
+    }
+
     if(this.wifiService) {
       this.wifiService.stopWatching(this);
       this.wifiService = null;
     }
-    if (this.timer != null) {
-      this.timer.cancel();
-      this.timer = null;
-    }
-
     this.started = false;
   },
 
   setHighAccuracy: function(enable) {
-    this.highAccuracy = enable;
-    LOG("setting highAccuracy to " + (this.highAccuracy?"TRUE":"FALSE"));
   },
 
   onChange: function(accessPoints) {
-    LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE"));
-    this.hasSeenWiFi = true;
-
-    Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
-        .locationUpdatePending();
-
-    let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
 
     function isPublic(ap) {
-        let mask = "_nomap"
-        let result = ap.ssid.indexOf(mask, ap.ssid.length - mask.length);
-        if (result != -1) {
-            LOG("Filtering out " + ap.ssid + " " + result);
-        }
-        return result;
+      let mask = "_nomap"
+      let result = ap.ssid.indexOf(mask, ap.ssid.length - mask.length);
+      if (result != -1) {
+        LOG("Filtering out " + ap.ssid + " " + result);
+      }
+      return result;
     };
 
     function sort(a, b) {
       return b.signal - a.signal;
     };
 
     function encode(ap) {
-      return { 'macAddress': ap.mac, 'signalStrength': ap.signal }; 
+      return { 'macAddress': ap.mac, 'signalStrength': ap.signal };
     };
 
     var data;
     if (accessPoints) {
-        data = JSON.stringify({wifiAccessPoints: accessPoints.filter(isPublic).sort(sort).map(encode)})
+      data = JSON.stringify({wifiAccessPoints: accessPoints.filter(isPublic).sort(sort).map(encode)})
     }
+    gWifiResults = data;
+  },
 
-    LOG("************************************* Sending request:\n" + url + "\n");
+  onError: function (code) {
+    LOG("wifi error: " + code);
+  },
 
-    // send our request to a wifi geolocation network provider:
+  notify: function (timeoutTimer) {
+    let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
+    LOG("Sending request: " + url + "\n");
+
     let xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                         .createInstance(Ci.nsIXMLHttpRequest);
 
-    // This is a background load
-  
+    getGeoService().locationUpdatePending();
+
     try {
-        xhr.open("POST", url, true);
+      xhr.open("POST", url, true);
     } catch (e) {
-       triggerError();
-       return;
+      getGeoService().notifyError(POSITION_UNAVAILABLE);
+      return;
     }
     xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
     xhr.responseType = "json";
     xhr.mozBackgroundRequest = true;
     xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
     xhr.onerror = function() {
-        LOG("onerror: " + xhr);
-        triggerError();
+      getGeoService().notifyError(POSITION_UNAVAILABLE);
+    };
+    xhr.onload = function() {
+      LOG("gls returned status: " + xhr.status + " --> " +  JSON.stringify(xhr.response));
+      if ((xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) ||
+          !xhr.response || !xhr.response.location) {
+        getGeoService().notifyError(POSITION_UNAVAILABLE);
+        return;
+      }
+
+      let newLocation = new WifiGeoPositionObject(xhr.response.location.lat,
+                                                  xhr.response.location.lng,
+                                                  xhr.response.accuracy);
+
+      getGeoService().update(newLocation);
     };
 
-    xhr.onload = function() {  
-        LOG("gls returned status: " + xhr.status + " --> " +  JSON.stringify(xhr.response));
-        if (xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) {
-            triggerError();
-            return;
-        }
-
-        if (!xhr.response || !xhr.response.location) {
-            triggerError();
-            return;
-        }
-
-        let newLocation = new WifiGeoPositionObject(xhr.response.location.lat,
-                                                    xhr.response.location.lng,
-                                                    xhr.response.accuracy);
-        
-        Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
-            .update(newLocation);
-    };
-
-    LOG("************************************* ------>>>> sending " + data);
+    let data = gWifiResults;
+    LOG("sending " + data);
     xhr.send(data);
   },
-
-  onError: function (code) {
-    LOG("wifi error: " + code);
-  },
-
-  notify: function (timer) {
-    if (gTestingEnabled || !gUseScanning) {
-      // if we are testing, timer is repeating
-      this.onChange(null);
-    }
-    else {
-      if (!this.hasSeenWiFi)
-        this.onChange(null);
-      this.timer = null;
-    }
-  },
 };
 
-function triggerError() {
-    Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
-        .notifyError(Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE);
+function getGeoService() {
+  return Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate);
 }
+
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -56,17 +56,18 @@ user_pref("extensions.enabledScopes", 5)
 // Disable metadata caching for installed add-ons by default
 user_pref("extensions.getAddons.cache.enabled", false);
 // Disable intalling any distribution add-ons
 user_pref("extensions.installDistroAddons", false);
 // XPI extensions are required for test harnesses to load
 user_pref("extensions.defaultProviders.enabled", true);
 
 user_pref("geo.wifi.uri", "http://%(server)s/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
-user_pref("geo.wifi.testing", true);
+user_pref("geo.wifi.timeToWaitBeforeSending", 200);
+user_pref("geo.wifi.scan", false);
 user_pref("geo.wifi.logging.enabled", true);
 
 user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others
 
 // Make url-classifier updates so rare that they won't affect tests
 user_pref("urlclassifier.updateinterval", 172800);
 // Point the url-classifier to the local testing server for fast failures
 user_pref("browser.safebrowsing.gethashURL", "http://%(server)s/safebrowsing-dummy/gethash");