[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

eric at webkit.org eric at webkit.org
Wed Apr 7 23:10:49 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit e9db0ae8d47bac7c1ec4393413582084e4e7978f
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Oct 28 01:07:25 2009 +0000

    2009-10-27  Steve Block  <steveblock at google.com>
    
            Reviewed by Darin Adler.
    
            When a Geolocation method is called, immediately calls the error calback asynchronously if permissions have already been denied.
            https://bugs.webkit.org/show_bug.cgi?id=27944.
    
            * fast/dom/Geolocation/resources/permission-denied-already-error.js: Added. Tests that when permission has already been denied, the error callback is invoked with code PERMISSION_DENIED, when the Geolocation service reports an error.
            * fast/dom/Geolocation/permission-denied-already-error.html: Added. Wrapper for above test.
            * fast/dom/Geolocation/permission-denied-already-error-expected.txt: Added. Expected result for above test.
            * fast/dom/Geolocation/resources/permission-denied-already-success.js: Added. Tests that when permission has already been denied, the error callback is invoked with code PERMISSION_DENIED, when the Geolocation service has a good position fix.
            * fast/dom/Geolocation/permission-denied-already-success.html: Added. Wrapper for above test.
            * fast/dom/Geolocation/permission-denied-already-success-expected.txt: Added. Expected result for above test.
            * fast/dom/Geolocation/resources/permission-denied.js: Modified. Updates error string.
            * fast/dom/Geolocation/permission-denied-expected.txt: Modified. Expected result for above test.
            * fast/dom/Geolocation/resources/permission-denied-stops-watches.js: Modified. Updates error string.
            * fast/dom/Geolocation/permission-denied-expected-stops-watches.txt: Modified. Expected result for above test.
            * platform/gtk/Skipped: Modified. Adds above tests to skipped list.
    2009-10-27  Steve Block  <steveblock at google.com>
    
            Reviewed by Darin Adler.
    
            When a Geolocation method is called, immediately calls the error calback asynchronously if permissions
            have already been denied.
            https://bugs.webkit.org/show_bug.cgi?id=27944.
    
            Tests: fast/dom/Geolocation/permission-denied-already-error.html
                   fast/dom/Geolocation/permission-denied-already-success.html
    
            * page/Geolocation.cpp: Modified.
            (WebCore::Geolocation::GeoNotifier::GeoNotifier): Modified. GeoNotifier takes Geolocation object as constructor argument.
            (WebCore::Geolocation::GeoNotifier::setFatalError): Added. Sets a fatal error for this notifier, causing it to terminate immediately and call the error callback asynchronously.
            (WebCore::Geolocation::GeoNotifier::timerFired): Added. Used to call the error callback asynchronously on fatal error.
            (WebCore::Geolocation::getCurrentPosition): Modified. Calls startRequest.
            (WebCore::Geolocation::watchPosition): Modified. Calls startRequest.
            (WebCore::Geolocation::startRequest): Added. Common functionality for starting a one-shot or watch request. Sets a fatal error on the notifier if permissions have already been denied.
            (WebCore::Geolocation::fatalErrorOccurred): Added. Registers that a notifier has encountered a fatal error and should be destroyed.
            (WebCore::Geolocation::setIsAllowed): Modified. Uses a standard error message for the error callback when permissions are denied.
            * page/Geolocation.h: Modified.
            (WebCore::Geolocation::isDenied): Added. Determines whether permissions have been denied.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50190 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index e173f82..5c27fb4 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2009-10-27  Steve Block  <steveblock at google.com>
+
+        Reviewed by Darin Adler.
+
+        When a Geolocation method is called, immediately calls the error calback asynchronously if permissions have already been denied.
+        https://bugs.webkit.org/show_bug.cgi?id=27944.
+
+        * fast/dom/Geolocation/resources/permission-denied-already-error.js: Added. Tests that when permission has already been denied, the error callback is invoked with code PERMISSION_DENIED, when the Geolocation service reports an error.
+        * fast/dom/Geolocation/permission-denied-already-error.html: Added. Wrapper for above test.
+        * fast/dom/Geolocation/permission-denied-already-error-expected.txt: Added. Expected result for above test.
+        * fast/dom/Geolocation/resources/permission-denied-already-success.js: Added. Tests that when permission has already been denied, the error callback is invoked with code PERMISSION_DENIED, when the Geolocation service has a good position fix.
+        * fast/dom/Geolocation/permission-denied-already-success.html: Added. Wrapper for above test.
+        * fast/dom/Geolocation/permission-denied-already-success-expected.txt: Added. Expected result for above test.
+        * fast/dom/Geolocation/resources/permission-denied.js: Modified. Updates error string.
+        * fast/dom/Geolocation/permission-denied-expected.txt: Modified. Expected result for above test.
+        * fast/dom/Geolocation/resources/permission-denied-stops-watches.js: Modified. Updates error string.
+        * fast/dom/Geolocation/permission-denied-expected-stops-watches.txt: Modified. Expected result for above test.
+        * platform/gtk/Skipped: Modified. Adds above tests to skipped list.
+
 2009-10-27  Eric Seidel  <eric at webkit.org>
 
         Reviewed by Nikolas Zimmermann.
diff --git a/LayoutTests/fast/dom/Geolocation/permission-denied-already-error-expected.txt b/LayoutTests/fast/dom/Geolocation/permission-denied-already-error-expected.txt
new file mode 100644
index 0000000..f4b614f
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/permission-denied-already-error-expected.txt
@@ -0,0 +1,22 @@
+Tests that when Geolocation permission has been denied prior to a call to a Geolocation method, the error callback is invoked with code PERMISSION_DENIED, when the Geolocation service encounters an error.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+PASS error.code is error.PERMISSION_DENIED
+PASS error.message is "User denied Geolocation"
+PASS error.UNKNOWN_ERROR is 0
+PASS error.PERMISSION_DENIED is 1
+PASS error.POSITION_UNAVAILABLE is 2
+PASS error.TIMEOUT is 3
+
+PASS error.code is error.PERMISSION_DENIED
+PASS error.message is "User denied Geolocation"
+PASS error.UNKNOWN_ERROR is 0
+PASS error.PERMISSION_DENIED is 1
+PASS error.POSITION_UNAVAILABLE is 2
+PASS error.TIMEOUT is 3
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/Geolocation/permission-denied-already-error.html b/LayoutTests/fast/dom/Geolocation/permission-denied-already-error.html
new file mode 100644
index 0000000..dc166c9
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/permission-denied-already-error.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/permission-denied-already-error.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/Geolocation/permission-denied-already-success-expected.txt b/LayoutTests/fast/dom/Geolocation/permission-denied-already-success-expected.txt
new file mode 100644
index 0000000..3ea0707
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/permission-denied-already-success-expected.txt
@@ -0,0 +1,22 @@
+Tests that when Geolocation permission has been denied prior to a call to a Geolocation method, the error callback is invoked with code PERMISSION_DENIED, when the Geolocation service has a good position.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+PASS error.code is error.PERMISSION_DENIED
+PASS error.message is "User denied Geolocation"
+PASS error.UNKNOWN_ERROR is 0
+PASS error.PERMISSION_DENIED is 1
+PASS error.POSITION_UNAVAILABLE is 2
+PASS error.TIMEOUT is 3
+
+PASS error.code is error.PERMISSION_DENIED
+PASS error.message is "User denied Geolocation"
+PASS error.UNKNOWN_ERROR is 0
+PASS error.PERMISSION_DENIED is 1
+PASS error.POSITION_UNAVAILABLE is 2
+PASS error.TIMEOUT is 3
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/Geolocation/permission-denied-already-success.html b/LayoutTests/fast/dom/Geolocation/permission-denied-already-success.html
new file mode 100644
index 0000000..4b086a7
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/permission-denied-already-success.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/permission-denied-already-success.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/Geolocation/permission-denied-expected.txt b/LayoutTests/fast/dom/Geolocation/permission-denied-expected.txt
index 501d740..b2ce8d1 100644
--- a/LayoutTests/fast/dom/Geolocation/permission-denied-expected.txt
+++ b/LayoutTests/fast/dom/Geolocation/permission-denied-expected.txt
@@ -5,7 +5,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 PASS successfullyParsed is true
 PASS error.code is error.PERMISSION_DENIED
-PASS error.message is "User disallowed Geolocation"
+PASS error.message is "User denied Geolocation"
 PASS error.UNKNOWN_ERROR is 0
 PASS error.PERMISSION_DENIED is 1
 PASS error.POSITION_UNAVAILABLE is 2
diff --git a/LayoutTests/fast/dom/Geolocation/permission-denied-stops-watches-expected.txt b/LayoutTests/fast/dom/Geolocation/permission-denied-stops-watches-expected.txt
index c8f8353..cf630a7 100644
--- a/LayoutTests/fast/dom/Geolocation/permission-denied-stops-watches-expected.txt
+++ b/LayoutTests/fast/dom/Geolocation/permission-denied-stops-watches-expected.txt
@@ -5,7 +5,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 PASS successfullyParsed is true
 PASS error.code is error.PERMISSION_DENIED
-PASS error.message is "User disallowed Geolocation"
+PASS error.message is "User denied Geolocation"
 PASS error.UNKNOWN_ERROR is 0
 PASS error.PERMISSION_DENIED is 1
 PASS error.POSITION_UNAVAILABLE is 2
diff --git a/LayoutTests/fast/dom/Geolocation/resources/permission-denied-already-error.js b/LayoutTests/fast/dom/Geolocation/resources/permission-denied-already-error.js
new file mode 100644
index 0000000..f271965
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/resources/permission-denied-already-error.js
@@ -0,0 +1,46 @@
+description("Tests that when Geolocation permission has been denied prior to a call to a Geolocation method, the error callback is invoked with code PERMISSION_DENIED, when the Geolocation service encounters an error.");
+
+// Prime the Geolocation instance by denying permission.
+window.layoutTestController.setGeolocationPermission(false);
+window.layoutTestController.setMockGeolocationPosition(51.478, -0.166, 100);
+
+var error;
+navigator.geolocation.getCurrentPosition(function(p) {
+    testFailed('Success callback invoked unexpectedly');
+    window.layoutTestController.notifyDone();
+}, function(e) {
+    error = e
+    shouldBe('error.code', 'error.PERMISSION_DENIED');
+    shouldBe('error.message', '"User denied Geolocation"');
+    shouldBe('error.UNKNOWN_ERROR', '0');
+    shouldBe('error.PERMISSION_DENIED', '1');
+    shouldBe('error.POSITION_UNAVAILABLE', '2');
+    shouldBe('error.TIMEOUT', '3');
+    debug('');
+    continueTest();
+});
+
+function continueTest()
+{
+    // Make another request, with permission already denied.
+    window.layoutTestController.setMockGeolocationError(0, 'test');
+
+    navigator.geolocation.getCurrentPosition(function(p) {
+        testFailed('Success callback invoked unexpectedly');
+        window.layoutTestController.notifyDone();
+    }, function(e) {
+        error = e
+        shouldBe('error.code', 'error.PERMISSION_DENIED');
+        shouldBe('error.message', '"User denied Geolocation"');
+        shouldBe('error.UNKNOWN_ERROR', '0');
+        shouldBe('error.PERMISSION_DENIED', '1');
+        shouldBe('error.POSITION_UNAVAILABLE', '2');
+        shouldBe('error.TIMEOUT', '3');
+        debug('<br /><span class="pass">TEST COMPLETE</span>');
+        window.layoutTestController.notifyDone();
+    });
+}
+window.layoutTestController.waitUntilDone();
+
+var isAsynchronous = true;
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/Geolocation/resources/permission-denied-already-success.js b/LayoutTests/fast/dom/Geolocation/resources/permission-denied-already-success.js
new file mode 100644
index 0000000..2dd89d9
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/resources/permission-denied-already-success.js
@@ -0,0 +1,44 @@
+description("Tests that when Geolocation permission has been denied prior to a call to a Geolocation method, the error callback is invoked with code PERMISSION_DENIED, when the Geolocation service has a good position.");
+
+// Prime the Geolocation instance by denying permission.
+window.layoutTestController.setGeolocationPermission(false);
+window.layoutTestController.setMockGeolocationPosition(51.478, -0.166, 100);
+
+var error;
+navigator.geolocation.getCurrentPosition(function(p) {
+    testFailed('Success callback invoked unexpectedly');
+    window.layoutTestController.notifyDone();
+}, function(e) {
+    error = e
+    shouldBe('error.code', 'error.PERMISSION_DENIED');
+    shouldBe('error.message', '"User denied Geolocation"');
+    shouldBe('error.UNKNOWN_ERROR', '0');
+    shouldBe('error.PERMISSION_DENIED', '1');
+    shouldBe('error.POSITION_UNAVAILABLE', '2');
+    shouldBe('error.TIMEOUT', '3');
+    debug('');
+    continueTest();
+});
+
+function continueTest()
+{
+    // Make another request, with permission already denied.
+    navigator.geolocation.getCurrentPosition(function(p) {
+        testFailed('Success callback invoked unexpectedly');
+        window.layoutTestController.notifyDone();
+    }, function(e) {
+        error = e
+        shouldBe('error.code', 'error.PERMISSION_DENIED');
+        shouldBe('error.message', '"User denied Geolocation"');
+        shouldBe('error.UNKNOWN_ERROR', '0');
+        shouldBe('error.PERMISSION_DENIED', '1');
+        shouldBe('error.POSITION_UNAVAILABLE', '2');
+        shouldBe('error.TIMEOUT', '3');
+        debug('<br /><span class="pass">TEST COMPLETE</span>');
+        window.layoutTestController.notifyDone();
+    });
+}
+window.layoutTestController.waitUntilDone();
+
+var isAsynchronous = true;
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/Geolocation/resources/permission-denied-stops-watches.js b/LayoutTests/fast/dom/Geolocation/resources/permission-denied-stops-watches.js
index 209d9da..147d669 100644
--- a/LayoutTests/fast/dom/Geolocation/resources/permission-denied-stops-watches.js
+++ b/LayoutTests/fast/dom/Geolocation/resources/permission-denied-stops-watches.js
@@ -19,7 +19,7 @@ navigator.geolocation.watchPosition(function(p) {
 
     error = e
     shouldBe('error.code', 'error.PERMISSION_DENIED');
-    shouldBe('error.message', '"User disallowed Geolocation"');
+    shouldBe('error.message', '"User denied Geolocation"');
     shouldBe('error.UNKNOWN_ERROR', '0');
     shouldBe('error.PERMISSION_DENIED', '1');
     shouldBe('error.POSITION_UNAVAILABLE', '2');
diff --git a/LayoutTests/fast/dom/Geolocation/resources/permission-denied.js b/LayoutTests/fast/dom/Geolocation/resources/permission-denied.js
index 977fbf9..f40de7a 100644
--- a/LayoutTests/fast/dom/Geolocation/resources/permission-denied.js
+++ b/LayoutTests/fast/dom/Geolocation/resources/permission-denied.js
@@ -10,7 +10,7 @@ navigator.geolocation.getCurrentPosition(function(p) {
 }, function(e) {
     error = e
     shouldBe('error.code', 'error.PERMISSION_DENIED');
-    shouldBe('error.message', '"User disallowed Geolocation"');
+    shouldBe('error.message', '"User denied Geolocation"');
     shouldBe('error.UNKNOWN_ERROR', '0');
     shouldBe('error.PERMISSION_DENIED', '1');
     shouldBe('error.POSITION_UNAVAILABLE', '2');
diff --git a/LayoutTests/platform/gtk/Skipped b/LayoutTests/platform/gtk/Skipped
index 4bbf5af..33b49cf 100644
--- a/LayoutTests/platform/gtk/Skipped
+++ b/LayoutTests/platform/gtk/Skipped
@@ -1273,6 +1273,8 @@ fast/dom/frame-loading-via-document-write.html
 fast/dom/Geolocation/callback-exception.html
 fast/dom/Geolocation/error.html
 fast/dom/Geolocation/permission-denied.html
+fast/dom/Geolocation/permission-denied-already-error.html
+fast/dom/Geolocation/permission-denied-already-success.html
 fast/dom/Geolocation/permission-denied-stops-watches.html
 fast/dom/Geolocation/position-string.html
 fast/dom/Geolocation/reentrant-error.html
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 81735ac..e6b540a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,26 @@
+2009-10-27  Steve Block  <steveblock at google.com>
+
+        Reviewed by Darin Adler.
+
+        When a Geolocation method is called, immediately calls the error calback asynchronously if permissions
+        have already been denied.
+        https://bugs.webkit.org/show_bug.cgi?id=27944.
+
+        Tests: fast/dom/Geolocation/permission-denied-already-error.html
+               fast/dom/Geolocation/permission-denied-already-success.html
+
+        * page/Geolocation.cpp: Modified.
+        (WebCore::Geolocation::GeoNotifier::GeoNotifier): Modified. GeoNotifier takes Geolocation object as constructor argument.
+        (WebCore::Geolocation::GeoNotifier::setFatalError): Added. Sets a fatal error for this notifier, causing it to terminate immediately and call the error callback asynchronously.
+        (WebCore::Geolocation::GeoNotifier::timerFired): Added. Used to call the error callback asynchronously on fatal error.
+        (WebCore::Geolocation::getCurrentPosition): Modified. Calls startRequest.
+        (WebCore::Geolocation::watchPosition): Modified. Calls startRequest.
+        (WebCore::Geolocation::startRequest): Added. Common functionality for starting a one-shot or watch request. Sets a fatal error on the notifier if permissions have already been denied.
+        (WebCore::Geolocation::fatalErrorOccurred): Added. Registers that a notifier has encountered a fatal error and should be destroyed.
+        (WebCore::Geolocation::setIsAllowed): Modified. Uses a standard error message for the error callback when permissions are denied.
+        * page/Geolocation.h: Modified.
+        (WebCore::Geolocation::isDenied): Added. Determines whether permissions have been denied.
+
 2009-10-27  Chris Marrin  <cmarrin at apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index 3590f84..a265e7d 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -31,10 +31,11 @@
 #include "Document.h"
 #include "Frame.h"
 #include "Page.h"
-#include "PositionError.h"
 
 namespace WebCore {
 
+static const char permissionDeniedErrorMessage[] = "User denied Geolocation";
+
 Geolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
     : m_geolocation(geolocation)
     , m_successCallback(successCallback)
@@ -42,12 +43,21 @@ Geolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<Posit
     , m_options(options)
     , m_timer(this, &Geolocation::GeoNotifier::timerFired)
 {
+    ASSERT(m_geolocation);
     ASSERT(m_successCallback);
     // If no options were supplied from JS, we should have created a default set
     // of options in JSGeolocationCustom.cpp.
     ASSERT(m_options);
 }
 
+void Geolocation::GeoNotifier::setFatalError(PassRefPtr<PositionError> error)
+{
+    // This method is called at most once on a given GeoNotifier object.
+    ASSERT(!m_fatalError);
+    m_fatalError = error;
+    m_timer.startOneShot(0);
+}
+
 bool Geolocation::GeoNotifier::hasZeroTimeout() const
 {
     return m_options->hasTimeout() && m_options->timeout() == 0;
@@ -63,6 +73,14 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
 {
     m_timer.stop();
 
+    if (m_fatalError) {
+        if (m_errorCallback)
+            m_errorCallback->handleEvent(m_fatalError.get());
+        // This will cause this notifier to be deleted.
+        m_geolocation->fatalErrorOccurred(this);
+        return;
+    }
+
     if (m_errorCallback) {
         RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timeout expired");
         m_errorCallback->handleEvent(error.get());
@@ -132,38 +150,55 @@ void Geolocation::disconnectFrame()
 
 void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
 {
-    RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options);
-
-    if (notifier->hasZeroTimeout() || 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());
-        }
+    RefPtr<GeoNotifier> notifier = startRequest(successCallback, errorCallback, options);
+    if (!notifier)
         return;
-    }
 
     m_oneShots.add(notifier);
 }
 
 int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
 {
+    RefPtr<GeoNotifier> notifier = startRequest(successCallback, errorCallback, options);
+    if (!notifier)
+        return 0;
+
+    static int nextAvailableWatchId = 1;
+    m_watchers.set(nextAvailableWatchId, notifier.release());
+    return nextAvailableWatchId++;
+}
+
+PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
+{
     RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options);
 
-    if (notifier->hasZeroTimeout() || m_service->startUpdating(notifier->m_options.get()))
-        notifier->startTimerIfNeeded();
+    // Check whether permissions have already been denied. Note that if this is the case,
+    // the permission state can not change again in the lifetime of this page.
+    if (isDenied())
+        notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
     else {
-        if (notifier->m_errorCallback) {
-            RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "Unable to Start");
-            notifier->m_errorCallback->handleEvent(error.get());
+        if (notifier->hasZeroTimeout() || 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());
+            }
+            return 0;
         }
-        return 0;
     }
-    
-    static int nextAvailableWatchId = 1;
-    m_watchers.set(nextAvailableWatchId, notifier.release());
-    return nextAvailableWatchId++;
+
+    return notifier.release();
+}
+
+void Geolocation::fatalErrorOccurred(Geolocation::GeoNotifier* notifier)
+{
+    // This request has failed fatally. Remove it from our lists.
+    m_oneShots.remove(notifier);
+    m_watchers.remove(notifier);
+
+    if (!hasListeners())
+        m_service->stopUpdating();
 }
 
 void Geolocation::requestTimedOut(GeoNotifier* notifier)
@@ -202,7 +237,7 @@ void Geolocation::setIsAllowed(bool allowed)
     if (isAllowed())
         makeSuccessCallbacks();
     else {
-        RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "User disallowed Geolocation");
+        RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage);
         error->setIsFatal(true);
         handleError(error.get());
     }
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
index c230826..4827664 100644
--- a/WebCore/page/Geolocation.h
+++ b/WebCore/page/Geolocation.h
@@ -28,6 +28,7 @@
 
 #include "GeolocationService.h"
 #include "PositionCallback.h"
+#include "PositionError.h"
 #include "PositionErrorCallback.h"
 #include "PositionOptions.h"
 #include "Timer.h"
@@ -64,6 +65,7 @@ public:
     
     void setIsAllowed(bool);
     bool isAllowed() const { return m_allowGeolocation == Yes; }
+    bool isDenied() const { return m_allowGeolocation == No; }
     
     void setShouldClearCache(bool shouldClearCache) { m_shouldClearCache = shouldClearCache; }
     bool shouldClearCache() const { return m_shouldClearCache; }
@@ -75,6 +77,7 @@ private:
     public:
         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>);
         bool hasZeroTimeout() const;
         void startTimerIfNeeded();
         void timerFired(Timer<GeoNotifier>*);
@@ -84,6 +87,7 @@ private:
         RefPtr<PositionErrorCallback> m_errorCallback;
         RefPtr<PositionOptions> m_options;
         Timer<GeoNotifier> m_timer;
+        RefPtr<PositionError> m_fatalError;
 
     private:
         GeoNotifier(Geolocation*, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
@@ -123,6 +127,9 @@ private:
     virtual void geolocationServicePositionChanged(GeolocationService*);
     virtual void geolocationServiceErrorOccurred(GeolocationService*);
 
+    PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
+
+    void fatalErrorOccurred(GeoNotifier*);
     void requestTimedOut(GeoNotifier*);
 
     typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list