summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--LayoutTests/fast/dom/Geolocation/ongoing-request-leak-expected.txt1
-rw-r--r--LayoutTests/fast/dom/Geolocation/ongoing-request-leak.html13
-rw-r--r--LayoutTests/fast/dom/Geolocation/script-tests/ongoing-request-leak.js13
-rw-r--r--WebCore/loader/FrameLoader.cpp13
-rw-r--r--WebCore/page/Geolocation.cpp17
-rw-r--r--WebCore/page/Geolocation.h4
6 files changed, 61 insertions, 0 deletions
diff --git a/LayoutTests/fast/dom/Geolocation/ongoing-request-leak-expected.txt b/LayoutTests/fast/dom/Geolocation/ongoing-request-leak-expected.txt
new file mode 100644
index 0000000..3fb979f
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/ongoing-request-leak-expected.txt
@@ -0,0 +1 @@
+Exercises a condition where the DOMWindow may leak if Geolocation requests are ongoing when the page is navigated away or closed. Complete.
diff --git a/LayoutTests/fast/dom/Geolocation/ongoing-request-leak.html b/LayoutTests/fast/dom/Geolocation/ongoing-request-leak.html
new file mode 100644
index 0000000..dab385e
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/ongoing-request-leak.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="script-tests/ongoing-request-leak.js"></script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/Geolocation/script-tests/ongoing-request-leak.js b/LayoutTests/fast/dom/Geolocation/script-tests/ongoing-request-leak.js
new file mode 100644
index 0000000..08e6b21
--- /dev/null
+++ b/LayoutTests/fast/dom/Geolocation/script-tests/ongoing-request-leak.js
@@ -0,0 +1,13 @@
+description("Exercises a condition where the DOMWindow may leak if Geolocation requests are ongoing when the page is navigated away or closed. The page should reoload.");
+
+if (window.layoutTestController) layoutTestController.setGeolocationPermission(true);
+if (window.layoutTestController) layoutTestController.setMockGeolocationPosition(51.478, -0.166, 100.0);
+
+navigator.geolocation.watchPosition(function() {}, null);
+
+document.body.onload = function() {
+ location = "data:text/html,Exercises a condition where the DOMWindow may leak if Geolocation requests are ongoing when the page is navigated away or closed. Complete.<script>if (window.layoutTestController) layoutTestController.notifyDone();</" + "script>";
+}
+
+window.jsTestIsAsync = true;
+window.successfullyParsed = true;
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index 8920b6a..20a8142 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -60,6 +60,9 @@
#include "FrameLoaderClient.h"
#include "FrameTree.h"
#include "FrameView.h"
+#if PLATFORM(ANDROID)
+#include "Geolocation.h"
+#endif // PLATFORM(ANDROID)
#include "HTMLAnchorElement.h"
#include "HTMLAppletElement.h"
#include "HTMLFormElement.h"
@@ -77,6 +80,9 @@
#include "Logging.h"
#include "MIMETypeRegistry.h"
#include "MainResourceLoader.h"
+#if PLATFORM(ANDROID)
+#include "Navigator.h"
+#endif // PLATFORM(ANDROID)
#include "Page.h"
#include "PageCache.h"
#include "PageGroup.h"
@@ -622,6 +628,13 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic
#endif
}
+#if PLATFORM(ANDROID)
+ // Stop the Geolocation object, if present. This call is made after the unload
+ // event has fired, so no new Geolocation activity is possible.
+ if (m_frame->domWindow()->navigator()->optionalGeolocation())
+ m_frame->domWindow()->navigator()->optionalGeolocation()->stop();
+#endif // PLATFORM(ANDROID)
+
// tell all subframes to stop as well
for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
child->loader()->stopLoading(unloadEventPolicy);
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index 7dcf0a1..13bc02a 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -221,12 +221,25 @@ Geolocation::~Geolocation()
{
}
+#if PLATFORM(ANDROID)
+void Geolocation::stop()
+{
+ m_oneShots.clear();
+ m_watchers.clear();
+ stopUpdating();
+}
+#endif // PLATFORM(ANDROID)
+
void Geolocation::disconnectFrame()
{
if (m_frame && m_frame->page() && m_allowGeolocation == InProgress)
m_frame->page()->chrome()->cancelGeolocationPermissionRequestForFrame(m_frame, this);
+#if PLATFORM(ANDROID)
+ // See Geolocation::stop()
+#else
stopTimers();
stopUpdating();
+#endif // PLATFORM(ANDROID)
if (m_frame && m_frame->document())
m_frame->document()->setUsingGeolocation(false);
m_frame = 0;
@@ -683,6 +696,10 @@ Geolocation::~Geolocation() {}
void Geolocation::setIsAllowed(bool) {}
+#if PLATFORM(ANDROID)
+void Geolocation::stop() {}
+#endif // PLATFORM(ANDROID)
+
}
#endif // ENABLE(GEOLOCATION)
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
index 1d0050f..fcb967f 100644
--- a/WebCore/page/Geolocation.h
+++ b/WebCore/page/Geolocation.h
@@ -65,6 +65,10 @@ public:
void suspend();
void resume();
+#if PLATFORM(ANDROID)
+ void stop();
+#endif // PLATFORM(ANDROID)
+
void setIsAllowed(bool);
Frame* frame() const { return m_frame; }