Bug 489813 - Fire timeout error if provider fails to response after initial response. Also cleans up test. r=smaug a=jst
authorDoug Turner <dougt@dougt.org>
Tue, 31 Aug 2010 09:15:52 -0700
changeset 51780 0d8d6369655d6b16c11cbf97afa761890016634c
parent 51779 4edcf6c4cd03867862bc0aee95f5942acee29274
child 51781 ccf0c898b4c8b7cde3c0dbf7e234d199476fb801
push id15425
push userdougt@mozilla.com
push dateTue, 31 Aug 2010 16:58:55 +0000
treeherdermozilla-central@ccf0c898b4c8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, jst
bugs489813
milestone2.0b6pre
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 489813 - Fire timeout error if provider fails to response after initial response. Also cleans up test. r=smaug a=jst
build/automation.py.in
dom/src/geolocation/nsGeolocation.cpp
dom/src/geolocation/nsGeolocation.h
dom/system/GPSDGeolocationProvider.js
dom/system/NetworkGeolocationProvider.js
dom/tests/mochitest/chrome/test_geolocation.xul
dom/tests/mochitest/geolocation/Makefile.in
dom/tests/mochitest/geolocation/geolocation_common.js
dom/tests/mochitest/geolocation/test_allowCurrent.html
dom/tests/mochitest/geolocation/test_allowWatch.html
dom/tests/mochitest/geolocation/test_cancelCurrent.html
dom/tests/mochitest/geolocation/test_cancelWatch.html
dom/tests/mochitest/geolocation/test_clearWatch.html
dom/tests/mochitest/geolocation/test_clearWatch_invalid.html
dom/tests/mochitest/geolocation/test_garbageWatch.html
dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html
dom/tests/mochitest/geolocation/test_manyCurrentSerial.html
dom/tests/mochitest/geolocation/test_manyWatchConcurrent.html
dom/tests/mochitest/geolocation/test_manyWatchSerial.html
dom/tests/mochitest/geolocation/test_manyWindows.html
dom/tests/mochitest/geolocation/test_optional_api_params.html
dom/tests/mochitest/geolocation/test_timeoutWatch.html
dom/tests/mochitest/geolocation/test_timerRestartWatch.html
dom/tests/mochitest/geolocation/test_windowClose.html
dom/tests/mochitest/geolocation/windowTest.html
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -358,16 +358,17 @@ user_pref("app.update.enabled", false);
 // Only load extensions from the application and user profile
 // AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
 user_pref("extensions.enabledScopes", 5);
 
 user_pref("extensions.testpilot.runStudies", false);
 
 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.ignore.location_filter", 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.provider.0.gethashURL", "http://%(server)s/safebrowsing-dummy/gethash");
 user_pref("browser.safebrowsing.provider.0.keyURL", "http://%(server)s/safebrowsing-dummy/newkey");
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -66,16 +66,17 @@
 #include "nsServiceManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsIURI.h"
 #include "nsIPermissionManager.h"
 #include "nsIObserverService.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"
 #include "nsIJSContextStack.h"
+#include "nsThreadUtils.h"
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
 
 #include <math.h>
 
 #ifdef WINCE_WINDOWS_MOBILE
 #include "WinMobileLocationProvider.h"
 #endif
@@ -93,16 +94,85 @@
 
 // Some limit to the number of get or watch geolocation requests
 // that a window can make.
 #define MAX_GEO_REQUESTS_PER_WINDOW  1500
 
 using mozilla::unused;          // <snicker>
 using namespace mozilla::dom;
 
+class RequestPromptEvent : public nsRunnable
+{
+public:
+  RequestPromptEvent(nsGeolocationRequest* request)
+    : mRequest(request)
+  {
+  }
+
+  NS_IMETHOD Run() {
+    nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
+    NS_ASSERTION(prompt, "null geolocation prompt");
+    if (prompt) 
+      prompt->Prompt(mRequest);
+    return NS_OK;
+  }
+
+private:
+  nsRefPtr<nsGeolocationRequest> mRequest;
+};
+
+class RequestAllowEvent : public nsRunnable
+{
+public:
+  RequestAllowEvent(int allow, nsGeolocationRequest* request)
+    : mAllow(allow),
+      mRequest(request)
+  {
+  }
+
+  NS_IMETHOD Run() {
+    if (mAllow)
+      mRequest->Allow();
+    else
+      mRequest->Cancel();
+    return NS_OK;
+  }
+
+private:
+  PRBool mAllow;
+  nsRefPtr<nsGeolocationRequest> mRequest;
+};
+
+class RequestSendLocationEvent : public nsRunnable
+{
+public:
+  // a bit funky.  if locator is passed, that means this
+  // event should remove the request from it.  If we ever
+  // have to do more, then we can change this around.
+  RequestSendLocationEvent(nsIDOMGeoPosition* aPosition, nsGeolocationRequest* aRequest, nsGeolocation* aLocator = nsnull)
+    : mPosition(aPosition),
+      mRequest(aRequest),
+      mLocator(aLocator)
+  {
+  }
+
+  NS_IMETHOD Run() {
+    mRequest->SendLocation(mPosition);
+    if (mLocator)
+      mLocator->RemoveRequest(mRequest);
+    return NS_OK;
+  }
+
+private:
+  nsCOMPtr<nsIDOMGeoPosition>    mPosition;
+  nsRefPtr<nsGeolocationRequest> mRequest;
+
+  nsRefPtr<nsGeolocation>        mLocator;
+};
+
 ////////////////////////////////////////////////////
 // nsDOMGeoPositionError
 ////////////////////////////////////////////////////
 
 class nsDOMGeoPositionError : public nsIDOMGeoPositionError
 {
 public:
   NS_DECL_ISUPPORTS
@@ -165,17 +235,16 @@ nsDOMGeoPositionError::NotifyCallback(ns
 ////////////////////////////////////////////////////
 
 nsGeolocationRequest::nsGeolocationRequest(nsGeolocation* aLocator,
                                            nsIDOMGeoPositionCallback* aCallback,
                                            nsIDOMGeoPositionErrorCallback* aErrorCallback,
                                            nsIDOMGeoPositionOptions* aOptions)
   : mAllowed(PR_FALSE),
     mCleared(PR_FALSE),
-    mHasSentData(PR_FALSE),
     mCallback(aCallback),
     mErrorCallback(aErrorCallback),
     mOptions(aOptions),
     mLocator(aLocator)
 {
 }
 
 nsGeolocationRequest::~nsGeolocationRequest()
@@ -222,21 +291,19 @@ nsGeolocationRequest::NotifyError(PRInt1
 
 NS_IMETHODIMP
 nsGeolocationRequest::Notify(nsITimer* aTimer)
 {
   // If we haven't gotten an answer from the geolocation
   // 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;
 }
  
 NS_IMETHODIMP
 nsGeolocationRequest::GetRequestingURI(nsIURI * *aRequestingURI)
 {
@@ -314,46 +381,61 @@ nsGeolocationRequest::Allow()
   }
 
   if (lastPosition && maximumAge > 0 &&
       ( PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <=
         PRTime(cachedPositionTime) )) {
     // okay, we can return a cached position
     mAllowed = PR_TRUE;
     
-    // send the cached location
-    SendLocation(lastPosition);
+    nsCOMPtr<nsIRunnable> ev = new RequestSendLocationEvent(lastPosition, this, mLocator);
+    NS_DispatchToMainThread(ev);
   }
 
+  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) {
     
     if (timeout < 10)
       timeout = 10;
 
     mTimeoutTimer = do_CreateInstance("@mozilla.org/timer;1");
     mTimeoutTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT);
   }
-
-  mAllowed = PR_TRUE;
-  return NS_OK;
 }
 
 void
 nsGeolocationRequest::MarkCleared()
 {
   mCleared = PR_TRUE;
 }
 
 void
 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);
     return;
   }
 
   // Ensure that the proper context is on the stack (bug 452762)
   nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1"));
@@ -361,17 +443,17 @@ nsGeolocationRequest::SendLocation(nsIDO
     return; // silently fail
   
   mCallback->HandleEvent(aPosition);
 
   // remove the stack
   JSContext* cx;
   stack->Pop(&cx);
 
-  mHasSentData = PR_TRUE;
+  SetTimeoutTimer();
 }
 
 void
 nsGeolocationRequest::Shutdown()
 {
   mCleared = PR_TRUE;
   mCallback = nsnull;
   mErrorCallback = nsnull;
@@ -396,27 +478,45 @@ NS_INTERFACE_MAP_BEGIN(nsGeolocationServ
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_THREADSAFE_ADDREF(nsGeolocationService)
 NS_IMPL_THREADSAFE_RELEASE(nsGeolocationService)
 
 
 static PRBool sGeoEnabled = PR_TRUE;
+static PRBool sGeoIgnoreLocationFilter = PR_FALSE;
+
 static int
 GeoEnabledChangedCallback(const char *aPrefName, void *aClosure)
 {
   sGeoEnabled = nsContentUtils::GetBoolPref("geo.enabled", PR_TRUE);
   return 0;
 }
 
+static int
+GeoIgnoreLocationFilterChangedCallback(const char *aPrefName, void *aClosure)
+{
+  sGeoIgnoreLocationFilter = nsContentUtils::GetBoolPref("geo.ignore.location_filter",
+                                                         PR_TRUE);
+  return 0;
+}
+
+
 nsresult nsGeolocationService::Init()
 {
   mTimeout = nsContentUtils::GetIntPref("geo.timeout", 6000);
 
+  nsContentUtils::RegisterPrefCallback("geo.ignore.location_filter",
+                                       GeoIgnoreLocationFilterChangedCallback,
+                                       nsnull);
+
+  GeoIgnoreLocationFilterChangedCallback("geo.ignore.location_filter", nsnull);
+
+
   nsContentUtils::RegisterPrefCallback("geo.enabled",
                                        GeoEnabledChangedCallback,
                                        nsnull);
 
   GeoEnabledChangedCallback("geo.enabled", nsnull);
 
   if (!sGeoEnabled)
     return NS_ERROR_FAILURE;
@@ -766,17 +866,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   for (i = 0; i < tmp->mPendingCallbacks.Length(); ++i)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mPendingCallbacks[i], nsIGeolocationRequest)
 
   for (i = 0; i < tmp->mWatchingCallbacks.Length(); ++i)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWatchingCallbacks[i], nsIGeolocationRequest)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 nsGeolocation::nsGeolocation() 
-: mUpdateInProgress(PR_FALSE)
 {
 }
 
 nsGeolocation::~nsGeolocation()
 {
   if (mService)
     Shutdown();
 }
@@ -854,43 +953,31 @@ nsGeolocation::RemoveRequest(nsGeolocati
   // mark the request as "cleared".
 
   aRequest->MarkCleared();
 }
 
 void
 nsGeolocation::Update(nsIDOMGeoPosition *aSomewhere)
 {
-  // This method calls out to objects which may spin and
-  // event loop which may add new location objects into
-  // mPendingCallbacks, and mWatchingCallbacks.  Since this
-  // function can only be called on the primary thread, we
-  // can lock this method with a member var.
-
-  if (mUpdateInProgress)
-    return;
+  if (!WindowOwnerStillExists())
+    return Shutdown();
 
-  mUpdateInProgress = PR_TRUE;
-
-  if (!WindowOwnerStillExists())
-  {
-    Shutdown();
-    return;
+  for (PRUint32 i = 0; i< mPendingCallbacks.Length(); i++) {
+    nsCOMPtr<nsIRunnable> ev  = new RequestSendLocationEvent(aSomewhere,
+                                                             mPendingCallbacks[i]);
+    NS_DispatchToMainThread(ev);
   }
-
-  // notify anyone that has been waiting
-  for (PRUint32 i = 0; i< mPendingCallbacks.Length(); i++)
-    mPendingCallbacks[i]->SendLocation(aSomewhere);
   mPendingCallbacks.Clear();
 
   // notify everyone that is watching
-  for (PRUint32 i = 0; i< mWatchingCallbacks.Length(); i++)
-    mWatchingCallbacks[i]->SendLocation(aSomewhere);
-
-  mUpdateInProgress = PR_FALSE;
+  for (PRUint32 i = 0; i< mWatchingCallbacks.Length(); i++) {
+    nsCOMPtr<nsIRunnable> ev  = new RequestSendLocationEvent(aSomewhere, mWatchingCallbacks[i]);
+    NS_DispatchToMainThread(ev);
+  }
 }
 
 NS_IMETHODIMP
 nsGeolocation::GetCurrentPosition(nsIDOMGeoPositionCallback *callback,
                                   nsIDOMGeoPositionErrorCallback *errorCallback,
                                   nsIDOMGeoPositionOptions *options)
 {
   NS_ENSURE_ARG_POINTER(callback);
@@ -906,26 +993,26 @@ nsGeolocation::GetCurrentPosition(nsIDOM
     return NS_ERROR_OUT_OF_MEMORY;
 
   if (NS_FAILED(request->Init()))
     return NS_ERROR_FAILURE; // this as OKAY.  not sure why we wouldn't throw. xxx dft
 
   if (mOwner) {
     RegisterRequestWithPrompt(request);
     mPendingCallbacks.AppendElement(request);
-
     return NS_OK;
   }
 
   if (!nsContentUtils::IsCallerChrome())
     return NS_ERROR_FAILURE;
 
-  request->Allow();
+  mPendingCallbacks.AppendElement(request);
 
-  mPendingCallbacks.AppendElement(request);
+  nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(true, request);
+  NS_DispatchToMainThread(ev);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocation::WatchPosition(nsIDOMGeoPositionCallback *callback,
                              nsIDOMGeoPositionErrorCallback *errorCallback,
                              nsIDOMGeoPositionOptions *options,
@@ -1025,20 +1112,25 @@ nsGeolocation::RegisterRequestWithPrompt
     // Corresponding release occurs in DeallocPGeolocationRequest.
     request->AddRef();
 
     unused << request->Sendprompt();
     return;
   }
 #endif
 
-  nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
-  NS_ASSERTION(prompt, "null geolocation prompt.  geolocation will not work without one.");
-  if (prompt)
-    prompt->Prompt(request);
+  if (nsContentUtils::GetBoolPref("geo.prompt.testing", PR_FALSE))
+  {
+    nsCOMPtr<nsIRunnable> ev  = new RequestAllowEvent(nsContentUtils::GetBoolPref("geo.prompt.testing.allow", PR_FALSE), request);
+    NS_DispatchToMainThread(ev);
+    return;
+  }
+
+  nsCOMPtr<nsIRunnable> ev  = new RequestPromptEvent(request);
+  NS_DispatchToMainThread(ev);
 }
 
 #if !defined(WINCE_WINDOWS_MOBILE) && !defined(MOZ_MAEMO_LIBLOCATION) && !defined(ANDROID)
 DOMCI_DATA(GeoPositionCoords, void)
 DOMCI_DATA(GeoPosition, void)
 #endif
 
 #ifdef MOZ_IPC
--- a/dom/src/geolocation/nsGeolocation.h
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -89,29 +89,29 @@ class nsGeolocationRequest
                        nsIDOMGeoPositionErrorCallback* errorCallback,
                        nsIDOMGeoPositionOptions* options);
   nsresult Init();
   void Shutdown();
 
   void SendLocation(nsIDOMGeoPosition* location);
   void MarkCleared();
   PRBool Allowed() {return mAllowed;}
+  void SetTimeoutTimer();
 
   ~nsGeolocationRequest();
 
 #ifdef MOZ_IPC
   bool Recv__delete__(const bool& allow);
 #endif
 
  private:
 
   void NotifyError(PRInt16 errorCode);
   PRPackedBool mAllowed;
   PRPackedBool mCleared;
-  PRPackedBool mHasSentData;
 
   nsCOMPtr<nsITimer> mTimeoutTimer;
   nsCOMPtr<nsIDOMGeoPositionCallback> mCallback;
   nsCOMPtr<nsIDOMGeoPositionErrorCallback> mErrorCallback;
   nsCOMPtr<nsIDOMGeoPositionOptions> mOptions;
 
   nsRefPtr<nsGeolocation> mLocator;
 };
@@ -227,18 +227,16 @@ private:
   // Two callback arrays.  The first |mPendingCallbacks| holds objects for only
   // one callback and then they are released/removed from the array.  The second
   // |mWatchingCallbacks| holds objects until the object is explictly removed or
   // there is a page change.
 
   nsTArray<nsRefPtr<nsGeolocationRequest> > mPendingCallbacks;
   nsTArray<nsRefPtr<nsGeolocationRequest> > mWatchingCallbacks;
 
-  PRBool mUpdateInProgress;
-
   // window that this was created for.  Weak reference.
   nsWeakPtr mOwner;
 
   // where the content was loaded from
   nsCOMPtr<nsIURI> mURI;
 
   // owning back pointer.
   nsRefPtr<nsGeolocationService> mService;
--- a/dom/system/GPSDGeolocationProvider.js
+++ b/dom/system/GPSDGeolocationProvider.js
@@ -172,26 +172,27 @@ GPSDProvider.prototype = {
     LOG("shutdown called\n"); 
     this.outputStream.close();
     this.inputStream.close();
     this.transport.close(Components.results.NS_OK);
   },
   
   watch: function(c) {
     LOG("watch called\n");    
+    try {
+        // Turn GPSD buffer on, results in smoother data points which I think we want.
+        // Required due to the way that different data arrives in different NMEA sentences.
+        var bufferOption = "J=1\n";
+        this.outputStream.write(bufferOption, bufferOption.length);
+        
+        // Go into "watcher" mode
+        var mode = "w\n";
+        this.outputStream.write(mode, mode.length);
+    } catch (e) { return; }
 
-    // Turn GPSD buffer on, results in smoother data points which I think we want.
-    // Required due to the way that different data arrives in different NMEA sentences.
-    var bufferOption = "J=1\n";
-    this.outputStream.write(bufferOption, bufferOption.length);
-
-    // Go into "watcher" mode
-    var mode = "w\n";
-    this.outputStream.write(mode, mode.length);
-    
     var dataListener = {
       onStartRequest: function(request, context) {},
       onStopRequest: function(request, context, status) {},
       onDataAvailable: function(request, context, inputStream, offset, count) {
     
         var sInputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
         sInputStream.init(inputStream);
 
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -9,17 +9,17 @@ var gTestingEnabled = false;
 function nowInSeconds()
 {
     return Date.now() / 1000;
 }
 
 function LOG(aMsg) {
   if (gLoggingEnabled)
   {
-    aMsg = ("*** WIFI GEO: " + aMsg);
+    aMsg = "*** WIFI GEO: " + aMsg + "\n";
     Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(aMsg);
     dump(aMsg);
   }
 }
 
 function WifiGeoAddressObject(streetNumber, street, premises, city, county, region, country, countryCode, postalCode) {
 
   this.streetNumber = streetNumber;
@@ -222,35 +222,28 @@ function WifiGeoPositionProvider() {
 
 WifiGeoPositionProvider.prototype = {
     classID:          Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
     QueryInterface:   XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
                                              Ci.nsIWifiListener,
                                              Ci.nsITimerCallback]),
 
     prefService:     null,
-
-    provider_url:    null,
     wifi_service:    null,
     timer:           null,
-    protocol:        null,
     hasSeenWiFi:     false,
+    started:         false,
 
     startup:         function() {
-        LOG("startup called");
-
-        this.provider_url = this.prefService.getCharPref("geo.wifi.uri");
-        LOG("provider url = " + this.provider_url);
+        if (this.started == true)
+            return;
 
-        try {
-            this.protocol = this.prefService.getIntPref("geo.wifi.protocol");
-            LOG("protocol = " + this.protocol);
-        } catch (e) {
-            this.protocol = 0;
-        }
+        this.started = true;
+
+        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.hasSeenWiFi = false;
         this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
         if (gTestingEnabled == false)
             this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
         else
@@ -279,16 +272,18 @@ WifiGeoPositionProvider.prototype = {
         // Although we aren't using cookies, we should err on the side of not
         // saving any access tokens if the user asked us not to save cookies or
         // has changed the lifetimePolicy.  The access token in these cases is
         // used and valid for the life of this object (eg. between startup and
         // shutdown).e
         let prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
         if (prefBranch.getIntPref("network.cookie.lifetimePolicy") != 0)
             prefBranch.deleteBranch("geo.wifi.access_token.");
+
+        this.started = false;
     },
 
     getAccessTokenForURL: function(url)
     {
         // check to see if we have an access token:
         var accessToken = "";
         
         try {
@@ -303,59 +298,69 @@ WifiGeoPositionProvider.prototype = {
                 accessTokenInterval = this.prefService.getIntPref("geo.wifi.access_token.recycle_interval");
             } catch (e) {}
             
             if (nowInSeconds() - accessTokenDate > accessTokenInterval)
                 accessToken = "";
         }
         catch (e) {
             accessToken = "";
-            LOG("Error: "+ e);
         }
         return accessToken;
     },
 
     onChange: function(accessPoints) {
 
         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);
+        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");
+        var provider_protocol = 0;
+        try {
+            provider_protocol = this.prefService.getIntPref("geo.wifi.protocol");
+        } catch (e) {}
+
+        LOG("provider url = " + provider_url);
+
+        xhr.open("POST", provider_url, false);
         
         // set something so that we can strip cookies
         xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
             
         xhr.onerror = function(req) {
             LOG("onerror: " + req);
         };
 
         xhr.onload = function (req) {  
 
             LOG("xhr onload...");
 
-            // if we get a bad response, we will throw and never report a location
-            var response;
-            switch (protocol) {
-                case 1:
-                    LOG("service returned: " + req.target.responseXML);
-                    response = HELD.decode(req.target.responseXML);
-                    break;
-                case 0:
-                default:
-                    LOG("service returned: " + req.target.responseText);
-                    response = JSON.parse(req.target.responseText);
+            try { 
+                // if we get a bad response, we will throw and never report a location
+                var response;
+                switch (provider_protocol) {
+                    case 1:
+                        LOG("service returned: " + req.target.responseXML);
+                        response = HELD.decode(req.target.responseXML);
+                        break;
+                    case 0:
+                    default:
+                        LOG("service returned: " + req.target.responseText);
+                        response = JSON.parse(req.target.responseText);
+                }
+            } catch (e) {
+                LOG("Parse failed");
+                return;
             }
 
             // response looks something like:
             // {"location":{"latitude":51.5090332,"longitude":-0.1212726,"accuracy":150.0},"access_token":"2:jVhRZJ-j6PiRchH_:RGMrR0W1BiwdZs12"}
 
             // Check to see if we have a new access token
             var newAccessToken = response.access_token;
             if (newAccessToken != undefined)
@@ -388,17 +393,17 @@ WifiGeoPositionProvider.prototype = {
             LOG("sending update to geolocation.");
 
             var newLocation = new WifiGeoPositionObject(response.location, address);
 
             var update = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate);
             update.update(newLocation);
         };
 
-        var accessToken = this.getAccessTokenForURL(this.provider_url);
+        var accessToken = this.getAccessTokenForURL(provider_url);
 
         var request = {
             version: "1.1.0",
             request_address: true,
         };
 
         if (accessToken != "")
             request.access_token = accessToken;
@@ -409,17 +414,17 @@ WifiGeoPositionProvider.prototype = {
                     mac_address: ap.mac,
                         ssid: ap.ssid,
                         signal_strength: ap.signal
                         })
             request.wifi_towers = accessPoints.filter(filterBlankSSIDs).map(deconstruct);
         }
 
         var requestString;
-        switch (protocol) {
+        switch (provider_protocol) {
           case 1:
               requestString = HELD.encode(request);
               break;
           case 0:
           default:
               requestString = JSON.stringify(request);
         }
         LOG("client sending: " + requestString);
@@ -429,16 +434,21 @@ WifiGeoPositionProvider.prototype = {
         } catch (e) {}
     },
 
     onError: function (code) {
         LOG("wifi error: " + code);
     },
 
     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);
     },
 
 };
 
 var NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);
--- a/dom/tests/mochitest/chrome/test_geolocation.xul
+++ b/dom/tests/mochitest/chrome/test_geolocation.xul
@@ -19,21 +19,19 @@ const Cc = Components.classes;
 
 var geolocation = Cc["@mozilla.org/geolocation;1"].getService(Ci.nsIDOMGeoGeolocation);
 geolocation.getCurrentPosition(done, error);
 
 function error(error)
 {
   ok(0, "error occured trying to get geolocation from chrome");
   SimpleTest.finish();
-  newwindow.close();
 }
 function done(position)
 {
   ok(position, "geolocation was found from chrome");
   SimpleTest.finish();
-  newwindow.close();
 }
 </script>
 
 <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
 
 </window>
--- a/dom/tests/mochitest/geolocation/Makefile.in
+++ b/dom/tests/mochitest/geolocation/Makefile.in
@@ -40,36 +40,31 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir	= dom/tests/mochitest/geolocation
 
 include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES	= \
-		test_manyCurrentSerial.html \
+		test_allowCurrent.html \
+		test_allowWatch.html \
+		test_cancelCurrent.html \
+		test_cancelWatch.html \
+		test_clearWatch.html \
+		test_clearWatch_invalid.html \
 		test_manyCurrentConcurrent.html \
-		test_garbageWatch.html \
+		test_manyCurrentSerial.html \
 		test_manyWatchConcurrent.html \
 		test_manyWatchSerial.html \
 		test_manyWindows.html \
-		test_allowCurrent.html \
-		test_allowWatch.html \
-		test_clearWatch.html \
-		test_clearWatch_invalid.html \
-		test_timeoutWatch.html \
+		test_optional_api_params.html \
 		test_windowClose.html \
-		windowTest.html \
-		geolocation_common.js  \
+	        test_timerRestartWatch.html \
 		geolocation.html \
-		test_optional_api_params.html \
+		geolocation_common.js  \
 		network_geolocation.sjs \
+		windowTest.html \
 		$(NULL)
 
-ifndef MOZ_PHOENIX
-_TEST_FILES += test_cancelCurrent.html \
-               test_cancelWatch.html \
-               $(NULL)
-endif
-
 libs:: 	$(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
--- a/dom/tests/mochitest/geolocation/geolocation_common.js
+++ b/dom/tests/mochitest/geolocation/geolocation_common.js
@@ -1,29 +1,58 @@
+
+function sleep(delay)
+{
+    var start = Date.now();
+    while (Date.now() < start + delay);
+}
+
+function force_prompt(allow) {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+  prefs.setBoolPref("geo.prompt.testing", true);
+  prefs.setBoolPref("geo.prompt.testing.allow", allow);
+}
+
+function reset_prompt() {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+  prefs.setBoolPref("geo.prompt.testing", false);
+  prefs.setBoolPref("geo.prompt.testing.allow", false);
+}
 
 
 function start_sending_garbage()
 {
   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?action=respond-garbage");
+
+  // we need to be sure that all location data has been purged/set.
+  sleep(1000);
 }
 
 function stop_sending_garbage()
 {
   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");
+
+  // we need to be sure that all location data has been purged/set.
+  sleep(1000);
 }
 
 function stop_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?action=stop-responding");
+
+  // we need to be sure that all location data has been purged/set.
+  sleep(1000);
 }
 
 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");
 }
@@ -47,65 +76,9 @@ function check_geolocation(location) {
 
   // optional ok("heading" in coords, "Check to see if there is a heading");
   // optional ok("speed" in coords, "Check to see if there is a speed");
 
   ok (location.coords.latitude  == 37.41857, "lat matches known value");
   ok (location.coords.longitude == -122.08769, "lon matches known value");
   ok(location.coords.altitude == 42, "alt matches known value");
   ok(location.coords.altitudeAccuracy == 42, "alt acc matches known value");
-
 }
-
-
-function getChromeWindow()
-{
-  const Ci = Components.interfaces;
-  var chromeWin = window.top
-      .QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIWebNavigation)
-      .QueryInterface(Ci.nsIDocShellTreeItem)
-      .rootTreeItem
-      .QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIDOMWindow)
-      .QueryInterface(Ci.nsIDOMChromeWindow);
-  return chromeWin;
-}
-
-function getNotificationBox()
-{
-  var chromeWin = getChromeWindow();
-  var notifyBox = chromeWin.getNotificationBox(window.top);
-
-  return notifyBox;
-}
-
-function clickNotificationButton(aButtonIndex) {
-  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
-  // First, check for new-style Firefox notifications
-  var chromeWin = getChromeWindow();
-  if (chromeWin.PopupNotifications) {
-    var panel = chromeWin.PopupNotifications.panel;
-    var notificationEl = panel.getElementsByAttribute("id", "geolocation-notification")[0];
-    if (aButtonIndex == kAcceptButton)
-      notificationEl.button.doCommand();
-    else if (aButtonIndex == kDenyButton)
-      throw "clickNotificationButton(kDenyButton) isn't supported in Firefox";
-
-    return;
-  }
-
-  // Otherwise, fall back to looking for a notificationbox
-  // This is a bit of a hack. The notification doesn't have an API to
-  // trigger buttons, so we dive down into the implementation and twiddle
-  // the buttons directly.
-  var box = getNotificationBox();
-  ok(box, "Got notification box");
-  var bar = box.getNotificationWithValue("geolocation");
-  ok(bar, "Got geolocation notification");
-  var button = bar.getElementsByTagName("button").item(aButtonIndex);
-  ok(button, "Got button");
-  button.doCommand();
-}
-
-const kAcceptButton = 0;
-const kDenyButton = 1;
--- a/dom/tests/mochitest/geolocation/test_allowCurrent.html
+++ b/dom/tests/mochitest/geolocation/test_allowCurrent.html
@@ -15,37 +15,25 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478911">Mozilla Bug 478911</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-var hasAccepted = false;
+SimpleTest.waitForExplicitFinish();
+resume_geolocationProvider();
+force_prompt(true);
 
 function successCallback(position) {
-  ok(hasAccepted, "Ensure that accept was pressed");
   check_geolocation(position);
+  reset_prompt();
   SimpleTest.finish();
 }
 
-function accept() {
-  hasAccepted = true;
-  clickNotificationButton(kAcceptButton);
-}
-
-SimpleTest.waitForExplicitFinish();
-
-var options = {
-    maximumAge: 0,
-};
-
-// one-shot position requests
-navigator.geolocation.getCurrentPosition(successCallback, null, options);
-
-setTimeout(accept, 50);
+navigator.geolocation.getCurrentPosition(successCallback);
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_allowWatch.html
+++ b/dom/tests/mochitest/geolocation/test_allowWatch.html
@@ -15,38 +15,28 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478911">Mozilla Bug 478911</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);
+
 var watchID;
-var hasAccepted = false;
 
 function successCallback(position) {
-  ok(hasAccepted, "Ensure that accept was pressed");
   check_geolocation(position);
-
   navigator.geolocation.clearWatch(watchID);
-
+  reset_prompt();
   SimpleTest.finish();
 }
 
-function accept() {
-  hasAccepted = true;
-  clickNotificationButton(kAcceptButton);
-}
-
-/** Test for Bug  **/
-
-SimpleTest.waitForExplicitFinish();
-
 watchID = navigator.geolocation.watchPosition(successCallback, null, null);
 
-setTimeout(accept, 50);
-
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_cancelCurrent.html
+++ b/dom/tests/mochitest/geolocation/test_cancelCurrent.html
@@ -15,32 +15,31 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478911">Mozilla Bug 478911</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(false);
+
 function failureCallback(error) {
   ok(error.code == error.PERMISSION_DENIED, "Ensure that the error was PERMISSION_DENIED");
+  reset_prompt();
   SimpleTest.finish();
 }
 
 function successCallback(position){
   ok(0, "Success was called when it shouldn't have been.  major problem");
+  reset_prompt();
   SimpleTest.finish();
 }
 
-/** Test for Bug  **/
-
-SimpleTest.waitForExplicitFinish();
-
 navigator.geolocation.getCurrentPosition(successCallback, failureCallback, null);
 
-// click deny
-setTimeout(clickNotificationButton, 50, kDenyButton);
-
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_cancelWatch.html
+++ b/dom/tests/mochitest/geolocation/test_cancelWatch.html
@@ -15,36 +15,35 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478911">Mozilla Bug 478911</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(false);
+
 var watchID;
 
 function failureCallback(error) {
   ok(error.code == error.PERMISSION_DENIED, "Ensure that the error was PERMISSION_DENIED");
+  reset_prompt();
   SimpleTest.finish();
 }
 
 function successCallback(position){
   ok(0, "Success was called when it shouldn't have been.  major problem");
+  reset_prompt();
   SimpleTest.finish();
 }
 
-/** Test for Bug  **/
-
-SimpleTest.waitForExplicitFinish();
-
 watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
 
-// click deny
-setTimeout(clickNotificationButton, 50, kDenyButton);
-
 </script>
 </pre>
 </body>
 </html>
 
 
 
--- a/dom/tests/mochitest/geolocation/test_clearWatch.html
+++ b/dom/tests/mochitest/geolocation/test_clearWatch.html
@@ -15,49 +15,48 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478911">Mozilla Bug 478911</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-var watchID;
+SimpleTest.waitForExplicitFinish();
+resume_geolocationProvider();
+force_prompt(true)
+
 var hasBeenCleared = false;
+var successWasCalledAfterClear = false;
+
 function failureCallback(error)
 {
   ok(0, "we should not be seeing failures from this watchPosition");
 }
 
 function successCallback(position) {
   if (hasBeenCleared == true) {
-    // we should not be called here
-    ok(0, "successCallback was called after clear");
+    successWasCalledAfterClear = true;
   }
 }
 
 function clearWatch() {
   navigator.geolocation.clearWatch(watchID);
   hasBeenCleared = true;
 }
 
 function testAccepted() {
+  ok(!successWasCalledAfterClear, "The successCallback should not be called after clear");
+  reset_prompt();
   SimpleTest.finish();
 }
 
 
-/** Test for Bug  **/
-
-SimpleTest.waitForExplicitFinish();
-
 watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
 
-setTimeout(clickNotificationButton, 10, kAcceptButton);
+setTimeout(clearWatch, 250);
 
-setTimeout(clearWatch, 50);
-
-// wait for position changes
-setTimeout(testAccepted, 1000);
+setTimeout(testAccepted, 2000);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_clearWatch_invalid.html
+++ b/dom/tests/mochitest/geolocation/test_clearWatch_invalid.html
@@ -14,18 +14,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=463039">Mozilla Bug 463039</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-/** Test for Bug 463039 **/
-
 // there are no watches, so this should always throw
 for (x=-10; x<10; x++) {
     navigator.geolocation.clearWatch(x);
     ok(1, "clearWatch should not throw");
 }
 
 // lets try something huge
 navigator.geolocation.clearWatch(Number.MAX_VALUE);
--- a/dom/tests/mochitest/geolocation/test_garbageWatch.html
+++ b/dom/tests/mochitest/geolocation/test_garbageWatch.html
@@ -17,39 +17,41 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 /** Test for Bug  **/
 
 SimpleTest.waitForExplicitFinish();
+resume_geolocationProvider();
+force_prompt(true);
 
 start_sending_garbage();
 
 function successCallback(pos){
   ok(false, "success should have never been called.");
   stop_sending_garbage();
+  reset_prompt();
   SimpleTest.finish();
 }
 
 function errorCallback(err) {
   ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
   stop_sending_garbage();
+  reset_prompt();
   SimpleTest.finish();
 }
 
 
 var options = {
     maximumAge: 0,
     timeout: 1000,
 };
 
 navigator.geolocation.watchPosition(successCallback,
                                     errorCallback,
                                     options);
 
-setTimeout(clickNotificationButton, 10, kAcceptButton);
-
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html
+++ b/dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html
@@ -15,48 +15,33 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=482260">Mozilla Bug 482260</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-var completeCount = 100;
+SimpleTest.waitForExplicitFinish();
+resume_geolocationProvider();
+force_prompt(true);
 
-var hasAccepted = false;
-
+var successCallbackCalled = false;
 
 function successCallback(position) {
-  check_geolocation(position);
-}
-
-function accept() {
-  hasAccepted = true;
-  clickNotificationButton(kAcceptButton);
+  successCallbackCalled = true;
 }
 
-SimpleTest.waitForExplicitFinish();
-
-// one-shot position requests
-
-var options = {
-    maximumAge: 0,
-};
+for (var x = 0; x < 100; x++)
+  navigator.geolocation.getCurrentPosition(successCallback);
 
-var y = completeCount;
-for (var x=0; x< y; x++)
-  navigator.geolocation.getCurrentPosition(successCallback, null, options);
-
-setTimeout(accept, 50);
-setTimeout(done, 1000);
-
-function done() {
-  completeCount--;
-  ok(1, "Saw all successCallbacks");
+function testPassed() {
+  ok(successCallbackCalled, "if nothing crashed, all okay");
+  reset_prompt();
   SimpleTest.finish();
 }
+setTimeout(testPassed, 1000);
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_manyCurrentSerial.html
+++ b/dom/tests/mochitest/geolocation/test_manyCurrentSerial.html
@@ -15,41 +15,33 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=482260">Mozilla Bug 482260</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-var completeCount = 1000;
+SimpleTest.waitForExplicitFinish();
 
-var hasAccepted = false;
+resume_geolocationProvider();
+force_prompt(true)
+
+var keepGoing = 10;
 
 function successCallback(position) {
-  check_geolocation(position);
-  completeCount--;
-  if (completeCount > 0)   
-    navigator.geolocation.getCurrentPosition(successCallback, null, null);
+  if (keepGoing-- > 0) {
+    setTimeout(function() {navigator.geolocation.getCurrentPosition(successCallback);}, 0);
+    return; 
+  }
+
+  ok(1, "100 successful calls");
+  reset_prompt();
   SimpleTest.finish();
 }
 
-function accept() {
-  hasAccepted = true;
-  clickNotificationButton(kAcceptButton);
-}
-
-SimpleTest.waitForExplicitFinish();
-
-var options = {
-    maximumAge: 0,
-};
-
-// one-shot position requests
-navigator.geolocation.getCurrentPosition(successCallback, null, options);
-
-setTimeout(accept, 50);
+navigator.geolocation.getCurrentPosition(successCallback);
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_manyWatchConcurrent.html
+++ b/dom/tests/mochitest/geolocation/test_manyWatchConcurrent.html
@@ -15,47 +15,32 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=482260">Mozilla Bug 482260</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-var completeCount = 100;
+SimpleTest.waitForExplicitFinish();
+resume_geolocationProvider();
+force_prompt(true);
 
-var hasAccepted = false;
-
+var successCallbackCalled = false;
 
 function successCallback(position) {
-  check_geolocation(position);
-}
-
-function accept() {
-  hasAccepted = true;
-  clickNotificationButton(kAcceptButton);
+  successCallbackCalled = true;
 }
 
-SimpleTest.waitForExplicitFinish();
-
-// one-shot position requests
-
-var options = {
-    maximumAge: 0,
-};
+for (var x = 0; x < 100; x++)
+  navigator.geolocation.watchPosition(successCallback);
 
-var y = completeCount;
-for (var x=0; x< y; x++)
-  navigator.geolocation.watchPosition(successCallback, null, options);
-
-setTimeout(accept, 50);
-setTimeout(done, 1000);
-
-function done() {
-  completeCount--;
-  ok(1, "Saw all successCallbacks");
+function testPassed() {
+  ok(successCallbackCalled, "if nothing crashed, all okay");
+  reset_prompt();
   SimpleTest.finish();
 }
+setTimeout(testPassed, 1000);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_manyWatchSerial.html
+++ b/dom/tests/mochitest/geolocation/test_manyWatchSerial.html
@@ -15,48 +15,39 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=482260">Mozilla Bug 482260</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
-var hasAccepted = false;
+SimpleTest.waitForExplicitFinish();
+resume_geolocationProvider();
+force_prompt(true);
+
 var watchID = 0;
 var completeCount = 10;
 
-var options = {
-    maximumAge: 0,
-};
 
 function successCallback(position) {
-  check_geolocation(position);
 
   navigator.geolocation.clearWatch(watchID);
 
   completeCount--;
 
   if (completeCount==0) {
     ok(1, "all watchPosition successCallbacks called");
+    reset_prompt();
     SimpleTest.finish();
-  } else {
-    watchID = navigator.geolocation.watchPosition(successCallback, null, options);
-    setTimeout(accept, 50);
+    return;
   }
+
+  watchID = navigator.geolocation.watchPosition(successCallback);
 }
 
-function accept() {
-  hasAccepted = true;
-  clickNotificationButton(kAcceptButton);
-}
-
-SimpleTest.waitForExplicitFinish();
-
-// one-shot position requests
-watchID = navigator.geolocation.watchPosition(successCallback, null, options);
-setTimeout(accept, 50);
+watchID = navigator.geolocation.watchPosition(successCallback);
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/test_manyWindows.html
+++ b/dom/tests/mochitest/geolocation/test_manyWindows.html
@@ -16,16 +16,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 href="https://bugzilla.mozilla.org/show_bug.cgi?id=478911">Crash in Multiple Windows</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
+// ensure we are using the right testing provider
+resume_geolocationProvider();
+force_prompt(true);
+
 /** Test for Bug  **/
 
 var numberOfWindows = 5;  // 20 seems to be the default max popups during the mochitest run
 var totalWindows = numberOfWindows;
 
 var windows = new Array(numberOfWindows);
 
 for(var i = 0; i < numberOfWindows; i++) {
@@ -43,16 +47,17 @@ function closeWindows()
 SimpleTest.waitForExplicitFinish();
 
 function checkDone()
 {
     if (totalWindows == 0)
     {
         ok(navigator.geolocation, "Opened a bunch of windows and didn't crash.");
         clearInterval(timer);
+        reset_prompt();
         SimpleTest.finish();
     }
 }
 
 var timer = setInterval(checkDone, 1000);
 
 setTimeout(closeWindows, 5000);
 
--- a/dom/tests/mochitest/geolocation/test_optional_api_params.html
+++ b/dom/tests/mochitest/geolocation/test_optional_api_params.html
@@ -14,16 +14,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=452566">Mozilla Bug 452566</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
+// ensure we are using the right testing provider
+resume_geolocationProvider();
+force_prompt(true)
+
 /** Test for Bug 452566 **/
 
 const NOT_ENOUGH_ARGS = 2153185281;
 
 ok(navigator.geolocation, "Should have geolocation");
 
 var exception = null;
 try {
@@ -100,16 +104,15 @@ try {
   navigator.geolocation.watchPosition(function() {}, function() {}, {});
 } catch(ex) {
   if (ex.result == NOT_ENOUGH_ARGS) {
     exception = ex;
   }
 }
 ok(!exception, exception);
 
-// Successful calls trigger a geolocation notification,
 // so clean up ready for the next test.
-clickNotificationButton(kAcceptButton);
+reset_prompt();
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/geolocation/test_timeoutWatch.html
+++ b/dom/tests/mochitest/geolocation/test_timeoutWatch.html
@@ -16,43 +16,46 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 /** Test for Bug  **/
 
+// ensure we are using the right testing provider
+resume_geolocationProvider();
+force_prompt(true);
+
 SimpleTest.waitForExplicitFinish();
 
 stop_geolocationProvider();
 
 function successCallback(pos){
   ok(false, "success should have never been called.");
   resume_geolocationProvider();
+  reset_prompt()
   SimpleTest.finish();
 }
 
 function errorCallback(err) {
   if (err.code == err.POSITION_UNAVAILABLE)
     ok(false, "nothing is hooked up to test against.");
   else
     ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
   resume_geolocationProvider();
+  reset_prompt()
   SimpleTest.finish();
 }
 
 
 var options = {
     maximumAge: 0,
     timeout: 10
 };
 
 navigator.geolocation.watchPosition(successCallback,
                                     errorCallback,
                                     options);
-
-setTimeout(clickNotificationButton, 10, kAcceptButton);
-
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/geolocation/test_timerRestartWatch.html
@@ -0,0 +1,55 @@
+<!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">
+
+SimpleTest.waitForExplicitFinish();
+
+// ensure we are using the right testing provider
+resume_geolocationProvider();
+force_prompt(true);
+
+var watchID;
+
+function errorCallback(err) {
+  ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
+  resume_geolocationProvider();
+  reset_prompt();
+  SimpleTest.finish();
+}
+
+function successCallback(position) {
+  // Now that we got a success callback, lets try to ensure
+  // that we get a timeout error.
+  stop_geolocationProvider();
+}
+
+var options = {
+    maximumAge: 0,
+    timeout: 1000
+};
+
+watchID = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
+
+</script>
+</pre>
+</body>
+</html>
+
--- a/dom/tests/mochitest/geolocation/test_windowClose.html
+++ b/dom/tests/mochitest/geolocation/test_windowClose.html
@@ -16,20 +16,23 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 function done() {
+  ok(1, "no crash, so pass.");
   SimpleTest.finish();
+  reset_prompt();
 }
 
 SimpleTest.waitForExplicitFinish();
+force_prompt(true);
 
 window.open("windowTest.html");
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/tests/mochitest/geolocation/windowTest.html
+++ b/dom/tests/mochitest/geolocation/windowTest.html
@@ -21,20 +21,14 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="text/javascript">
 
 function successCallback(position) {
   var opener = window.opener;
   window.close();
   opener.done();
 }
 
-function accept() {
-  clickNotificationButton(kAcceptButton);
-}
-
 navigator.geolocation.watchPosition(successCallback, null, null);
-setTimeout(accept, 50);
-
 </script>
 </pre>
 </body>
 </html>