summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/page/Geolocation.cpp52
-rw-r--r--WebCore/page/Geolocation.h11
2 files changed, 40 insertions, 23 deletions
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index 7fa3a6d..aaf164d 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -56,9 +56,9 @@ void Geolocation::GeoNotifier::setFatalError(PassRefPtr<PositionError> error)
m_timer.startOneShot(0);
}
-void Geolocation::GeoNotifier::startTimer()
+void Geolocation::GeoNotifier::startTimerIfNeeded()
{
- if (m_errorCallback && m_options->hasTimeout())
+ if (m_options->hasTimeout())
m_timer.startOneShot(m_options->timeout() / 1000.0);
}
@@ -75,8 +75,11 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
return;
}
- RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timed out");
- m_errorCallback->handleEvent(error.get());
+ if (m_errorCallback) {
+ RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timed out");
+ m_errorCallback->handleEvent(error.get());
+ }
+ m_geolocation->requestTimedOut(this);
}
Geolocation::Geolocation(Frame* frame)
@@ -107,7 +110,9 @@ void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallbac
RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage);
notifier->setFatalError(error.release());
} else {
- if (!m_service->startUpdating(notifier->m_options.get())) {
+ if (m_service->startUpdating(notifier->m_options.get()))
+ notifier->startTimerIfNeeded();
+ else {
if (notifier->m_errorCallback) {
RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "Unable to Start");
notifier->m_errorCallback->handleEvent(error.get());
@@ -145,7 +150,9 @@ int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, Pas
RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage);
notifier->setFatalError(error.release());
} else {
- if (!m_service->startUpdating(notifier->m_options.get())) {
+ if (m_service->startUpdating(notifier->m_options.get()))
+ notifier->startTimerIfNeeded();
+ else {
if (notifier->m_errorCallback) {
RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "Unable to Start");
notifier->m_errorCallback->handleEvent(error.get());
@@ -161,6 +168,15 @@ int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, Pas
return sIdentifier;
}
+void Geolocation::requestTimedOut(GeoNotifier* notifier)
+{
+ // If this is a one-shot request, stop it.
+ m_oneShots.remove(notifier);
+
+ if (!hasListeners())
+ m_service->stopUpdating();
+}
+
void Geolocation::clearWatch(int watchId)
{
m_watchers.remove(watchId);
@@ -186,7 +202,6 @@ void Geolocation::setIsAllowed(bool allowed)
m_allowGeolocation = allowed ? Yes : No;
if (isAllowed()) {
- startTimers();
makeSuccessCallbacks();
} else {
WTF::RefPtr<WebCore::PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage);
@@ -233,7 +248,6 @@ void Geolocation::sendPositionToOneShots(Geoposition* position)
RefPtr<GeoNotifier> notifier = *it;
ASSERT(notifier->m_successCallback);
- notifier->m_timer.stop();
notifier->m_successCallback->handleEvent(position);
}
}
@@ -248,40 +262,39 @@ void Geolocation::sendPositionToWatchers(Geoposition* position)
RefPtr<GeoNotifier> notifier = *it;
ASSERT(notifier->m_successCallback);
- notifier->m_timer.stop();
notifier->m_successCallback->handleEvent(position);
}
}
-void Geolocation::startTimer(Vector<RefPtr<GeoNotifier> >& notifiers)
+void Geolocation::stopTimer(Vector<RefPtr<GeoNotifier> >& notifiers)
{
Vector<RefPtr<GeoNotifier> >::const_iterator end = notifiers.end();
for (Vector<RefPtr<GeoNotifier> >::const_iterator it = notifiers.begin(); it != end; ++it) {
RefPtr<GeoNotifier> notifier = *it;
- notifier->startTimer();
+ notifier->m_timer.stop();
}
}
-void Geolocation::startTimersForOneShots()
+void Geolocation::stopTimersForOneShots()
{
Vector<RefPtr<GeoNotifier> > copy;
copyToVector(m_oneShots, copy);
- startTimer(copy);
+ stopTimer(copy);
}
-void Geolocation::startTimersForWatchers()
+void Geolocation::stopTimersForWatchers()
{
Vector<RefPtr<GeoNotifier> > copy;
copyValuesToVector(m_watchers, copy);
- startTimer(copy);
+ stopTimer(copy);
}
-void Geolocation::startTimers()
+void Geolocation::stopTimers()
{
- startTimersForOneShots();
- startTimersForWatchers();
+ stopTimersForOneShots();
+ stopTimersForWatchers();
}
void Geolocation::handleError(PositionError* error)
@@ -319,6 +332,9 @@ void Geolocation::geolocationServicePositionChanged(GeolocationService*)
{
ASSERT(m_service->lastPosition());
+ // Stop all currently running timers.
+ stopTimers();
+
if (!isAllowed()) {
// requestPermission() will ask the chrome for permission. This may be
// implemented synchronously or asynchronously. In both cases,
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
index 547d284..70a8196 100644
--- a/WebCore/page/Geolocation.h
+++ b/WebCore/page/Geolocation.h
@@ -78,7 +78,7 @@ private:
static PassRefPtr<GeoNotifier> create(Geolocation* geolocation, PassRefPtr<PositionCallback> positionCallback, PassRefPtr<PositionErrorCallback> positionErrorCallback, PassRefPtr<PositionOptions> options) { return adoptRef(new GeoNotifier(geolocation, positionCallback, positionErrorCallback, options)); }
void setFatalError(PassRefPtr<PositionError> error);
- void startTimer();
+ void startTimerIfNeeded();
void timerFired(Timer<GeoNotifier>*);
Geolocation* m_geolocation;
@@ -99,10 +99,10 @@ private:
void sendPositionToOneShots(Geoposition*);
void sendPositionToWatchers(Geoposition*);
- static void startTimer(Vector<RefPtr<GeoNotifier> >&);
- void startTimersForOneShots();
- void startTimersForWatchers();
- void startTimers();
+ static void stopTimer(Vector<RefPtr<GeoNotifier> >&);
+ void stopTimersForOneShots();
+ void stopTimersForWatchers();
+ void stopTimers();
void makeSuccessCallbacks();
void handleError(PositionError*);
@@ -114,6 +114,7 @@ private:
virtual void geolocationServiceErrorOccurred(GeolocationService*);
void fatalErrorOccurred(GeoNotifier* notifier);
+ void requestTimedOut(GeoNotifier* notifier);
typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
typedef HashMap<int, RefPtr<GeoNotifier> > GeoNotifierMap;