- Revision
- 193885
- Author
- dba...@webkit.org
- Date
- 2015-12-09 18:53:12 -0800 (Wed, 09 Dec 2015)
Log Message
[iOS] Suspend and resume device motion and device orientation updates when page is hidden and visible, respectively
https://bugs.webkit.org/show_bug.cgi?id=151840
<rdar://problem/23753931>
Reviewed by Simon Fraser.
.:
Add a manual test that can be used to verify that we suspend dispatching device motion and
device orientation events when the page is hidden.
* ManualTests/ios/resources/suspend-orientation-and-motion-events-when-page-becomes-hidden.js: Added.
(resetTest):
(checkEvent):
(handleVisibilityChange):
* ManualTests/ios/suspend-orientation-and-motion-events-when-page-becomes-hidden.html: Added.
Source/WebCore:
* dom/Document.cpp:
(WebCore::Document::suspendDeviceMotionAndOrientationUpdates): Added.
(WebCore::Document::resumeDeviceMotionAndOrientationUpdates): Added.
(WebCore::Document::platformSuspendOrStopActiveDOMObjects): Moved logic to suspend device motion and
orientation updates from here to Document::suspendDeviceMotionAndOrientationUpdates().
(WebCore::Document::suspendActiveDOMObjects): Modified to call Document::suspendDeviceMotionAndOrientationUpdates().
(WebCore::Document::resumeActiveDOMObjects): Modified to call Document::resumeDeviceMotionAndOrientationUpdates().
* dom/Document.h:
* page/Page.cpp:
(WebCore::Page::setIsVisibleInternal): Suspend device motion and orientation updates when the page is hidden and
resume updates when the page is visible.
(WebCore::Page::suspendDeviceMotionAndOrientationUpdates): Added.
(WebCore::Page::resumeDeviceMotionAndOrientationUpdates): Added.
* page/Page.h:
Modified Paths
Added Paths
Diff
Modified: trunk/ChangeLog (193884 => 193885)
--- trunk/ChangeLog 2015-12-10 02:51:11 UTC (rev 193884)
+++ trunk/ChangeLog 2015-12-10 02:53:12 UTC (rev 193885)
@@ -1,3 +1,20 @@
+2015-12-09 Daniel Bates <daba...@apple.com>
+
+ [iOS] Suspend and resume device motion and device orientation updates when page is hidden and visible, respectively
+ https://bugs.webkit.org/show_bug.cgi?id=151840
+ <rdar://problem/23753931>
+
+ Reviewed by Simon Fraser.
+
+ Add a manual test that can be used to verify that we suspend dispatching device motion and
+ device orientation events when the page is hidden.
+
+ * ManualTests/ios/resources/suspend-orientation-and-motion-events-when-page-becomes-hidden.js: Added.
+ (resetTest):
+ (checkEvent):
+ (handleVisibilityChange):
+ * ManualTests/ios/suspend-orientation-and-motion-events-when-page-becomes-hidden.html: Added.
+
2015-12-07 Alex Christensen <achristen...@webkit.org>
Fix internal Windows build
Added: trunk/ManualTests/ios/resources/suspend-orientation-and-motion-events-when-page-becomes-hidden.js (0 => 193885)
--- trunk/ManualTests/ios/resources/suspend-orientation-and-motion-events-when-page-becomes-hidden.js (rev 0)
+++ trunk/ManualTests/ios/resources/suspend-orientation-and-motion-events-when-page-becomes-hidden.js 2015-12-10 02:53:12 UTC (rev 193885)
@@ -0,0 +1,41 @@
+var eventFrequencyTable;
+
+function resetTest()
+{
+ eventFrequencyTable = {};
+}
+
+function log(message)
+{
+ document.getElementById("console").appendChild(document.createTextNode(message + "\n"));
+}
+
+function checkEvent(event)
+{
+ if (document.visibilityState === "visible")
+ return;
+ var type = event.type;
+ if (!eventFrequencyTable[type])
+ eventFrequencyTable[type] = 0;
+ ++eventFrequencyTable[type];
+}
+
+function handleVisibilityChange()
+{
+ if (document.visibilityState === "hidden")
+ return;
+ var receivedEventsMessageParts = [];
+ for (var type in eventFrequencyTable)
+ receivedEventsMessageParts.push(type + " (\u00D7 " + eventFrequencyTable[type] + ")");
+ if (receivedEventsMessageParts.length)
+ log("Expected to receive no events when the page was hidden, but received: " + receivedEventsMessageParts.join(", ") + ".");
+ else
+ log("Received no events when the page was hidden.");
+ resetTest();
+}
+
+resetTest();
+
+window.addEventListener("devicemotion", checkEvent, false);
+window.addEventListener("deviceorientation", checkEvent, false);
+document.addEventListener("visibilitychange", handleVisibilityChange, false);
Added: trunk/ManualTests/ios/suspend-orientation-and-motion-events-when-page-becomes-hidden.html (0 => 193885)
--- trunk/ManualTests/ios/suspend-orientation-and-motion-events-when-page-becomes-hidden.html (rev 0)
+++ trunk/ManualTests/ios/suspend-orientation-and-motion-events-when-page-becomes-hidden.html 2015-12-10 02:53:12 UTC (rev 193885)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<p>This test can be used to verify that <code>devicemotion</code> and <code>deviceorientation</code> events are not dispatched when the page is hidden.</p>
+<button _onclick_="window.open('suspend-orientation-and-motion-events-when-page-becomes-hidden.html')">Open this page in a child window to verify that this page does not receive events when the child window is the front-most window</button>
+<pre id="console"></pre>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (193884 => 193885)
--- trunk/Source/WebCore/ChangeLog 2015-12-10 02:51:11 UTC (rev 193884)
+++ trunk/Source/WebCore/ChangeLog 2015-12-10 02:53:12 UTC (rev 193885)
@@ -1,5 +1,28 @@
2015-12-09 Daniel Bates <daba...@apple.com>
+ [iOS] Suspend and resume device motion and device orientation updates when page is hidden and visible, respectively
+ https://bugs.webkit.org/show_bug.cgi?id=151840
+ <rdar://problem/23753931>
+
+ Reviewed by Simon Fraser.
+
+ * dom/Document.cpp:
+ (WebCore::Document::suspendDeviceMotionAndOrientationUpdates): Added.
+ (WebCore::Document::resumeDeviceMotionAndOrientationUpdates): Added.
+ (WebCore::Document::platformSuspendOrStopActiveDOMObjects): Moved logic to suspend device motion and
+ orientation updates from here to Document::suspendDeviceMotionAndOrientationUpdates().
+ (WebCore::Document::suspendActiveDOMObjects): Modified to call Document::suspendDeviceMotionAndOrientationUpdates().
+ (WebCore::Document::resumeActiveDOMObjects): Modified to call Document::resumeDeviceMotionAndOrientationUpdates().
+ * dom/Document.h:
+ * page/Page.cpp:
+ (WebCore::Page::setIsVisibleInternal): Suspend device motion and orientation updates when the page is hidden and
+ resume updates when the page is visible.
+ (WebCore::Page::suspendDeviceMotionAndOrientationUpdates): Added.
+ (WebCore::Page::resumeDeviceMotionAndOrientationUpdates): Added.
+ * page/Page.h:
+
+2015-12-09 Daniel Bates <daba...@apple.com>
+
Unify iOS Frame::setTimersPaused() logic and Frame::{suspend, resume}ActiveDOMObjectsAndAnimations()
https://bugs.webkit.org/show_bug.cgi?id=152006
Modified: trunk/Source/WebCore/dom/Document.cpp (193884 => 193885)
--- trunk/Source/WebCore/dom/Document.cpp 2015-12-10 02:51:11 UTC (rev 193884)
+++ trunk/Source/WebCore/dom/Document.cpp 2015-12-10 02:53:12 UTC (rev 193885)
@@ -2345,16 +2345,35 @@
node->removeAllEventListeners();
}
-void Document::platformSuspendOrStopActiveDOMObjects()
+void Document::suspendDeviceMotionAndOrientationUpdates()
{
-#if PLATFORM(IOS)
-#if ENABLE(DEVICE_ORIENTATION)
+ if (m_areDeviceMotionAndOrientationUpdatesSuspended)
+ return;
+ m_areDeviceMotionAndOrientationUpdatesSuspended = true;
+#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS)
if (m_deviceMotionController)
m_deviceMotionController->suspendUpdates();
if (m_deviceOrientationController)
m_deviceOrientationController->suspendUpdates();
#endif
+}
+void Document::resumeDeviceMotionAndOrientationUpdates()
+{
+ if (!m_areDeviceMotionAndOrientationUpdatesSuspended)
+ return;
+ m_areDeviceMotionAndOrientationUpdatesSuspended = false;
+#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS)
+ if (m_deviceMotionController)
+ m_deviceMotionController->resumeUpdates();
+ if (m_deviceOrientationController)
+ m_deviceOrientationController->resumeUpdates();
+#endif
+}
+
+void Document::platformSuspendOrStopActiveDOMObjects()
+{
+#if PLATFORM(IOS)
if (WebThreadCountOfObservedContentModifiers() > 0) {
Frame* frame = this->frame();
if (Page* page = frame ? frame->page() : nullptr)
@@ -2366,19 +2385,14 @@
void Document::suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension why)
{
ScriptExecutionContext::suspendActiveDOMObjects(why);
+ suspendDeviceMotionAndOrientationUpdates();
platformSuspendOrStopActiveDOMObjects();
}
void Document::resumeActiveDOMObjects(ActiveDOMObject::ReasonForSuspension why)
{
ScriptExecutionContext::resumeActiveDOMObjects(why);
-
-#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS)
- if (m_deviceMotionController)
- m_deviceMotionController->resumeUpdates();
- if (m_deviceOrientationController)
- m_deviceOrientationController->resumeUpdates();
-#endif
+ resumeDeviceMotionAndOrientationUpdates();
// FIXME: For iOS, do we need to add content change observers that were removed in Document::suspendActiveDOMObjects()?
}
Modified: trunk/Source/WebCore/dom/Document.h (193884 => 193885)
--- trunk/Source/WebCore/dom/Document.h 2015-12-10 02:51:11 UTC (rev 193884)
+++ trunk/Source/WebCore/dom/Document.h 2015-12-10 02:53:12 UTC (rev 193885)
@@ -604,6 +604,9 @@
virtual void resumeActiveDOMObjects(ActiveDOMObject::ReasonForSuspension) override final;
virtual void stopActiveDOMObjects() override final;
+ void suspendDeviceMotionAndOrientationUpdates();
+ void resumeDeviceMotionAndOrientationUpdates();
+
RenderView* renderView() const { return m_renderView.get(); }
bool renderTreeBeingDestroyed() const { return m_renderTreeBeingDestroyed; }
@@ -1775,6 +1778,7 @@
#if ENABLE(MEDIA_SESSION)
RefPtr<MediaSession> m_defaultMediaSession;
#endif
+ bool m_areDeviceMotionAndOrientationUpdatesSuspended { false };
};
inline void Document::notifyRemovePendingSheetIfNeeded()
Modified: trunk/Source/WebCore/page/Page.cpp (193884 => 193885)
--- trunk/Source/WebCore/page/Page.cpp 2015-12-10 02:51:11 UTC (rev 193884)
+++ trunk/Source/WebCore/page/Page.cpp 2015-12-10 02:53:12 UTC (rev 193885)
@@ -1312,6 +1312,9 @@
m_isPrerender = false;
resumeScriptedAnimations();
+#if PLATFORM(IOS)
+ resumeDeviceMotionAndOrientationUpdates();
+#endif
if (FrameView* view = mainFrame().view())
view->show();
@@ -1333,6 +1336,9 @@
if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
mainFrame().animation().suspendAnimations();
+#if PLATFORM(IOS)
+ suspendDeviceMotionAndOrientationUpdates();
+#endif
suspendScriptedAnimations();
if (FrameView* view = mainFrame().view())
@@ -1556,6 +1562,22 @@
m_relevantUnpaintedRegion.unite(snappedIntRect(objectPaintRect));
}
+void Page::suspendDeviceMotionAndOrientationUpdates()
+{
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (Document* document = frame->document())
+ document->suspendDeviceMotionAndOrientationUpdates();
+ }
+}
+
+void Page::resumeDeviceMotionAndOrientationUpdates()
+{
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (Document* document = frame->document())
+ document->resumeDeviceMotionAndOrientationUpdates();
+ }
+}
+
void Page::suspendActiveDOMObjectsAndAnimations()
{
for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
Modified: trunk/Source/WebCore/page/Page.h (193884 => 193885)
--- trunk/Source/WebCore/page/Page.h 2015-12-10 02:51:11 UTC (rev 193884)
+++ trunk/Source/WebCore/page/Page.h 2015-12-10 02:53:12 UTC (rev 193885)
@@ -394,6 +394,9 @@
WEBCORE_EXPORT void suspendActiveDOMObjectsAndAnimations();
WEBCORE_EXPORT void resumeActiveDOMObjectsAndAnimations();
+ void suspendDeviceMotionAndOrientationUpdates();
+ void resumeDeviceMotionAndOrientationUpdates();
+
#ifndef NDEBUG
void setIsPainting(bool painting) { m_isPainting = painting; }
bool isPainting() const { return m_isPainting; }