diff --git a/dom/src/geolocation/nsGeolocation.cpp b/dom/src/geolocation/nsGeolocation.cpp index 4068f9a146e..527f352eae5 100644 --- a/dom/src/geolocation/nsGeolocation.cpp +++ b/dom/src/geolocation/nsGeolocation.cpp @@ -431,32 +431,28 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices) return NS_OK; } - nsCOMPtr lastPosition = gs->GetCachedPosition(); - DOMTimeStamp cachedPositionTime; - if (lastPosition) { - lastPosition->GetTimestamp(&cachedPositionTime); - } - - // check to see if we can use a cached value - // if the user has specified a maximumAge, return a cached value. - - uint32_t maximumAge = 0; - if (mOptions) { - if (mOptions->mMaximumAge > 0) { - maximumAge = mOptions->mMaximumAge; + bool canUseCache = false; + CachedPositionAndAccuracy lastPosition = gs->GetCachedPosition(); + if (lastPosition.position) { + DOMTimeStamp cachedPositionTime_ms; + lastPosition.position->GetTimestamp(&cachedPositionTime_ms); + // check to see if we can use a cached value + // if the user has specified a maximumAge, return a cached value. + if (mOptions && mOptions->mMaximumAge > 0) { + uint32_t maximumAge_ms = mOptions->mMaximumAge; + bool isCachedWithinRequestedAccuracy = WantsHighAccuracy() <= lastPosition.isHighAccuracy; + bool isCachedWithinRequestedTime = + DOMTimeStamp(PR_Now() / PR_USEC_PER_MSEC - maximumAge_ms) <= cachedPositionTime_ms; + canUseCache = isCachedWithinRequestedAccuracy && isCachedWithinRequestedTime; } } + gs->UpdateAccuracy(WantsHighAccuracy()); - - bool canUseCache = lastPosition && maximumAge > 0 && - (PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <= - PRTime(cachedPositionTime)); - if (canUseCache) { // okay, we can return a cached position // getCurrentPosition requests serviced by the cache // will now be owned by the RequestSendLocationEvent - Update(lastPosition); + Update(lastPosition.position); } if (mIsWatchPositionRequest || !canUseCache) { @@ -764,7 +760,7 @@ nsGeolocationService::HandleMozsettingValue(const bool aValue) // turn things off StopDevice(); Update(nullptr); - mLastPosition = nullptr; + mLastPosition.position = nullptr; sGeoEnabled = false; } else { sGeoEnabled = true; @@ -854,10 +850,11 @@ nsGeolocationService::NotifyError(uint16_t aErrorCode) void nsGeolocationService::SetCachedPosition(nsIDOMGeoPosition* aPosition) { - mLastPosition = aPosition; + mLastPosition.position = aPosition; + mLastPosition.isHighAccuracy = mHigherAccuracy; } -nsIDOMGeoPosition* +CachedPositionAndAccuracy nsGeolocationService::GetCachedPosition() { return mLastPosition; diff --git a/dom/src/geolocation/nsGeolocation.h b/dom/src/geolocation/nsGeolocation.h index 638c5253f93..71c3a3aac99 100644 --- a/dom/src/geolocation/nsGeolocation.h +++ b/dom/src/geolocation/nsGeolocation.h @@ -45,6 +45,11 @@ typedef CallbackObjectHolder position; + bool isHighAccuracy; +}; + /** * Singleton that manages the geolocation provider */ @@ -73,7 +78,7 @@ public: void RemoveLocator(mozilla::dom::Geolocation* locator); void SetCachedPosition(nsIDOMGeoPosition* aPosition); - nsIDOMGeoPosition* GetCachedPosition(); + CachedPositionAndAccuracy GetCachedPosition(); // Find and startup a geolocation device (gps, nmea, etc.) nsresult StartDevice(nsIPrincipal* aPrincipal); @@ -106,7 +111,7 @@ private: nsTArray mGeolocators; // This is the last geo position that we have seen. - nsCOMPtr mLastPosition; + CachedPositionAndAccuracy mLastPosition; // Current state of requests for higher accuracy bool mHigherAccuracy;