From c0e2188e07b9754075e5103951f23187d00af6a8 Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Fri, 5 Dec 2008 08:29:43 -0800 Subject: [PATCH] Bug 466493 Implement PositionOptions::maximumAge. r/sr=jst Bug 466494 Make geolocation mochitest use PositionError named values. r/sr=jst --- .../idl/geolocation/nsIDOMGeoGeolocation.idl | 4 +- .../geolocation/nsIDOMGeoPositionOptions.idl | 3 +- dom/src/geolocation/nsGeolocation.cpp | 55 +++++++++++++++---- dom/src/geolocation/nsGeolocation.h | 6 ++ dom/tests/mochitest/geolocation/Makefile.in | 1 - .../geolocation/test_allowWatch.html | 2 +- .../geolocation/test_cancelCurrent.html | 2 +- .../geolocation/test_cancelWatch.html | 2 +- .../geolocation/test_clearWatch.html | 2 +- .../geolocation/test_timeoutWatch.html | 4 +- 10 files changed, 60 insertions(+), 21 deletions(-) diff --git a/dom/public/idl/geolocation/nsIDOMGeoGeolocation.idl b/dom/public/idl/geolocation/nsIDOMGeoGeolocation.idl index 278a94e195b..b8c6d941b6e 100644 --- a/dom/public/idl/geolocation/nsIDOMGeoGeolocation.idl +++ b/dom/public/idl/geolocation/nsIDOMGeoGeolocation.idl @@ -41,11 +41,9 @@ interface nsIDOMGeoPositionOptions; interface nsIDOMGeoPositionCallback; interface nsIDOMGeoPositionErrorCallback; -[scriptable, function, uuid(0EC70F3F-7E15-45E0-84E9-CDE078CB150A)] +[scriptable, function, uuid(37687DAF-B85F-4E4D-8881-85A0AD24CF78)] interface nsIDOMGeoGeolocation : nsISupports { - readonly attribute nsIDOMGeoPosition lastPosition; - void getCurrentPosition(in nsIDOMGeoPositionCallback successCallback, [optional] in nsIDOMGeoPositionErrorCallback errorCallback, [optional] in nsIDOMGeoPositionOptions options); diff --git a/dom/public/idl/geolocation/nsIDOMGeoPositionOptions.idl b/dom/public/idl/geolocation/nsIDOMGeoPositionOptions.idl index d723a8b94af..4ca695ab283 100644 --- a/dom/public/idl/geolocation/nsIDOMGeoPositionOptions.idl +++ b/dom/public/idl/geolocation/nsIDOMGeoPositionOptions.idl @@ -37,9 +37,10 @@ #include "domstubs.idl" -[scriptable, uuid(74FA3BE6-4CBF-47C7-9BE1-FB9F17DD0D5D)] +[scriptable, uuid(19C44AAA-64E4-4D25-8C59-EEE7ADCEB709)] interface nsIDOMGeoPositionOptions : nsISupports { attribute boolean enableHighAccuracy; attribute unsigned long timeout; + attribute unsigned long maximumAge; }; diff --git a/dom/src/geolocation/nsGeolocation.cpp b/dom/src/geolocation/nsGeolocation.cpp index e3b8c122639..305ea707851 100644 --- a/dom/src/geolocation/nsGeolocation.cpp +++ b/dom/src/geolocation/nsGeolocation.cpp @@ -236,8 +236,30 @@ nsGeolocationRequest::Cancel() NS_IMETHODIMP nsGeolocationRequest::Allow() { - // Kick off the geo device, if it isn't already running nsRefPtr geoService = nsGeolocationService::GetInstance(); + + // check to see if we can use a cached value + PRUint32 maximumAge; + if (mOptions && NS_SUCCEEDED(mOptions->GetMaximumAge(&maximumAge)) && maximumAge != 0) { + nsCOMPtr lastPosition = geoService->GetCachedPosition(); + DOMTimeStamp cachedPositionTime; + lastPosition->GetTimestamp(&cachedPositionTime); + + if ( PR_Now() - (maximumAge * PR_MSEC_PER_SEC) >= cachedPositionTime ) + { + // okay, we can return a cached position + mAllowed = PR_TRUE; + + // send the cached location + SendLocation(lastPosition); + + // remove ourselves from the locators callback lists. + mLocator->RemoveRequest(this); + } + + } + + // Kick off the geo device, if it isn't already running nsresult rv = geoService->StartDevice(); if (NS_FAILED(rv)) { @@ -252,6 +274,7 @@ nsGeolocationRequest::Allow() mTimeoutTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT); } + mAllowed = PR_TRUE; return NS_OK; } @@ -379,6 +402,19 @@ nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere) return NS_OK; } + +void +nsGeolocationService::SetCachedPosition(nsIDOMGeoPosition* aPosition) +{ + mLastPosition = aPosition; +} + +nsIDOMGeoPosition* +nsGeolocationService::GetCachedPosition() +{ + return mLastPosition; +} + PRBool nsGeolocationService::HasGeolocationProvider() { @@ -563,6 +599,14 @@ nsGeolocation::Update(nsIDOMGeoPosition *aSomewhere) return; mUpdateInProgress = PR_TRUE; + + if (!aSomewhere) + { + nsRefPtr geoService = nsGeolocationService::GetInstance(); + geoService->SetCachedPosition(aSomewhere); + } + + if (!OwnerStillExists()) { Shutdown(); @@ -581,15 +625,6 @@ nsGeolocation::Update(nsIDOMGeoPosition *aSomewhere) mUpdateInProgress = PR_FALSE; } -NS_IMETHODIMP -nsGeolocation::GetLastPosition(nsIDOMGeoPosition * *aLastPosition) -{ - // we are advocating that this method be removed. - NS_ENSURE_ARG_POINTER(aLastPosition); - *aLastPosition = nsnull; - return NS_OK; -} - NS_IMETHODIMP nsGeolocation::GetCurrentPosition(nsIDOMGeoPositionCallback *callback, nsIDOMGeoPositionErrorCallback *errorCallback, diff --git a/dom/src/geolocation/nsGeolocation.h b/dom/src/geolocation/nsGeolocation.h index 1e3628ff61b..1ade038903e 100644 --- a/dom/src/geolocation/nsGeolocation.h +++ b/dom/src/geolocation/nsGeolocation.h @@ -114,6 +114,9 @@ public: void AddLocator(nsGeolocation* locator); void RemoveLocator(nsGeolocation* locator); + void SetCachedPosition(nsIDOMGeoPosition* aPosition); + nsIDOMGeoPosition* GetCachedPosition(); + // Returns true if there is a geolocation provider registered. PRBool HasGeolocationProvider(); @@ -148,6 +151,9 @@ private: // addes them to this list, and their destructor removes // them from this list. nsTArray mGeolocators; + + // This is the last geo position that we have seen. + nsCOMPtr mLastPosition; }; diff --git a/dom/tests/mochitest/geolocation/Makefile.in b/dom/tests/mochitest/geolocation/Makefile.in index 821da080306..14027195733 100644 --- a/dom/tests/mochitest/geolocation/Makefile.in +++ b/dom/tests/mochitest/geolocation/Makefile.in @@ -45,7 +45,6 @@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk _TEST_FILES = \ - test_lastPosition.html \ test_manyWindows.html \ test_allowCurrent.html \ test_allowWatch.html \ diff --git a/dom/tests/mochitest/geolocation/test_allowWatch.html b/dom/tests/mochitest/geolocation/test_allowWatch.html index 356e0a5ba2f..f81c0a9a0f1 100644 --- a/dom/tests/mochitest/geolocation/test_allowWatch.html +++ b/dom/tests/mochitest/geolocation/test_allowWatch.html @@ -27,7 +27,7 @@ var watchID = new Array(numCallbacks); function failureCallback(error) { - ok(error.code == 2, "Failure was something other than position unavailable"); + ok(error.code == error.POSITION_UNAVAILABLE, "Failure was something other than position unavailable"); removePrompt(); SimpleTest.finish(); } diff --git a/dom/tests/mochitest/geolocation/test_cancelCurrent.html b/dom/tests/mochitest/geolocation/test_cancelCurrent.html index 78022ea9871..d1a07317639 100644 --- a/dom/tests/mochitest/geolocation/test_cancelCurrent.html +++ b/dom/tests/mochitest/geolocation/test_cancelCurrent.html @@ -26,7 +26,7 @@ var callbackCounter = new Array(numCallbacks); function failureCallback(error) { - ok(error.code == 2, "Failure was something other than position unavailable"); + ok(error.code == error.POSITION_UNAVAILABLE, "Failure was something other than position unavailable"); removePrompt(); SimpleTest.finish(); } diff --git a/dom/tests/mochitest/geolocation/test_cancelWatch.html b/dom/tests/mochitest/geolocation/test_cancelWatch.html index a5170b00098..6d0e99976cb 100644 --- a/dom/tests/mochitest/geolocation/test_cancelWatch.html +++ b/dom/tests/mochitest/geolocation/test_cancelWatch.html @@ -27,7 +27,7 @@ var watchID = new Array(numCallbacks); function failureCallback(error) { - ok(error.code == 2, "Failure was something other than position unavailable"); + ok(error.code == error.POSITION_UNAVAILABLE, "Failure was something other than position unavailable"); removePrompt(); SimpleTest.finish(); } diff --git a/dom/tests/mochitest/geolocation/test_clearWatch.html b/dom/tests/mochitest/geolocation/test_clearWatch.html index f8f694198c4..fcf8713378b 100644 --- a/dom/tests/mochitest/geolocation/test_clearWatch.html +++ b/dom/tests/mochitest/geolocation/test_clearWatch.html @@ -27,7 +27,7 @@ var watchID = new Array(numCallbacks); function failureCallback(error) { - ok(error.code == 2, "Failure was something other than position unavailable"); + ok(error.code == error.POSITION_UNAVAILABLE, "Failure was something other than position unavailable"); removePrompt(); SimpleTest.finish(); } diff --git a/dom/tests/mochitest/geolocation/test_timeoutWatch.html b/dom/tests/mochitest/geolocation/test_timeoutWatch.html index 066e6cd2dd3..cc7e8dbe84d 100644 --- a/dom/tests/mochitest/geolocation/test_timeoutWatch.html +++ b/dom/tests/mochitest/geolocation/test_timeoutWatch.html @@ -38,13 +38,13 @@ function successCallback(pos){ function errorCallback(err) { removePrompt(); - if (err.code == 2) { + if (err.code == err.POSITION_UNAVAILABLE) { // nothing is hooked up to test against. SimpleTest.finish(); return; } - ok(err.code == 4, "ensure error is a timeout."); + ok(err.code == err.TIMEOUT, "ensure error is a timeout."); removePrompt(); SimpleTest.finish(); }