WebCore/page/Geolocation.cpp
changeset 2 303757a437d3
parent 0 4f2f89ce4247
--- a/WebCore/page/Geolocation.cpp	Fri Sep 17 09:02:29 2010 +0300
+++ b/WebCore/page/Geolocation.cpp	Mon Oct 04 01:32:07 2010 +0300
@@ -278,13 +278,18 @@
         notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
     else if (haveSuitableCachedPosition(notifier->m_options.get()))
         notifier->setUseCachedPosition();
-    else if (notifier->hasZeroTimeout() || startUpdating(notifier.get())) {
+    else if (notifier->hasZeroTimeout())
+        notifier->startTimerIfNeeded();
 #if USE(PREEMPT_GEOLOCATION_PERMISSION)
-        // Only start timer if we're not waiting for user permission.
-        if (!m_startRequestPermissionNotifier)
-#endif            
-            notifier->startTimerIfNeeded();
-    } else
+    else if (!isAllowed()) {
+        // if we don't yet have permission, request for permission before calling startUpdating()
+        m_pendingForPermissionNotifiers.add(notifier);
+        requestPermission();
+    }
+#endif
+    else if (startUpdating(notifier.get()))
+        notifier->startTimerIfNeeded();
+    else
         notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
 
     return notifier.release();
@@ -401,26 +406,10 @@
     m_allowGeolocation = allowed ? Yes : No;
     
 #if USE(PREEMPT_GEOLOCATION_PERMISSION)
-    if (m_startRequestPermissionNotifier) {
-        if (isAllowed()) {
-            // Permission request was made during the startUpdating process
-            m_startRequestPermissionNotifier->startTimerIfNeeded();
-            m_startRequestPermissionNotifier = 0;
-#if ENABLE(CLIENT_BASED_GEOLOCATION)
-            if (!m_frame)
-                return;
-            Page* page = m_frame->page();
-            if (!page)
-                return;
-            page->geolocationController()->addObserver(this);
-#else
-            // TODO: Handle startUpdate() for non-client based implementations using pre-emptive policy
-#endif
-        } else {
-            m_startRequestPermissionNotifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
-            m_oneShots.add(m_startRequestPermissionNotifier);
-            m_startRequestPermissionNotifier = 0;
-        }
+    // Permission request was made during the startRequest process
+    if (!m_pendingForPermissionNotifiers.isEmpty()) {
+        handlePendingPermissionNotifiers();
+        m_pendingForPermissionNotifiers.clear();
         return;
     }
 #endif
@@ -616,14 +605,6 @@
 
 bool Geolocation::startUpdating(GeoNotifier* notifier)
 {
-#if USE(PREEMPT_GEOLOCATION_PERMISSION)
-    if (!isAllowed()) {
-        m_startRequestPermissionNotifier = notifier;
-        requestPermission();
-        return true;
-    }
-#endif
-
 #if ENABLE(CLIENT_BASED_GEOLOCATION)
     if (!m_frame)
         return false;
@@ -632,8 +613,7 @@
     if (!page)
         return false;
 
-    // FIXME: Pass options to client.
-    page->geolocationController()->addObserver(this);
+    page->geolocationController()->addObserver(this, notifier->m_options->enableHighAccuracy());
     return true;
 #else
     return m_service->startUpdating(notifier->m_options.get());
@@ -657,6 +637,28 @@
 
 }
 
+#if USE(PREEMPT_GEOLOCATION_PERMISSION)
+void Geolocation::handlePendingPermissionNotifiers()
+{
+    // While we iterate through the list, we need not worry about list being modified as the permission 
+    // is already set to Yes/No and no new listeners will be added to the pending list
+    GeoNotifierSet::const_iterator end = m_pendingForPermissionNotifiers.end();
+    for (GeoNotifierSet::const_iterator iter = m_pendingForPermissionNotifiers.begin(); iter != end; ++iter) {
+        GeoNotifier* notifier = iter->get();
+
+        if (isAllowed()) {
+            // start all pending notification requests as permission granted.
+            // The notifier is always ref'ed by m_oneShots or m_watchers.
+            if (startUpdating(notifier))
+                notifier->startTimerIfNeeded();
+            else
+                notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
+        } else
+            notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
+    }
+}
+#endif
+
 } // namespace WebCore
 
 #else