Title: [157735] trunk/Source/WebCore
Revision
157735
Author
jer.no...@apple.com
Date
2013-10-21 14:20:55 -0700 (Mon, 21 Oct 2013)

Log Message

Limit use of display sleep assertion when <video> element is off-screen.
https://bugs.webkit.org/show_bug.cgi?id=123041

Reviewed by Darin Adler.

Use page visibility changes to suspend and resume the use of sleep assertions in
HTMLMediaElement.

Page will propogate the page visibility change notifications to its Documents, which
will further propogate those notifications to registered elements.  Upon receiving
these notifications, HTMLMediaElement will release or take a DisplaySleepDisabler
token if necessary.

Also, rename HTMLMediaElement's updateDisableSleep() to updateSleepDisabling() and wrap
the implementation in a PLATFORM(MAC) guard rather than at each call site.

* dom/Document.cpp:
(WebCore::Document::registerForVisibilityStateCallbacks): Added registration method.
(WebCore::Document::unregisterForVisibilityStateCallbacks): Added unregistration method.
(WebCore::Document::visibilityStateChanged): Call all registered clients.
* dom/Document.h:
* dom/Element.h:
(WebCore::Element::visibilityStateChanged): Added default virtual method to be overridden
    by subclasses.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement): Register for the notification, and check the
    current status of Document::hidden().
(WebCore::HTMLMediaElement::~HTMLMediaElement): Unregister for the notification.
(WebCore::HTMLMediaElement::visibilityStateChanged): Set m_displaySleepDisablingSuspended
    and call updateSleepDisabling().
(WebCore::HTMLMediaElement::shouldDisableSleep): Add a check for m_displaySleepDisablingSuspended.
* html/HTMLMediaElement.h:
* page/Page.cpp:
(WebCore::Page::setVisibilityState): Pass to every child document.

Rename updateDisableSleep() -> updateSleepDisabling():
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement):
(WebCore::HTMLMediaElement::~HTMLMediaElement):
(WebCore::HTMLMediaElement::parseAttribute):
(WebCore::HTMLMediaElement::mediaPlayerRateChanged):
(WebCore::HTMLMediaElement::clearMediaPlayer):
(WebCore::HTMLMediaElement::stop):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (157734 => 157735)


--- trunk/Source/WebCore/ChangeLog	2013-10-21 21:20:35 UTC (rev 157734)
+++ trunk/Source/WebCore/ChangeLog	2013-10-21 21:20:55 UTC (rev 157735)
@@ -1,3 +1,49 @@
+2013-10-21  Jer Noble  <jer.no...@apple.com>
+
+        Limit use of display sleep assertion when <video> element is off-screen.
+        https://bugs.webkit.org/show_bug.cgi?id=123041
+
+        Reviewed by Darin Adler.
+
+        Use page visibility changes to suspend and resume the use of sleep assertions in
+        HTMLMediaElement.
+
+        Page will propogate the page visibility change notifications to its Documents, which
+        will further propogate those notifications to registered elements.  Upon receiving
+        these notifications, HTMLMediaElement will release or take a DisplaySleepDisabler
+        token if necessary.
+
+        Also, rename HTMLMediaElement's updateDisableSleep() to updateSleepDisabling() and wrap
+        the implementation in a PLATFORM(MAC) guard rather than at each call site.
+
+        * dom/Document.cpp:
+        (WebCore::Document::registerForVisibilityStateCallbacks): Added registration method.
+        (WebCore::Document::unregisterForVisibilityStateCallbacks): Added unregistration method.
+        (WebCore::Document::visibilityStateChanged): Call all registered clients.
+        * dom/Document.h:
+        * dom/Element.h:
+        (WebCore::Element::visibilityStateChanged): Added default virtual method to be overridden
+            by subclasses.
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::HTMLMediaElement): Register for the notification, and check the
+            current status of Document::hidden().
+        (WebCore::HTMLMediaElement::~HTMLMediaElement): Unregister for the notification.
+        (WebCore::HTMLMediaElement::visibilityStateChanged): Set m_displaySleepDisablingSuspended
+            and call updateSleepDisabling().
+        (WebCore::HTMLMediaElement::shouldDisableSleep): Add a check for m_displaySleepDisablingSuspended.
+        * html/HTMLMediaElement.h:
+        * page/Page.cpp:
+        (WebCore::Page::setVisibilityState): Pass to every child document.
+
+        Rename updateDisableSleep() -> updateSleepDisabling():
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::HTMLMediaElement):
+        (WebCore::HTMLMediaElement::~HTMLMediaElement):
+        (WebCore::HTMLMediaElement::parseAttribute):
+        (WebCore::HTMLMediaElement::mediaPlayerRateChanged):
+        (WebCore::HTMLMediaElement::clearMediaPlayer):
+        (WebCore::HTMLMediaElement::stop):
+
 2013-10-21  Thiago de Barros Lacerda  <thiago.lace...@openbossa.org>
 
         MediaStreamTrack now tracks its own state

Modified: trunk/Source/WebCore/dom/Document.cpp (157734 => 157735)


--- trunk/Source/WebCore/dom/Document.cpp	2013-10-21 21:20:35 UTC (rev 157734)
+++ trunk/Source/WebCore/dom/Document.cpp	2013-10-21 21:20:55 UTC (rev 157735)
@@ -1528,6 +1528,23 @@
 }
 
 #if ENABLE(PAGE_VISIBILITY_API)
+void Document::registerForVisibilityStateChangedCallbacks(Element* element)
+{
+    m_visibilityStateCallbackElements.add(element);
+}
+
+void Document::unregisterForVisibilityStateChangedCallbacks(Element* element)
+{
+    m_visibilityStateCallbackElements.remove(element);
+}
+
+void Document::visibilityStateChanged()
+{
+    dispatchEvent(Event::create(eventNames().visibilitychangeEvent, false, false));
+    for (auto it = m_visibilityStateCallbackElements.begin(); it != m_visibilityStateCallbackElements.end(); ++it)
+        (*it)->visibilityStateChanged();
+}
+
 PageVisibilityState Document::pageVisibilityState() const
 {
     // The visibility of the document is inherited from the visibility of the

Modified: trunk/Source/WebCore/dom/Document.h (157734 => 157735)


--- trunk/Source/WebCore/dom/Document.h	2013-10-21 21:20:35 UTC (rev 157734)
+++ trunk/Source/WebCore/dom/Document.h	2013-10-21 21:20:55 UTC (rev 157735)
@@ -417,6 +417,7 @@
     virtual URL baseURI() const OVERRIDE;
 
 #if ENABLE(PAGE_VISIBILITY_API)
+    void visibilityStateChanged();
     String visibilityState() const;
     bool hidden() const;
 #endif
@@ -967,6 +968,11 @@
     void captionPreferencesChanged();
 #endif
 
+#if ENABLE(PAGE_VISIBILITY_API)
+    void registerForVisibilityStateChangedCallbacks(Element*);
+    void unregisterForVisibilityStateChangedCallbacks(Element*);
+#endif
+
     void setShouldCreateRenderers(bool);
     bool shouldCreateRenderers();
 
@@ -1439,6 +1445,10 @@
     HashSet<Element*> m_captionPreferencesChangedElements;
 #endif
 
+#if ENABLE(PAGE_VISIBILITY_API)
+    HashSet<Element*> m_visibilityStateCallbackElements;
+#endif
+
     HashMap<StringImpl*, Element*, CaseFoldingHash> m_elementsByAccessKey;
     bool m_accessKeyMapValid;
 

Modified: trunk/Source/WebCore/dom/Element.h (157734 => 157735)


--- trunk/Source/WebCore/dom/Element.h	2013-10-21 21:20:35 UTC (rev 157734)
+++ trunk/Source/WebCore/dom/Element.h	2013-10-21 21:20:55 UTC (rev 157735)
@@ -418,6 +418,11 @@
     virtual void didBecomeFullscreenElement() { }
     virtual void willStopBeingFullscreenElement() { }
 
+#if ENABLE(PAGE_VISIBILITY_API)
+    // Use Document::registerForVisibilityStateChangedCallbacks() to subscribe to this.
+    virtual void visibilityStateChanged() { }
+#endif
+
 #if ENABLE(VIDEO_TRACK)
     virtual void captionPreferencesChanged() { }
 #endif

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (157734 => 157735)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2013-10-21 21:20:35 UTC (rev 157734)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2013-10-21 21:20:55 UTC (rev 157735)
@@ -317,6 +317,9 @@
     , m_completelyLoaded(false)
     , m_havePreparedToPlay(false)
     , m_parsingInProgress(createdByParser)
+#if ENABLE(PAGE_VISIBILITY_API)
+    , m_isDisplaySleepDisablingSuspended(document.hidden())
+#endif
 #if ENABLE(VIDEO_TRACK)
     , m_tracksAreReady(true)
     , m_haveVisibleTextTrack(false)
@@ -342,6 +345,10 @@
     document.registerForMediaVolumeCallbacks(this);
     document.registerForPrivateBrowsingStateChangedCallbacks(this);
 
+#if ENABLE(PAGE_VISIBILITY_API)
+    document.registerForVisibilityStateChangedCallbacks(this);
+#endif
+
     if (document.settings() && document.settings()->mediaPlaybackRequiresUserGesture()) {
         addBehaviorRestriction(RequireUserGestureForRateChangeRestriction);
         addBehaviorRestriction(RequireUserGestureForLoadRestriction);
@@ -367,6 +374,11 @@
     setShouldDelayLoadEvent(false);
     document().unregisterForMediaVolumeCallbacks(this);
     document().unregisterForPrivateBrowsingStateChangedCallbacks(this);
+
+#if ENABLE(PAGE_VISIBILITY_API)
+    document().unregisterForVisibilityStateChangedCallbacks(this);
+#endif
+
 #if ENABLE(VIDEO_TRACK)
     document().unregisterForCaptionPreferencesChangedCallbacks(this);
     if (m_audioTracks) {
@@ -459,10 +471,8 @@
         }
     } else if (name == controlsAttr)
         configureMediaControls();
-#if PLATFORM(MAC)
     else if (name == loopAttr)
-        updateDisableSleep();
-#endif
+        updateSleepDisabling();
     else if (name == preloadAttr) {
         if (equalIgnoringCase(value, "none"))
             m_preload = MediaPlayer::None;
@@ -3754,9 +3764,7 @@
     if (m_playing)
         invalidateCachedTime();
 
-#if PLATFORM(MAC)
-    updateDisableSleep();
-#endif
+    updateSleepDisabling();
 
     endProcessingMediaPlayerCallback();
 }
@@ -4171,9 +4179,7 @@
         configureTextTrackDisplay();
 #endif
 
-#if PLATFORM(MAC)
-    updateDisableSleep();
-#endif
+    updateSleepDisabling();
 }
 
 bool HTMLMediaElement::canSuspend() const
@@ -4207,9 +4213,7 @@
     // if the media was not fully loaded. This handles all other cases.
     m_player.clear();
 
-#if PLATFORM(MAC)
-    updateDisableSleep();
-#endif
+    updateSleepDisabling();
 }
 
 void HTMLMediaElement::suspend(ReasonForSuspension why)
@@ -4268,6 +4272,15 @@
     updateVolume();
 }
 
+#if ENABLE(PAGE_VISIBILITY_API)
+void HTMLMediaElement::visibilityStateChanged()
+{
+    LOG(Media, "HTMLMediaElement::visibilityStateChanged");
+    m_isDisplaySleepDisablingSuspended = document().hidden();
+    updateSleepDisabling();
+}
+#endif
+
 void HTMLMediaElement::defaultEventHandler(Event* event)
 {
 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
@@ -5025,17 +5038,24 @@
     }
 }
 
+void HTMLMediaElement::updateSleepDisabling()
+{
 #if PLATFORM(MAC)
-void HTMLMediaElement::updateDisableSleep()
-{
     if (!shouldDisableSleep() && m_sleepDisabler)
         m_sleepDisabler = nullptr;
     else if (shouldDisableSleep() && !m_sleepDisabler)
         m_sleepDisabler = DisplaySleepDisabler::create("com.apple.WebCore: HTMLMediaElement playback");
+#endif
 }
 
+#if PLATFORM(MAC)
 bool HTMLMediaElement::shouldDisableSleep() const
 {
+#if ENABLE(PAGE_VISIBILITY_API)
+    if (m_isDisplaySleepDisablingSuspended)
+        return false;
+#endif
+
     return m_player && !m_player->paused() && hasVideo() && hasAudio() && !loop();
 }
 #endif

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (157734 => 157735)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2013-10-21 21:20:35 UTC (rev 157734)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2013-10-21 21:20:55 UTC (rev 157735)
@@ -458,6 +458,10 @@
     
     virtual void mediaVolumeDidChange() OVERRIDE;
 
+#if ENABLE(PAGE_VISIBILITY_API)
+    virtual void visibilityStateChanged() OVERRIDE;
+#endif
+
     virtual void updateDisplayState() { }
     
     void setReadyState(MediaPlayer::ReadyState);
@@ -621,7 +625,7 @@
     bool isAutoplaying() const { return m_autoplaying; }
 
 #if PLATFORM(MAC)
-    void updateDisableSleep();
+    void updateSleepDisabling();
     bool shouldDisableSleep() const;
 #endif
 
@@ -730,6 +734,9 @@
     bool m_completelyLoaded : 1;
     bool m_havePreparedToPlay : 1;
     bool m_parsingInProgress : 1;
+#if ENABLE(PAGE_VISIBILITY_API)
+    bool m_isDisplaySleepDisablingSuspended : 1;
+#endif
 
 #if ENABLE(VIDEO_TRACK)
     bool m_tracksAreReady : 1;

Modified: trunk/Source/WebCore/page/Page.cpp (157734 => 157735)


--- trunk/Source/WebCore/page/Page.cpp	2013-10-21 21:20:35 UTC (rev 157734)
+++ trunk/Source/WebCore/page/Page.cpp	2013-10-21 21:20:55 UTC (rev 157735)
@@ -1244,7 +1244,7 @@
             documents.append(*frame->document());
 
         for (size_t i = 0, size = documents.size(); i < size; ++i)
-            documents[i]->dispatchEvent(Event::create(eventNames().visibilitychangeEvent, false, false));
+            documents[i]->visibilityStateChanged();
     }
 #endif
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to