- Revision
- 98481
- Author
- [email protected]
- Date
- 2011-10-26 07:56:09 -0700 (Wed, 26 Oct 2011)
Log Message
Properly suspend/resume Geolocation/DeviceMotion/DeviceOrientation objects
https://bugs.webkit.org/show_bug.cgi?id=70328
Reviewed by Simon Hausmann.
Also remove checks for m_client in DeviceMotionController as it can never be null.
No new tests, as the suspend/resume functionality is not fully working yet.
* dom/DeviceMotionController.cpp:
(WebCore::DeviceMotionController::timerFired):
(WebCore::DeviceMotionController::addListener):
(WebCore::DeviceMotionController::removeListener):
(WebCore::DeviceMotionController::removeAllListeners):
(WebCore::DeviceMotionController::suspend):
(WebCore::DeviceMotionController::resume):
* dom/DeviceMotionController.h:
* dom/DeviceOrientationController.cpp:
(WebCore::DeviceOrientationController::suspend):
(WebCore::DeviceOrientationController::resume):
* dom/DeviceOrientationController.h:
* dom/Document.cpp:
(WebCore::Document::suspendActiveDOMObjects):
(WebCore::Document::resumeActiveDOMObjects):
(WebCore::Document::stopActiveDOMObjects):
* dom/Document.h:
* dom/ScriptExecutionContext.h:
* page/GeolocationController.cpp:
(WebCore::GeolocationController::GeolocationController):
(WebCore::GeolocationController::removeObserver):
(WebCore::GeolocationController::suspend):
(WebCore::GeolocationController::resume):
* page/GeolocationController.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (98480 => 98481)
--- trunk/Source/WebCore/ChangeLog 2011-10-26 14:54:14 UTC (rev 98480)
+++ trunk/Source/WebCore/ChangeLog 2011-10-26 14:56:09 UTC (rev 98481)
@@ -1,3 +1,39 @@
+2011-10-26 Kenneth Rohde Christiansen <[email protected]>
+
+ Properly suspend/resume Geolocation/DeviceMotion/DeviceOrientation objects
+ https://bugs.webkit.org/show_bug.cgi?id=70328
+
+ Reviewed by Simon Hausmann.
+
+ Also remove checks for m_client in DeviceMotionController as it can never be null.
+
+ No new tests, as the suspend/resume functionality is not fully working yet.
+
+ * dom/DeviceMotionController.cpp:
+ (WebCore::DeviceMotionController::timerFired):
+ (WebCore::DeviceMotionController::addListener):
+ (WebCore::DeviceMotionController::removeListener):
+ (WebCore::DeviceMotionController::removeAllListeners):
+ (WebCore::DeviceMotionController::suspend):
+ (WebCore::DeviceMotionController::resume):
+ * dom/DeviceMotionController.h:
+ * dom/DeviceOrientationController.cpp:
+ (WebCore::DeviceOrientationController::suspend):
+ (WebCore::DeviceOrientationController::resume):
+ * dom/DeviceOrientationController.h:
+ * dom/Document.cpp:
+ (WebCore::Document::suspendActiveDOMObjects):
+ (WebCore::Document::resumeActiveDOMObjects):
+ (WebCore::Document::stopActiveDOMObjects):
+ * dom/Document.h:
+ * dom/ScriptExecutionContext.h:
+ * page/GeolocationController.cpp:
+ (WebCore::GeolocationController::GeolocationController):
+ (WebCore::GeolocationController::removeObserver):
+ (WebCore::GeolocationController::suspend):
+ (WebCore::GeolocationController::resume):
+ * page/GeolocationController.h:
+
2011-10-26 Pavel Feldman <[email protected]>
Not reviewed: follow up to 98236 - moved inspector settings initialization earlier to unbreak settings panel.
Modified: trunk/Source/WebCore/dom/DeviceMotionController.cpp (98480 => 98481)
--- trunk/Source/WebCore/dom/DeviceMotionController.cpp 2011-10-26 14:54:14 UTC (rev 98480)
+++ trunk/Source/WebCore/dom/DeviceMotionController.cpp 2011-10-26 14:56:09 UTC (rev 98481)
@@ -48,10 +48,10 @@
void DeviceMotionController::timerFired(Timer<DeviceMotionController>* timer)
{
ASSERT_UNUSED(timer, timer == &m_timer);
- ASSERT(!m_client || m_client->currentDeviceMotion());
+ ASSERT(m_client->currentDeviceMotion());
m_timer.stop();
- RefPtr<DeviceMotionData> deviceMotionData = m_client ? m_client->currentDeviceMotion() : DeviceMotionData::create();
+ RefPtr<DeviceMotionData> deviceMotionData = m_client->currentDeviceMotion();
RefPtr<DeviceMotionEvent> event = DeviceMotionEvent::create(eventNames().devicemotionEvent, deviceMotionData.get());
Vector<RefPtr<DOMWindow> > listenersVector;
@@ -63,9 +63,9 @@
void DeviceMotionController::addListener(DOMWindow* window)
{
- // If no client is present or the client already has motion data,
+ // If the client already has motion data,
// immediately trigger an asynchronous response.
- if (!m_client || m_client->currentDeviceMotion()) {
+ if (m_client->currentDeviceMotion()) {
m_newListeners.add(window);
if (!m_timer.isActive())
m_timer.startOneShot(0);
@@ -73,15 +73,16 @@
bool wasEmpty = m_listeners.isEmpty();
m_listeners.add(window);
- if (wasEmpty && m_client)
+ if (wasEmpty)
m_client->startUpdating();
}
void DeviceMotionController::removeListener(DOMWindow* window)
{
m_listeners.remove(window);
+ m_suspendedListeners.remove(window);
m_newListeners.remove(window);
- if (m_listeners.isEmpty() && m_client)
+ if (m_listeners.isEmpty())
m_client->stopUpdating();
}
@@ -92,11 +93,34 @@
return;
m_listeners.removeAll(window);
+ m_suspendedListeners.removeAll(window);
m_newListeners.remove(window);
- if (m_listeners.isEmpty() && m_client)
+ if (m_listeners.isEmpty())
m_client->stopUpdating();
}
+void DeviceMotionController::suspendEventsForAllListeners(DOMWindow* window)
+{
+ if (!m_listeners.contains(window))
+ return;
+
+ int count = m_listeners.count(window);
+ removeAllListeners(window);
+ while (count--)
+ m_suspendedListeners.add(window);
+}
+
+void DeviceMotionController::resumeEventsForAllListeners(DOMWindow* window)
+{
+ if (!m_suspendedListeners.contains(window))
+ return;
+
+ int count = m_suspendedListeners.count(window);
+ m_suspendedListeners.removeAll(window);
+ while (count--)
+ addListener(window);
+}
+
void DeviceMotionController::didChangeDeviceMotion(DeviceMotionData* deviceMotionData)
{
RefPtr<DeviceMotionEvent> event = DeviceMotionEvent::create(eventNames().devicemotionEvent, deviceMotionData);
Modified: trunk/Source/WebCore/dom/DeviceMotionController.h (98480 => 98481)
--- trunk/Source/WebCore/dom/DeviceMotionController.h 2011-10-26 14:54:14 UTC (rev 98480)
+++ trunk/Source/WebCore/dom/DeviceMotionController.h 2011-10-26 14:56:09 UTC (rev 98481)
@@ -44,6 +44,9 @@
void removeListener(DOMWindow*);
void removeAllListeners(DOMWindow*);
+ void suspendEventsForAllListeners(DOMWindow*);
+ void resumeEventsForAllListeners(DOMWindow*);
+
void didChangeDeviceMotion(DeviceMotionData*);
bool isActive() { return !m_listeners.isEmpty(); }
@@ -54,6 +57,7 @@
DeviceMotionClient* m_client;
typedef HashCountedSet<RefPtr<DOMWindow> > ListenersCountedSet;
ListenersCountedSet m_listeners;
+ ListenersCountedSet m_suspendedListeners;
typedef HashSet<RefPtr<DOMWindow> > ListenersSet;
ListenersSet m_newListeners;
Timer<DeviceMotionController> m_timer;
Modified: trunk/Source/WebCore/dom/DeviceOrientationController.cpp (98480 => 98481)
--- trunk/Source/WebCore/dom/DeviceOrientationController.cpp 2011-10-26 14:54:14 UTC (rev 98480)
+++ trunk/Source/WebCore/dom/DeviceOrientationController.cpp 2011-10-26 14:56:09 UTC (rev 98481)
@@ -82,6 +82,7 @@
void DeviceOrientationController::removeListener(DOMWindow* window)
{
m_listeners.remove(window);
+ m_suspendedListeners.remove(window);
m_newListeners.remove(window);
if (m_listeners.isEmpty())
m_client->stopUpdating();
@@ -94,11 +95,34 @@
return;
m_listeners.removeAll(window);
+ m_suspendedListeners.removeAll(window);
m_newListeners.remove(window);
if (m_listeners.isEmpty())
m_client->stopUpdating();
}
+void DeviceOrientationController::suspendEventsForAllListeners(DOMWindow* window)
+{
+ if (!m_listeners.contains(window))
+ return;
+
+ int count = m_listeners.count(window);
+ removeAllListeners(window);
+ while (count--)
+ m_suspendedListeners.add(window);
+}
+
+void DeviceOrientationController::resumeEventsForAllListeners(DOMWindow* window)
+{
+ if (!m_suspendedListeners.contains(window))
+ return;
+
+ int count = m_suspendedListeners.count(window);
+ m_suspendedListeners.removeAll(window);
+ while (count--)
+ addListener(window);
+}
+
void DeviceOrientationController::didChangeDeviceOrientation(DeviceOrientation* orientation)
{
RefPtr<DeviceOrientationEvent> event = DeviceOrientationEvent::create(eventNames().deviceorientationEvent, orientation);
Modified: trunk/Source/WebCore/dom/DeviceOrientationController.h (98480 => 98481)
--- trunk/Source/WebCore/dom/DeviceOrientationController.h 2011-10-26 14:54:14 UTC (rev 98480)
+++ trunk/Source/WebCore/dom/DeviceOrientationController.h 2011-10-26 14:56:09 UTC (rev 98481)
@@ -46,6 +46,9 @@
void removeListener(DOMWindow*);
void removeAllListeners(DOMWindow*);
+ void suspendEventsForAllListeners(DOMWindow*);
+ void resumeEventsForAllListeners(DOMWindow*);
+
void didChangeDeviceOrientation(DeviceOrientation*);
bool isActive() { return !m_listeners.isEmpty(); }
@@ -57,6 +60,7 @@
DeviceOrientationClient* m_client;
typedef HashCountedSet<RefPtr<DOMWindow> > ListenersCountedSet;
ListenersCountedSet m_listeners;
+ ListenersCountedSet m_suspendedListeners;
typedef HashSet<RefPtr<DOMWindow> > ListenersSet;
ListenersSet m_newListeners;
Timer<DeviceOrientationController> m_timer;
Modified: trunk/Source/WebCore/dom/Document.cpp (98480 => 98481)
--- trunk/Source/WebCore/dom/Document.cpp 2011-10-26 14:54:14 UTC (rev 98480)
+++ trunk/Source/WebCore/dom/Document.cpp 2011-10-26 14:56:09 UTC (rev 98481)
@@ -47,6 +47,10 @@
#include "DOMImplementation.h"
#include "DOMWindow.h"
#include "DateComponents.h"
+#include "DeviceMotionController.h"
+#include "DeviceMotionEvent.h"
+#include "DeviceOrientationController.h"
+#include "DeviceOrientationEvent.h"
#include "DocumentFragment.h"
#include "DocumentLoader.h"
#include "DocumentMarkerController.h"
@@ -70,6 +74,7 @@
#include "FrameSelection.h"
#include "FrameTree.h"
#include "FrameView.h"
+#include "GeolocationController.h"
#include "HashChangeEvent.h"
#include "HTMLAllCollection.h"
#include "HTMLAnchorElement.h"
@@ -1835,6 +1840,36 @@
node->removeAllEventListeners();
}
+void Document::suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension why)
+{
+ ScriptExecutionContext::suspendActiveDOMObjects(why);
+
+#if ENABLE(DEVICE_ORIENTATION)
+ if (!page())
+ return;
+
+ if (page()->deviceMotionController())
+ page()->deviceMotionController()->suspendEventsForAllListeners(domWindow());
+ if (page()->deviceOrientationController())
+ page()->deviceOrientationController()->suspendEventsForAllListeners(domWindow());
+#endif
+}
+
+void Document::resumeActiveDOMObjects()
+{
+ ScriptExecutionContext::resumeActiveDOMObjects();
+
+#if ENABLE(DEVICE_ORIENTATION)
+ if (!page())
+ return;
+
+ if (page()->deviceMotionController())
+ page()->deviceMotionController()->resumeEventsForAllListeners(domWindow());
+ if (page()->deviceOrientationController())
+ page()->deviceOrientationController()->resumeEventsForAllListeners(domWindow());
+#endif
+}
+
RenderView* Document::renderView() const
{
return toRenderView(renderer());
Modified: trunk/Source/WebCore/dom/Document.h (98480 => 98481)
--- trunk/Source/WebCore/dom/Document.h 2011-10-26 14:54:14 UTC (rev 98480)
+++ trunk/Source/WebCore/dom/Document.h 2011-10-26 14:56:09 UTC (rev 98481)
@@ -564,6 +564,10 @@
virtual void attach();
virtual void detach();
+ // Override ScriptExecutionContext methods to do additional work
+ virtual void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension) OVERRIDE;
+ virtual void resumeActiveDOMObjects() OVERRIDE;
+
RenderArena* renderArena() { return m_renderArena.get(); }
RenderView* renderView() const;
Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.h (98480 => 98481)
--- trunk/Source/WebCore/dom/ScriptExecutionContext.h 2011-10-26 14:54:14 UTC (rev 98480)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.h 2011-10-26 14:56:09 UTC (rev 98481)
@@ -109,9 +109,10 @@
bool canSuspendActiveDOMObjects();
// Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' -
// step-by-step JS debugging is one example.
- void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
- void resumeActiveDOMObjects();
- void stopActiveDOMObjects();
+ virtual void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
+ virtual void resumeActiveDOMObjects();
+ virtual void stopActiveDOMObjects();
+
void createdActiveDOMObject(ActiveDOMObject*, void* upcastPointer);
void destroyedActiveDOMObject(ActiveDOMObject*);
typedef const HashMap<ActiveDOMObject*, void*> ActiveDOMObjectsMap;