Bug 716127 - Test for overlapping geolocation provider shutdown and unfulfilled request. r=dougt
authorJosh Matthews <josh@joshmatthews.net>
Mon, 09 Jan 2012 15:27:43 -0500
changeset 85280 4998e366dd09a2f86f869fed2e522f5343727b9c
parent 85279 e8544d85984776b38f31f2c2fd0735e8d5a0b94c
child 85281 c7e4fd6cd6a46c2b5032255ba13975e2c3a82402
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougt
bugs716127
milestone12.0a1
Bug 716127 - Test for overlapping geolocation provider shutdown and unfulfilled request. r=dougt
dom/src/geolocation/nsGeolocation.cpp
dom/src/geolocation/nsGeolocation.h
dom/tests/mochitest/geolocation/Makefile.in
dom/tests/mochitest/geolocation/geolocation_common.js
dom/tests/mochitest/geolocation/network_geolocation.sjs
dom/tests/mochitest/geolocation/test_shutdown.html
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -503,46 +503,23 @@ NS_INTERFACE_MAP_BEGIN(nsGeolocationServ
 NS_INTERFACE_MAP_END
 
 NS_IMPL_THREADSAFE_ADDREF(nsGeolocationService)
 NS_IMPL_THREADSAFE_RELEASE(nsGeolocationService)
 
 
 static bool sGeoEnabled = true;
 static bool sGeoIgnoreLocationFilter = false;
-
-static int
-GeoEnabledChangedCallback(const char *aPrefName, void *aClosure)
-{
-  sGeoEnabled = Preferences::GetBool("geo.enabled", true);
-  return 0;
-}
-
-static int
-GeoIgnoreLocationFilterChangedCallback(const char *aPrefName, void *aClosure)
-{
-  sGeoIgnoreLocationFilter =
-    Preferences::GetBool("geo.ignore.location_filter", true);
-  return 0;
-}
-
+static PRInt32 sProviderTimeout = 6000; // Time, in milliseconds, to wait for the location provider to spin up.
 
 nsresult nsGeolocationService::Init()
 {
-  mTimeout = Preferences::GetInt("geo.timeout", 6000);
-
-  Preferences::RegisterCallback(GeoIgnoreLocationFilterChangedCallback,
-                                "geo.ignore.location_filter");
-
-  GeoIgnoreLocationFilterChangedCallback("geo.ignore.location_filter", nsnull);
-
-
-  Preferences::RegisterCallback(GeoEnabledChangedCallback, "geo.enabled");
-
-  GeoEnabledChangedCallback("geo.enabled", nsnull);
+  Preferences::AddIntVarCache(&sProviderTimeout, "geo.timeout", sProviderTimeout);
+  Preferences::AddBoolVarCache(&sGeoEnabled, "geo.enabled", sGeoEnabled);
+  Preferences::AddBoolVarCache(&sGeoIgnoreLocationFilter, "geo.ignore.location_filter", sGeoIgnoreLocationFilter);
 
   if (!sGeoEnabled)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIGeolocationProvider> provider = do_GetService(NS_GEOLOCATION_PROVIDER_CONTRACTID);
   if (provider)
     mProviders.AppendObject(provider);
 
@@ -705,17 +682,17 @@ void
 nsGeolocationService::SetDisconnectTimer()
 {
   if (!mDisconnectTimer)
     mDisconnectTimer = do_CreateInstance("@mozilla.org/timer;1");
   else
     mDisconnectTimer->Cancel();
 
   mDisconnectTimer->Init(this,
-                         mTimeout,
+                         sProviderTimeout,
                          nsITimer::TYPE_ONE_SHOT);
 }
 
 void 
 nsGeolocationService::StopDevice()
 {
   if(mDisconnectTimer) {
     mDisconnectTimer->Cancel();
--- a/dom/src/geolocation/nsGeolocation.h
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -129,17 +129,17 @@ public:
   static nsGeolocationService* GetGeolocationService();
   static nsGeolocationService* GetInstance();  // Non-Addref'ing
   static nsGeolocationService* gService;
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIGEOLOCATIONUPDATE
   NS_DECL_NSIOBSERVER
 
-  nsGeolocationService() {mTimeout = 6000;};
+  nsGeolocationService() {}
 
   nsresult Init();
 
   // Management of the nsGeolocation objects
   void AddLocator(nsGeolocation* locator);
   void RemoveLocator(nsGeolocation* locator);
 
   void SetCachedPosition(nsIDOMGeoPosition* aPosition);
@@ -158,19 +158,16 @@ private:
 
   ~nsGeolocationService();
 
   // Disconnect timer.  When this timer expires, it clears all pending callbacks
   // and closes down the provider, unless we are watching a point, and in that
   // case, we disable the disconnect timer.
   nsCOMPtr<nsITimer> mDisconnectTimer;
 
-  // Time, in milliseconds, to wait for the location provider to spin up.
-  PRInt32 mTimeout;
-
   // The object providing geo location information to us.
   nsCOMArray<nsIGeolocationProvider> mProviders;
 
   // mGeolocators are not owned here.  Their constructor
   // adds them to this list, and their destructor removes
   // them from this list.
   nsTArray<nsGeolocation*> mGeolocators;
 
--- a/dom/tests/mochitest/geolocation/Makefile.in
+++ b/dom/tests/mochitest/geolocation/Makefile.in
@@ -52,16 +52,17 @@ include $(topsrcdir)/config/rules.mk
 		test_clearWatch.html \
 		test_clearWatch_invalid.html \
 		test_manyCurrentConcurrent.html \
 		test_manyCurrentSerial.html \
 		test_manyWatchConcurrent.html \
 		test_manyWatchSerial.html \
 		test_manyWindows.html \
 		test_optional_api_params.html \
+		test_shutdown.html \
 		test_windowClose.html \
 		test_timerRestartWatch.html \
 		test_worseAccuracyDoesNotBlockCallback.html \
 		geolocation.html \
 		geolocation_common.js  \
 		network_geolocation.sjs \
 		windowTest.html \
 		$(NULL)
--- a/dom/tests/mochitest/geolocation/geolocation_common.js
+++ b/dom/tests/mochitest/geolocation/geolocation_common.js
@@ -59,16 +59,23 @@ function worse_geolocationProvider()
 
 function resume_geolocationProvider()
 {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
   prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
 }
 
+function delay_geolocationProvider(delay)
+{
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+  prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay);
+}
+
 function check_geolocation(location) {
 
   ok(location, "Check to see if this location is non-null");
 
   ok("timestamp" in location, "Check to see if there is a timestamp");
 
   // eventually, coords may be optional (eg, when civic addresses are supported)
   ok("coords" in location, "Check to see if this location has a coords");
--- a/dom/tests/mochitest/geolocation/network_geolocation.sjs
+++ b/dom/tests/mochitest/geolocation/network_geolocation.sjs
@@ -26,16 +26,17 @@ function getPosition(action)
       lng: -122.08769,
     },
     accuracy: (action == "worse-accuracy") ? 100 : 42,
   };
   
   return JSON.stringify(response);
 }
 
+var timer;
 function handleRequest(request, response)
 {
   var params = parseQueryString(request.queryString);
 
   if (params.action == "stop-responding") {
       return;
   }
 
@@ -49,14 +50,24 @@ function handleRequest(request, response
 
     for (var i=0; i< len; i++) {
         var c = Math.floor(Math.random() * chars.length);
         position += chars.substring(c, c+1);
     }
   }
 
   var response;
+  response.processAsync();
   response.setStatusLine("1.0", 200, "OK");
   response.setHeader("Cache-Control", "no-cache", false);
   response.setHeader("Content-Type", "aplication/x-javascript", false);
-  response.write(position);
+
+  var delay = 0;
+  if ('delay' in params) {
+    delay = params.delay;
+  }
+  timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
+  timer.initWithCallback(function() {
+    response.write(position);
+    response.finish();
+  }, delay, timer.TYPE_ONE_SHOT);
 }
 
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/geolocation/test_shutdown.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=716127
+-->
+<head>
+  <title>Test for getCurrentPosition </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=716127">Mozilla Bug 716127</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();
+force_prompt(true);
+
+function successCallback(position) {
+  check_geolocation(position);
+
+  SpecialPowers.pushPrefEnv({'set': [['geo.timeout', 100]]}, function() {
+      delay_geolocationProvider(1000);
+      force_prompt(true);
+      navigator.geolocation.getCurrentPosition(success2, handle_error, {maximumAge: 0});
+  });
+}
+
+function errorCallback() {
+  ok(false, "unexpected error");
+  SimpleTest.finish();
+}
+
+navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
+
+function success2(position) {
+  check_geolocation(position);
+  reset_prompt();
+  SimpleTest.finish();
+}
+
+function handle_error() {
+  ok(false, "geolocation provider should not have timed out");
+  SimpleTest.finish();
+}
+</script>
+</pre>
+</body>
+</html>
+